����JFIFXX�����    $.' ",#(7),01444'9=82<.342  2!!22222222222222222222222222222222222222222222222222����"��4�� ���,�PG"Z_�4�˷����kjز�Z�,F+��_z�,�© �����zh6�٨�ic�fu���#ډb���_�N�?��wQ���5-�~�I���8����TK<5o�Iv-�����k�_U_�����~b�M��d����Ӝ�U�Hh��?]��E�w��Q���k�{��_}qFW7HTՑ��Y��F�?_�'ϔ��_�Ջt��=||I ��6�έ"�����D���/[�k�9���Y�8ds|\���Ҿp6�Ҵ���]��.����6�z<�v��@]�i%��$j��~�g��J>��no����pM[me�i$[����s�o�ᘨ�˸ nɜG-�ĨU�ycP�3.DB�li�;��hj���x7Z^�N�h������N3u{�:j�x�힞��#M&��jL P@_���� P��&��o8������9�����@Sz6�t7#O�ߋ �s}Yf�T���lmr����Z)'N��k�۞p����w\�Tȯ?�8`�O��i{wﭹW�[�r�� ��Q4F�׊���3m&L�=��h3����z~��#�\�l :�F,j@�� ʱ�wQT����8�"kJO���6�֚l����}���R�>ډK���]��y����&����p�}b��;N�1�m�r$�|��7�>e�@B�TM*-iH��g�D�)� E�m�|�ؘbҗ�a��Ҿ����t4���o���G��*oCN�rP���Q��@z,|?W[0�����:�n,jWiE��W��$~/�hp\��?��{(�0���+�Y8rΟ�+����>S-S����VN;�}�s?.����� w�9��˟<���Mq4�Wv'��{)0�1mB��V����W[�����8�/<� �%���wT^�5���b��)iM� pg�N�&ݝ��VO~�q���u���9� ����!��J27����$O-���! �:�%H��� ـ����y�ΠM=t{!S�� oK8������t<����è:a������[�����ա�H���~��w��Qz`�po�^ ����Q��n� �,uu�C�$ ^���,������8�#��:�6��e�|~���!�3�3.�\0��q��o�4`.|� ����y�Q�`~;�d�ׯ,��O�Zw�������`73�v�܋�<���Ȏ�� ـ4k��5�K�a�u�=9Yd��$>x�A�&�� j0� ���vF��� Y�|�y��� ~�6�@c��1vOp�Ig����4��l�OD���L����� R���c���j�_�uX6��3?nk��Wy�f;^*B� ��@�~a�`��Eu������+���6�L��.ü>��}y���}_�O�6�͐�:�YrG�X��kG�����l^w���~㒶sy��Iu�!� W ��X��N�7BV��O��!X�2����wvG�R�f�T#�����t�/?���%8�^�W�aT��G�cL�M���I��(J����1~�8�?aT ���]����AS�E��(��*E}� 2��#I/�׍qz��^t�̔���b�Yz4x���t�){ OH��+(E��A&�N�������XT��o��"�XC��'���)}�J�z�p� ��~5�}�^����+�6����w��c��Q�|Lp�d�H��}�(�.|����k��c4^�"�����Z?ȕ ��a<�L�!039C� �Eu�C�F�Ew�ç ;�n?�*o���B�8�bʝ���'#Rqf���M}7����]����s2tcS{�\icTx;�\��7K���P���ʇ Z O-��~��c>"��?�������P��E��O�8��@�8��G��Q�g�a�Վ���󁶠�䧘��_%#r�>�1�z�a��eb��qcPѵ��n���#L��� =��׀t� L�7�`��V���A{�C:�g���e@�w1 Xp3�c3�ġ����p��M"'-�@n4���fG��B3�DJ�8[Jo�ߐ���gK)ƛ��$���� ���8�3�����+���� �����6�ʻ���� ���S�kI�*KZlT _`���?��K����QK�d����B`�s}�>���`��*�>��,*@J�d�oF*����弝��O}�k��s��]��y�ߘ��c1G�V���<=�7��7����6�q�PT��tXԀ�!9*4�4Tހ3XΛex�46���Y��D ����� �BdemDa����\�_l,��G�/���֌7���Y�](�xTt^%�GE�����4�}bT���ڹ�����;Y)���B�Q��u��>J/J �⮶.�XԄ��j�ݳ�+E��d ��r�5�_D�1 ��o�� �B�x�΢�#���<��W�����8���R6�@g�M�.��� dr�D��>(otU��@x=��~v���2� ӣ�d�oBd��3�eO�6�㣷�����ݜ6��6Y��Qz`��S��{���\P�~z m5{J/L��1������<�e�ͅPu�b�]�ϔ���'������f�b� Zpw��c`"��i���BD@:)ִ�:�]��hv�E�w���T�l��P���"Ju�}��وV J��G6��. J/�Qgl߭�e�����@�z�Zev2u�)]կ�����7x���s�M�-<ɯ�c��r�v�����@��$�ޮ}lk���a���'����>x��O\�ZFu>�����ck#��&:��`�$�ai�>2Δ����l���oF[h��lE�ܺ�Πk:)���`�� $[6�����9�����kOw�\|���8}������ބ:��񶐕��I�A1/�=�2[�,�!��.}gN#�u����b��� ~��݊��}34q����d�E��Lc��$��"�[q�U�硬g^��%B �z���r�pJ�ru%v\h1Y�ne`ǥ:g���pQM~�^�Xi� ��`S�:V29.�P���V�?B�k�� AEvw%�_�9C�Q����wKekPؠ�\�;Io d�{ ߞo�c1eP����\� `����E=���@K<�Y���eڼ�J���w����{av�F�'�M�@/J��+9p���|]�����Iw &`��8���&M�hg��[�{��Xj��%��Ӓ�$��(����ʹN���<>�I���RY���K2�NPlL�ɀ)��&e����B+ь����( � �JTx���_?EZ� }@ 6�U���뙢ط�z��dWI�n` D����噥�[��uV��"�G&Ú����2g�}&m��?ċ�"����Om#��������� ��{�ON��"S�X��Ne��ysQ���@Fn��Vg���dX�~nj�]J�<�K]:��FW��b�������62�=��5f����JKw��bf�X�55��~J �%^����:�-�QIE��P��v�nZum� z � ~ə ���� ���ة����;�f��\v���g�8�1��f24;�V���ǔ�)����9���1\��c��v�/'Ƞ�w�������$�4�R-��t���� e�6�/�ġ �̕Ecy�J���u�B���<�W�ַ~�w[B1L۲�-JS΂�{���΃������A��20�c#��@ 0!1@AP"#2Q`$3V�%45a6�FRUq��� ����^7ׅ,$n�������+��F�`��2X'��0vM��p�L=������5��8������u�p~���.�`r�����\���O��,ư�0oS ��_�M�����l���4�kv\JSd���x���SW�<��Ae�IX����������$I���w�:S���y���›R��9�Q[���,�5�;�@]�%���u�@ *ro�lbI �� ��+���%m:�͇ZV�����u�̉����θau<�fc�.����{�4Ա� �Q����*�Sm��8\ujqs]{kN���)qO�y�_*dJ�b�7���yQqI&9�ԌK!�M}�R�;������S�T���1���i[U�ɵz�]��U)V�S6���3$K{�ߊ<�(� E]Զ[ǼENg�����'�\?#)Dkf��J���o��v���'�%ƞ�&K�u�!��b�35LX�Ϸ��63$K�a�;�9>,R��W��3�3� d�JeTYE.Mϧ��-�o�j3+y��y^�c�������VO�9NV\nd�1 ��!͕_)a�v;����թ�M�lWR1��)El��P;��yوÏ�u 3�k�5Pr6<�⒲l�!˞*��u־�n�!�l:����UNW ��%��Chx8vL'��X�@��*��)���̮��ˍ��� ���D-M�+J�U�kvK����+�x8��cY������?�Ԡ��~3mo��|�u@[XeY�C�\Kp�x8�oC�C�&����N�~3-H���� ��MX�s�u<`���~"WL��$8ξ��3���a�)|:@�m�\���^�`�@ҷ)�5p+��6���p�%i)P M���ngc�����#0Aruz���RL+xSS?���ʮ}()#�t��mˇ!��0}}y����<�e� �-ή�Ԩ��X������ MF���ԙ~l L.3���}�V뽺�v�����멬��Nl�)�2����^�Iq��a��M��qG��T�����c3#������3U�Ǎ���}��לS�|qa��ڃ�+���-��2�f����/��bz��ڐ�� �ݼ[2�ç����k�X�2�* �Z�d���J�G����M*9W���s{��w���T��x��y,�in�O�v��]���n����P�$�JB@=4�OTI�n��e�22a\����q�d���%�$��(���:���: /*�K[PR�fr\nڙdN���F�n�$�4�[�� U�zƶ����� �mʋ���,�ao�u 3�z� �x��Kn����\[��VFmbE;�_U��&V�Gg�]L�۪&#n%�$ɯ�dG���D�TI=�%+AB�Ru#��b4�1�»x�cs�YzڙJG��f��Il��d�eF'T� iA��T���uC�$����Y��H?����[!G`}���ͪ� �纤Hv\������j�Ex�K���!���OiƸ�Yj�+u-<���'q����uN�*�r\��+�]���<�wOZ.fp�ێ��,-*)V?j-kÊ#�`�r��dV����(�ݽBk�����G�ƛk�QmUڗe��Z���f}|����8�8��a���i��3'J�����~G_�^���d�8w������ R�`(�~�.��u���l�s+g�bv���W���lGc}��u���afE~1�Ue������Z�0�8�=e�� f@/�jqEKQQ�J��oN��J���W5~M>$6�Lt�;$ʳ{���^��6�{����v6���ķܰg�V�cnn �~z�x�«�,2�u�?cE+Ș�H؎�%�Za�)���X>uW�Tz�Nyo����s���FQƤ��$��*�&�LLXL)�1�" L��eO��ɟ�9=���:t��Z���c��Ž���Y?�ӭV�wv�~,Y��r�ۗ�|�y��GaF�����C�����.�+� ���v1���fήJ�����]�S��T��B��n5sW}y�$��~z�'�c ��8 ��� ,! �p��VN�S��N�N�q��y8z˱�A��4��*��'������2n<�s���^ǧ˭P�Jޮɏ�U�G�L�J�*#��<�V��t7�8����TĜ>��i}K%,���)[��z�21z ?�N�i�n1?T�I�R#��m-�����������������1����lA�`��fT5+��ܐ�c�q՝��ʐ��,���3�f2U�եmab��#ŠdQ�y>\��)�SLY����w#��.���ʑ�f��� ,"+�w�~�N�'�c�O�3F�������N<���)j��&��,-� �љ���֊�_�zS���TǦ����w�>��?�������n��U仆�V���e�����0���$�C�d���rP �m�׈e�Xm�Vu� �L��.�bֹ��� �[Դaզ���*��\y�8�Է:�Ez\�0�Kq�C b��̘��cө���Q��=0Y��s�N��S.���3.���O�o:���#���v7�[#߫ ��5�܎�L���Er4���9n��COWlG�^��0k�%<���ZB���aB_���������'=��{i�v�l�$�uC���mƎҝ{�c㱼�y]���W�i ��ߧc��m�H� m�"�"�����;Y�ߝ�Z�Ǔ�����:S#��|}�y�,/k�Ld� TA�(�AI$+I3��;Y*���Z��}|��ӧO��d�v��..#:n��f>�>���ȶI�TX��� 8��y����"d�R�|�)0���=���n4��6ⲑ�+��r<�O�܂~zh�z����7ܓ�HH�Ga롏���nCo�>������a ���~]���R���̲c?�6(�q�;5%� |�uj�~z8R=X��I�V=�|{v�Gj\gc��q����z�؋%M�ߍ����1y��#��@f^���^�>N�����#x#۹��6�Y~�?�dfPO��{��P�4��V��u1E1J �*|���%���JN��`eWu�zk M6���q t[�� ��g�G���v��WIG��u_ft����5�j�"�Y�:T��ɐ���*�;� e5���4����q$C��2d�}���� _S�L#m�Yp��O�.�C�;��c����Hi#֩%+) �Ӎ��ƲV���SYź��g |���tj��3�8���r|���V��1#;.SQ�A[���S������#���`n�+���$��$I �P\[�@�s��(�ED�z���P��])8�G#��0B��[ى��X�II�q<��9�~[Z멜�Z�⊔IWU&A>�P~�#��dp<�?����7���c��'~���5 ��+$���lx@�M�dm��n<=e�dyX��?{�|Aef ,|n3�<~z�ƃ�uۧ�����P��Y,�ӥQ�*g�#먙R�\���;T��i,��[9Qi歉����c>]9�� ��"�c��P�� �Md?٥��If�ت�u��k��/����F��9�c*9��Ǎ:�ØF���z�n*�@|I�ށ9����N3{'��[�'ͬ�Ҳ4��#}��!�V� Fu��,�,mTIk���v C�7v���B�6k�T9��1�*l� '~��ƞF��lU��'�M ����][ΩũJ_�{�i�I�n��$���L�� j��O�dx�����kza۪��#�E��Cl����x˘�o�����V���ɞ�ljr��)�/,�߬h�L��#��^��L�ф�,íMƁe�̩�NB�L�����iL����q�}��(��q��6IçJ$�W�E$��:������=#����(�K�B����zђ <��K(�N�۫K�w��^O{!����)�H���>x�������lx�?>Պ�+�>�W���,Ly!_�D���Ō�l���Q�!�[ �S����J��1��Ɛ�Y}��b,+�Lo�x�ɓ)����=�y�oh�@�꥟/��I��ѭ=��P�y9��� �ۍYӘ�e+�p�Jnϱ?V\SO%�(�t� ���=?MR�[Ș�����d�/ ��n�l��B�7j� ��!�;ӥ�/�[-���A�>�dN�sLj ��,ɪv��=1c�.SQ�O3�U���ƀ�ܽ�E����������̻��9G�ϷD�7(�}��Ävӌ\�y�_0[w ���<΍>����a_��[0+�L��F.�޺��f�>oN�T����q;���y\��bՃ��y�jH�<|q-eɏ�_?_9+P���Hp$�����[ux�K w�Mw��N�ی'$Y2�=��q���KB��P��~������Yul:�[<����F1�2�O���5=d����]Y�sw:���Ϯ���E��j,_Q��X��z`H1,#II ��d�wr��P˂@�ZJV����y$�\y�{}��^~���[:N����ߌ�U�������O��d�����ؾe��${p>G��3c���Ė�lʌ�� ת��[��`ϱ�-W����dg�I��ig2��� ��}s ��ؤ(%#sS@���~���3�X�nRG�~\jc3�v��ӍL��M[JB�T��s3}��j�Nʖ��W����;7��ç?=X�F=-�=����q�ߚ���#���='�c��7���ڑW�I(O+=:uxq�������������e2�zi+�kuG�R��������0�&e�n���iT^J����~\jy���p'dtG��s����O��3����9* �b#Ɋ�� p������[Bws�T�>d4�ۧs���nv�n���U���_�~,�v����ƜJ1��s�� �QIz��)�(lv8M���U=�;����56��G���s#�K���MP�=��LvyGd��}�VwWBF�'�à �?MH�U�g2�� ����!�p�7Q��j��ڴ����=��j�u��� Jn�A s���uM������e��Ɔ�Ҕ�!)'��8Ϣ�ٔ��ޝ(��Vp���צ֖d=�IC�J�Ǡ{q������kԭ�߸���i��@K����u�|�p=..�*+����x�����z[Aqġ#s2a�Ɗ���RR�)*HRsi�~�a &f��M��P����-K�L@��Z��Xy�'x�{}��Zm+���:�)�) IJ�-i�u���� ���ܒH��'�L(7�y�GӜq���� j��� 6ߌg1�g�o���,kر���tY�?W,���p���e���f�OQS��!K�۟cҒA�|ս�j�>��=⬒��˧L[�� �߿2JaB~R��u�:��Q�] �0H~���]�7��Ƽ�I���(}��cq '�ήET���q�?f�ab���ӥvr� �)o��-Q��_'����ᴎo��K������;��V���o��%���~OK ����*��b�f:���-ťIR��`B�5!RB@���ï�� �u �̯e\�_U�_������� g�ES��3�������QT��a����x����U<~�c?�*�#]�MW,[8O�a�x��]�1bC|踤�P��lw5V%�)�{t�<��d��5���0i�XSU��m:��Z�┵�i�"��1�^B�-��P�hJ��&)O��*�D��c�W��vM��)����}���P��ܗ-q����\mmζZ-l@�}��a��E�6��F�@��&Sg@���ݚ�M����� ȹ 4����#p�\H����dYDo�H���"��\��..R�B�H�z_�/5˘����6��KhJR��P�mƶi�m���3�,#c�co��q�a)*Pt����R�m�k�7x�D�E�\Y�閣_X�<���~�)���c[[�BP����6�Yq���S��0����%_����;��Àv�~�| VS؇ ��'O0��F0��\���U�-�d@�����7�SJ*z��3n��y��P����O���������m�~�P�3|Y��ʉr#�C�<�G~�.,! ���bqx���h~0=��!ǫ�jy����l�O,�[B��~��|9��ٱ����Xly�#�i�B��g%�S��������tˋ���e���ې��\[d�t)��.+u�|1 ������#�~Oj����hS�%��i.�~X���I�H�m��0n���c�1uE�q��cF�RF�o���7� �O�ꮧ� ���ۛ{��ʛi5�rw?׌#Qn�TW��~?y$��m\�\o����%W� ?=>S�N@�� �Ʈ���R����N�)�r"C�:��:����� �����#��qb��Y�. �6[��2K����2u�Ǧ�HYR��Q�MV��� �G�$��Q+.>�����nNH��q�^��� ����q��mM��V��D�+�-�#*�U�̒ ���p욳��u:�������IB���m���PV@O���r[b= �� ��1U�E��_Nm�yKbN�O���U�}�the�`�|6֮P>�\2�P�V���I�D�i�P�O;�9�r�mAHG�W�S]��J*�_�G��+kP�2����Ka�Z���H�'K�x�W�MZ%�O�YD�Rc+o��?�q��Ghm��d�S�oh�\�D�|:W������UA�Qc yT�q������~^�H��/��#p�CZ���T�I�1�ӏT����4��"�ČZ�����}��`w�#�*,ʹ�� ��0�i��課�Om�*�da��^gJ݅{���l�e9uF#T�ֲ��̲�ٞC"�q���ߍ ոޑ�o#�XZTp����@ o�8��(jd��xw�]�,f���`~�|,s��^����f�1���t��|��m�򸄭/ctr��5s��7�9Q�4�H1꠲BB@l9@���C�����+�wp�xu�£Yc�9��?`@#�o�mH�s2��)�=��2�.�l����jg�9$�Y�S�%*L������R�Y������7Z���,*=�䷘$�������arm�o�ϰ���UW.|�r�uf����IGw�t����Zwo��~5 ��YյhO+=8fF�)�W�7�L9lM�̘·Y���֘YLf�큹�pRF���99.A �"wz��=E\Z���'a� 2��Ǚ�#;�'}�G���*��l��^"q��+2FQ� hj��kŦ��${���ޮ-�T�٭cf�|�3#~�RJ����t��$b�(R��(����r���dx� >U b�&9,>���%E\� Ά�e�$��'�q't��*�א���ެ�b��-|d���SB�O�O��$�R+�H�)�܎�K��1m`;�J�2�Y~9��O�g8=vqD`K[�F)k�[���1m޼c��n���]s�k�z$@��)!I �x՝"v��9=�ZA=`Ɠi �:�E��)`7��vI��}d�YI�_ �o�:ob���o ���3Q��&D&�2=�� �Ά��;>�h����y.*ⅥS������Ӭ�+q&����j|UƧ����}���J0��WW< ۋS�)jQR�j���Ư��rN)�Gű�4Ѷ(�S)Ǣ�8��i��W52���No˓� ۍ%�5brOn�L�;�n��\G����=�^U�dI���8$�&���h��'���+�(������cȁ߫k�l��S^���cƗjԌE�ꭔ��gF���Ȓ��@���}O���*;e�v�WV���YJ\�]X'5��ղ�k�F��b 6R�o՜m��i N�i����>J����?��lPm�U��}>_Z&�KK��q�r��I�D�Չ~�q�3fL�:S�e>���E���-G���{L�6p�e,8��������QI��h��a�Xa��U�A'���ʂ���s�+טIjP�-��y�8ۈZ?J$��W�P� ��R�s�]��|�l(�ԓ��sƊi��o(��S0��Y� 8�T97.�����WiL��c�~�dxc�E|�2!�X�K�Ƙਫ਼�$((�6�~|d9u+�qd�^3�89��Y�6L�.I�����?���iI�q���9�)O/뚅����O���X��X�V��ZF[�یgQ�L��K1���RҖr@v�#��X�l��F���Нy�S�8�7�kF!A��sM���^rkp�jP�DyS$N���q��nxҍ!U�f�!eh�i�2�m���`�Y�I�9r�6� �TF���C}/�y�^���Η���5d�'��9A-��J��>{�_l+�`��A���[�'��յ�ϛ#w:݅�%��X�}�&�PSt�Q�"�-��\縵�/����$Ɨh�Xb�*�y��BS����;W�ջ_mc�����vt?2}1�;qS�d�d~u:2k5�2�R�~�z+|HE!)�Ǟl��7`��0�<�,�2*���Hl-��x�^����'_TV�gZA�'j� ^�2Ϊ��N7t�����?w�� �x1��f��Iz�C-Ȗ��K�^q�;���-W�DvT�7��8�Z�������� hK�(P:��Q- �8�n�Z���܃e貾�<�1�YT<�,�����"�6{/ �?�͟��|1�:�#g��W�>$����d��J��d�B��=��jf[��%rE^��il:��B���x���Sּ�1հ��,�=��*�7 fcG��#q� �eh?��2�7�����,�!7x��6�n�LC�4x��},Geǝ�tC.��vS �F�43��zz\��;QYC,6����~;RYS/6���|2���5���v��T��i����������mlv��������&� �nRh^ejR�LG�f���? �ۉҬܦƩ��|��Ȱ����>3����!v��i�ʯ�>�v��オ�X3e���_1z�Kȗ\<������!�8���V��]��?b�k41�Re��T�q��mz��TiOʦ�Z��Xq���L������q"+���2ۨ��8}�&N7XU7Ap�d�X��~�׿��&4e�o�F��� �H����O���č�c�� 懴�6���͉��+)��v;j��ݷ�� �UV�� i��� j���Y9GdÒJ1��詞�����V?h��l����l�cGs�ځ�������y�Ac�����\V3�? �� ܙg�>qH�S,�E�W�[�㺨�uch�⍸�O�}���a��>�q�6�n6����N6�q������N ! 1AQaq�0@����"2BRb�#Pr���3C`��Scst���$4D���%Td�� ?���N����a��3��m���C���w��������xA�m�q�m���m������$����4n淿t'��C"w��zU=D�\R+w�p+Y�T�&�պ@��ƃ��3ޯ?�Aﶂ��aŘ���@-�����Q�=���9D��ռ�ѻ@��M�V��P��܅�G5�f�Y<�u=,EC)�<�Fy'�"�&�չ�X~f��l�KԆV��?�� �W�N����=(� �;���{�r����ٌ�Y���h{�١������jW����P���Tc�����X�K�r��}���w�R��%��?���E��m�� �Y�q|����\lEE4���r���}�lsI�Y������f�$�=�d�yO����p�����yBj8jU�o�/�S��?�U��*������ˍ�0������u�q�m [�?f����a�� )Q�>����6#������� ?����0UQ����,IX���(6ڵ[�DI�MNލ�c&���υ�j\��X�R|,4��� j������T�hA�e��^���d���b<����n�� �즇�=!���3�^�`j�h�ȓr��jẕ�c�,ٞX����-����a�ﶔ���#�$��]w�O��Ӫ�1y%��L�Y<�wg#�ǝ�̗`�x�xa�t�w��»1���o7o5��>�m뭛C���Uƃߜ}�C���y1Xνm�F8�jI���]����H���ۺиE@I�i;r�8ӭ����V�F�Շ| ��&?�3|x�B�MuS�Ge�=Ӕ�#BE5G�����Y!z��_e��q�р/W>|-�Ci߇�t�1ޯќd�R3�u��g�=0 5��[?�#͏��q�cf���H��{ ?u�=?�?ǯ���}Z��z���hmΔ�BFTW�����<�q�(v� ��!��z���iW]*�J�V�z��gX֧A�q�&��/w���u�gYӘa���; �i=����g:��?2�dž6�ى�k�4�>�Pxs����}������G�9��3 ���)gG�R<>r h�$��'nc�h�P��Bj��J�ҧH� -��N1���N��?��~��}-q!=��_2hc�M��l�vY%UE�@|�v����M2�.Y[|y�"Eï��K�ZF,�ɯ?,q�?v�M 80jx�"�;�9vk�����+ ֧�� �ȺU��?�%�vcV��mA�6��Qg^M����A}�3�nl� QRN�l8�kkn�'�����(��M�7m9و�q���%ޟ���*h$Zk"��$�9��: �?U8�Sl��,,|ɒ��xH(ѷ����Gn�/Q�4�P��G�%��Ա8�N��!� �&�7�;���eKM7�4��9R/%����l�c>�x;������>��C�:�����t��h?aKX�bhe�ᜋ^�$�Iհ �hr7%F$�E��Fd���t��5���+�(M6�t����Ü�UU|zW�=a�Ts�Tg������dqP�Q����b'�m���1{|Y����X�N��b �P~��F^F:����k6�"�j!�� �I�r�`��1&�-$�Bevk:y���#yw��I0��x��=D�4��tU���P�ZH��ڠ底taP��6����b>�xa����Q�#� WeF��ŮNj�p�J* mQ�N����*I�-*�ȩ�F�g�3 �5��V�ʊ�ɮ�a��5F���O@{���NX��?����H�]3��1�Ri_u��������ѕ�� ����0��� F��~��:60�p�͈�S��qX#a�5>���`�o&+�<2�D����: �������ڝ�$�nP���*)�N�|y�Ej�F�5ټ�e���ihy�Z �>���k�bH�a�v��h�-#���!�Po=@k̆IEN��@��}Ll?j�O������߭�ʞ���Q|A07x���wt!xf���I2?Z��<ץ�T���cU�j��]��陎Ltl �}5�ϓ��$�,��O�mˊ�;�@O��jE��j(�ا,��LX���LO���Ц�90�O �.����a��nA���7������j4 ��W��_ٓ���zW�jcB������y՗+EM�)d���N�g6�y1_x��p�$Lv:��9�"z��p���ʙ$��^��JԼ*�ϭ����o���=x�Lj�6�J��u82�A�H�3$�ٕ@�=Vv�]�'�qEz�;I˼��)��=��ɯ���x �/�W(V���p�����$ �m�������u�����񶤑Oqˎ�T����r��㠚x�sr�GC��byp�G��1ߠ�w e�8�$⿄����/�M{*}��W�]˷.�CK\�ުx���/$�WPw���r� |i���&�}�{�X� �>��$-��l���?-z���g����lΆ���(F���h�vS*���b���߲ڡn,|)mrH[���a�3�ר�[1��3o_�U�3�TC�$��(�=�)0�kgP���� ��u�^=��4 �WYCҸ:��vQ�ר�X�à��tk�m,�t*��^�,�}D*� �"(�I��9R����>`�`��[~Q]�#af��i6l��8���6�:,s�s�N6�j"�A4���IuQ��6E,�GnH��zS�HO�uk�5$�I�4��ؤ�Q9�@��C����wp�BGv[]�u�Ov���0I4���\��y�����Q�Ѹ��~>Z��8�T��a��q�ޣ;z��a���/��S��I:�ܫ_�|������>=Z����8:�S��U�I�J��"IY���8%b8���H��:�QO�6�;7�I�S��J��ҌAά3��>c���E+&jf$eC+�z�;��V����� �r���ʺ������my�e���aQ�f&��6�ND��.:��NT�vm�<- u���ǝ\MvZY�N�NT��-A�>jr!S��n�O 1�3�Ns�%�3D@���`������ܟ 1�^c<���� �a�ɽ�̲�Xë#�w�|y�cW�=�9I*H8�p�^(4���՗�k��arOcW�tO�\�ƍR��8����'�K���I�Q�����?5�>[�}��yU�ײ -h��=��% q�ThG�2�)���"ו3]�!kB��*p�FDl�A���,�eEi�H�f�Ps�����5�H:�Փ~�H�0Dت�D�I����h�F3�������c��2���E��9�H��5�zԑ�ʚ�i�X�=:m�xg�hd(�v����׊�9iS��O��d@0ڽ���:�p�5�h-��t�&���X�q�ӕ,��ie�|���7A�2���O%P��E��htj��Y1��w�Ѓ!����  ���� ࢽ��My�7�\�a�@�ţ�J �4�Ȼ�F�@o�̒?4�wx��)��]�P��~�����u�����5�����7X ��9��^ܩ�U;Iꭆ 5 �������eK2�7(�{|��Y׎ �V��\"���Z�1� Z�����}��(�Ǝ"�1S���_�vE30>���p;� ΝD��%x�W�?W?v����o�^V�i�d��r[��/&>�~`�9Wh��y�;���R��� ;;ɮT��?����r$�g1�K����A��C��c��K��l:�'��3 c�ﳯ*"t8�~l��)���m��+U,z��`(�>yJ�?����h>��]��v��ЍG*�{`��;y]��I�T� ;c��NU�fo¾h���/$���|NS���1�S�"�H��V���T���4��uhǜ�]�v;���5�͠x��'C\�SBpl���h}�N����� A�Bx���%��ޭ�l��/����T��w�ʽ]D�=����K���ž�r㻠l4�S�O?=�k �M:� ��c�C�a�#ha���)�ѐxc�s���gP�iG��{+���x���Q���I= �� z��ԫ+ �8"�k�ñ�j=|����c ��y��CF��/��*9ж�h{ �?4�o� ��k�m�Q�N�x��;�Y��4膚�a�w?�6�>e]�����Q�r�:����g�,i"�����ԩA�*M�<�G��b�if��l^M��5� �Ҩ�{����6J��ZJ�����P�*�����Y���ݛu�_4�9�I8�7���������,^ToR���m4�H��?�N�S�ѕw��/S��甍�@�9H�S�T��t�ƻ���ʒU��*{Xs�@����f�����֒Li�K{H�w^���������Ϥm�tq���s� ���ք��f:��o~s��g�r��ט� �S�ѱC�e]�x���a��) ���(b-$(�j>�7q�B?ӕ�F��hV25r[7 Y� }L�R��}����*sg+��x�r�2�U=�*'WS��ZDW]�WǞ�<��叓���{�$�9Ou4��y�90-�1�'*D`�c�^o?(�9��u���ݐ��'PI&� f�Jݮ�������:wS����jfP1F:X �H�9dԯ���˝[�_54 �}*;@�ܨ�� ð�yn�T���?�ןd�#���4rG�ͨ��H�1�|-#���Mr�S3��G�3�����)�.᧏3v�z֑��r����$G"�`j �1t��x0<Ɔ�Wh6�y�6��,œ�Ga��gA����y��b��)��h�D��ß�_�m��ü �gG;��e�v��ݝ�nQ� ��C����-�*��o���y�a��M��I�>�<���]obD��"�:���G�A��-\%LT�8���c�)��+y76���o�Q�#*{�(F�⽕�y����=���rW�\p���۩�c���A���^e6��K������ʐ�cVf5$�'->���ՉN"���F�"�UQ@�f��Gb~��#�&�M=��8�ט�JNu9��D��[̤�s�o�~������ G��9T�tW^g5y$b��Y'��س�Ǵ�=��U-2 #�MC�t(�i� �lj�@Q 5�̣i�*�O����s�x�K�f��}\��M{E�V�{�υ��Ƈ�����);�H����I��fe�Lȣr�2��>��W�I�Ȃ6������i��k�� �5�YOxȺ����>��Y�f5'��|��H+��98pj�n�.O�y�������jY��~��i�w'������l�;�s�2��Y��:'lg�ꥴ)o#'Sa�a�K��Z� �m��}�`169�n���"���x��I ��*+� }F<��cГ���F�P�������ֹ*�PqX�x۩��,� ��N�� �4<-����%����:��7����W���u�`����� $�?�I��&����o��o��`v�>��P��"��l���4��5'�Z�gE���8���?��[�X�7(��.Q�-��*���ތL@̲����v��.5���[��=�t\+�CNܛ��,g�SQnH����}*F�G16���&:�t��4ُ"A��̣��$�b �|����#rs��a�����T�� ]�<�j��BS�('$�ɻ� �wP;�/�n��?�ݜ��x�F��yUn�~mL*-�������Xf�wd^�a�}��f�,=t�׵i�.2/wpN�Ep8�OР���•��R�FJ� 55TZ��T �ɭ�<��]��/�0�r�@�f��V��V����Nz�G��^���7hZi����k��3�,kN�e|�vg�1{9]_i��X5y7� 8e]�U����'�-2,���e"����]ot�I��Y_��n�(JҼ��1�O ]bXc���Nu�No��pS���Q_���_�?i�~�x h5d'�(qw52] ��'ޤ�q��o1�R!���`ywy�A4u���h<קy���\[~�4�\ X�Wt/� 6�����n�F�a8��f���z �3$�t(���q��q�x��^�XWeN'p<-v�!�{�(>ӽDP7��ո0�y)�e$ٕv�Ih'Q�EA�m*�H��RI��=:��� ���4牢) �%_iN�ݧ�l]� �Nt���G��H�L��� ɱ�g<���1V�,�J~�ٹ�"K��Q�� 9�HS�9�?@��k����r�;we݁�]I�!{ �@�G�[�"��`���J:�n]�{�cA�E����V��ʆ���#��U9�6����j�#Y�m\��q�e4h�B�7��C�������d<�?J����1g:ٳ���=Y���D�p�ц� ׈ǔ��1�]26؜oS�'��9�V�FVu�P�h�9�xc�oq�X��p�o�5��Ա5$�9W�V(�[Ak�aY錎qf;�'�[�|���b�6�Ck��)��#a#a˙��8���=äh�4��2��C��4tm^ �n'c���]GQ$[Wҿ��i���vN�{Fu ��1�gx��1┷���N�m��{j-,��x�� Ūm�ЧS�[�s���Gna���䑴�� x�p 8<������97�Q���ϴ�v�aϚG��Rt�Һ׈�f^\r��WH�JU�7Z���y)�vg=����n��4�_)y��D'y�6�]�c�5̪�\� �PF�k����&�c;��cq�$~T�7j ���nç]�<�g ":�to�t}�159�<�/�8������m�b�K#g'I'.W�����6��I/��>v��\�MN��g���m�A�yQL�4u�Lj�j9��#44�t��l^�}L����n��R��!��t��±]��r��h6ٍ>�yҏ�N��fU�� ���� Fm@�8}�/u��jb9������he:A�y�ծw��GpΧh�5����l}�3p468��)U��d��c����;Us/�֔�YX�1�O2��uq�s��`hwg�r~�{ R��mhN��؎*q 42�*th��>�#���E����#��Hv�O����q�}�����6�e��\�,Wk�#���X��b>��p}�դ��3���T5��†��6��[��@�P�y*n��|'f�֧>�lư΂�̺����SU�'*�q�p�_S�����M�� '��c�6�����m�� ySʨ;M��r���Ƌ�m�Kxo,���Gm�P��A�G�:��i��w�9�}M(�^�V��$ǒ�ѽ�9���|���� �a����J�SQ�a���r�B;����}���ٻ֢�2�%U���c�#�g���N�a�ݕ�'�v�[�OY'��3L�3�;,p�]@�S��{ls��X�'���c�jw�k'a�.��}�}&�� �dP�*�bK=ɍ!����;3n�gΊU�ߴmt�'*{,=SzfD� A��ko~�G�aoq�_mi}#�m�������P�Xhύ����mxǍ�΂���巿zf��Q���c���|kc�����?���W��Y�$���_Lv����l߶��c���`?����l�j�ݲˏ!V��6����U�Ђ(A���4y)H���p�Z_�x��>���e��R��$�/�`^'3qˏ�-&Q�=?��CFVR �D�fV�9��{�8g�������n�h�(P"��6�[�D���< E�����~0<@�`�G�6����Hг�cc�� �c�K.5��D��d�B���`?�XQ��2��ٿyqo&+�1^� DW�0�ꊩ���G�#��Q�nL3��c���������/��x ��1�1[y�x�პCW��C�c�UĨ80�m�e�4.{�m��u���I=��f�����0QRls9���f���������9���~f�����Ǩ��a�"@�8���ȁ�Q����#c�ic������G��$���G���r/$W�(��W���V�"��m�7�[m�A�m����bo��D� j����۳� l���^�k�h׽����� ��#� iXn�v��eT�k�a�^Y�4�BN��ĕ��0 !01@Q"2AaPq3BR������?���@4�Q�����T3,���㺠�W�[=JK�Ϟ���2�r^7��vc�:�9 �E�ߴ�w�S#d���Ix��u��:��Hp��9E!�� V 2;73|F��9Y���*ʬ�F��D����u&���y؟��^EA��A��(ɩ���^��GV:ݜDy�`��Jr29ܾ�㝉��[���E;Fzx��YG��U�e�Y�C���� ����v-tx����I�sם�Ę�q��Eb�+P\ :>�i�C'�;�����k|z�رn�y]�#ǿb��Q��������w�����(�r|ӹs��[�D��2v-%��@;�8<a���[\o[ϧw��I!��*0�krs)�[�J9^��ʜ��p1)� "��/_>��o��<1����A�E�y^�C��`�x1'ܣn�p��s`l���fQ��):�l����b>�Me�jH^?�kl3(�z:���1ŠK&?Q�~�{�ٺ�h�y���/�[��V�|6��}�KbX����mn[-��7�5q�94�������dm���c^���h� X��5��<�eޘ>G���-�}�دB�ޟ� ��|�rt�M��V+�]�c?�-#ڛ��^ǂ}���Lkr���O��u�>�-D�ry� D?:ޞ�U��ǜ�7�V��?瓮�"�#���r��չģVR;�n���/_� ؉v�ݶe5d�b9��/O��009�G���5n�W����JpA�*�r9�>�1��.[t���s�F���nQ� V 77R�]�ɫ8����_0<՜�IF�u(v��4��F�k�3��E)��N:��yڮe��P�`�1}�$WS��J�SQ�N�j�ٺ��޵�#l���ј(�5=��5�lǏmoW�v-�1����v,W�mn��߀$x�<����v�j(����c]��@#��1������Ǔ���o'��u+����;G�#�޸��v-lη��/(`i⣍Pm^���ԯ̾9Z��F��������n��1��� ��]�[��)�'������:�֪�W��FC����� �B9،!?���]��V��A�Վ�M��b�w��G F>_DȬ0¤�#�QR�[V��kz���m�w�"��9ZG�7'[��=�Q����j8R?�zf�\a�=��O�U����*oB�A�|G���2�54 �p��.w7� �� ��&������ξxGHp� B%��$g�����t�Џ򤵍z���HN�u�Я�-�'4��0��;_��3 !01"@AQa2Pq#3BR������?��ʩca��en��^��8���<�u#��m*08r��y�N"�<�Ѳ0��@\�p��� �����Kv�D��J8�Fҽ� �f�Y��-m�ybX�NP����}�!*8t(�OqѢ��Q�wW�K��ZD��Δ^e��!� ��B�K��p~�����e*l}z#9ң�k���q#�Ft�o��S�R����-�w�!�S���Ӥß|M�l޶V��!eˈ�8Y���c�ЮM2��tk���� ������J�fS����Ö*i/2�����n]�k�\���|4yX�8��U�P.���Ы[���l��@"�t�<������5�lF���vU�����W��W��;�b�cД^6[#7@vU�xgZv��F�6��Q,K�v��� �+Ъ��n��Ǣ��Ft���8��0��c�@�!�Zq s�v�t�;#](B��-�nῃ~���3g������5�J�%���O������n�kB�ĺ�.r��+���#�N$?�q�/�s�6��p��a����a��J/��M�8��6�ܰ"�*������ɗud"\w���aT(����[��F��U՛����RT�b���n�*��6���O��SJ�.�ij<�v�MT��R\c��5l�sZB>F��<7�;EA��{��E���Ö��1U/�#��d1�a�n.1ě����0�ʾR�h��|�R��Ao�3�m3 ��%�� ���28Q� ��y��φ���H�To�7�lW>����#i`�q���c����a��� �m,B�-j����݋�'mR1Ήt�>��V��p���s�0IbI�C.���1R�ea�����]H�6����������4B>��o��](��$B���m�����a�!=��?�B� K�Ǿ+�Ծ"�n���K��*��+��[T#�{E�J�S����Q�����s�5�:�U�\wĐ�f�3����܆&�)����I���Ԇw��E T�lrTf6Q|R�h:��[K�� �z��c֧�G�C��%\��_�a�84��HcO�bi��ؖV��7H �)*ģK~Xhչ0��4?�0��� �E<���}3���#���u�?�� ��|g�S�6ꊤ�|�I#Hڛ� �ա��w�X��9��7���Ŀ%�SL��y6č��|�F�a 8���b��$�sק�h���b9RAu7�˨p�Č�_\*w��묦��F ����4D~�f����|(�"m���NK��i�S�>�$d7SlA��/�²����SL��|6N�}���S�˯���g��]6��; �#�.��<���q'Q�1|KQ$�����񛩶"�$r�b:���N8�w@��8$�� �AjfG|~�9F ���Y��ʺ��Bwؒ������M:I岎�G��`s�YV5����6��A �b:�W���G�q%l�����F��H���7�������Fsv7��k�� 403WebShell
403Webshell
Server IP : 51.161.54.47  /  Your IP : 216.73.216.98
Web Server : Apache/2.4.68 (Unix) OpenSSL/1.1.1k
System : Linux host.ditinformatica.ar 4.18.0-553.153.1.el8_10.x86_64 #1 SMP Thu Aug 6 00:53:12 EDT 2026 x86_64
User : kalaycom ( 1021)
PHP Version : 7.4.33
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : OFF  |  Sudo : ON  |  Pkexec : ON
Directory :  /usr/share/scap-security-guide/ansible/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /usr/share/scap-security-guide/ansible/almalinux8-playbook-cis.yml
---
###############################################################################
#
# Ansible Playbook for CIS AlmaLinux OS 8 Benchmark for Level 2 - Server
#
# Profile Description:
# This profile defines a baseline that aligns to the "Level 2 - Server"
# configuration from the Center for Internet Security®
# AlmaLinux OS 8 Benchmark™, v4.0.0, released 2025-08-28.
# This profile includes Center for Internet Security®
# AlmaLinux OS 8 CIS Benchmarks™ content.
#
# Profile ID:  xccdf_org.ssgproject.content_profile_cis
# Benchmark ID:  xccdf_org.ssgproject.content_benchmark_ALMALINUX-8
# Benchmark Version:  0.1.81
# XCCDF Version:  1.2
#
# This Ansible Playbook is generated from an XCCDF profile without preliminary evaluation.
# It attempts to fix every selected rule, even if the system is already compliant.
#
# How to apply this Ansible Playbook:
# $ ansible-playbook -i "localhost," -c local playbook.yml
# $ ansible-playbook -i "192.168.1.155," playbook.yml
# $ ansible-playbook -i inventory.ini playbook.yml
#
###############################################################################

- name: Ansible Playbook for xccdf_org.ssgproject.content_profile_cis
  hosts: all
  vars:
    inactivity_timeout_value: '900'
    var_screensaver_lock_delay: '5'
    var_sudo_logfile: /var/log/sudo.log
    var_sudo_timestamp_timeout: '15'
    var_authselect_profile: sssd
    cis_banner_text: Authorized users only. All activity may be monitored and reported.
    dconf_login_banner_contents: Authorized uses only. All activity may be monitored
      and reported.
    var_password_pam_remember: '24'
    var_password_pam_remember_control_flag: requisite,required
    var_accounts_passwords_pam_faillock_deny: '5'
    var_accounts_passwords_pam_faillock_unlock_time: '900'
    var_password_pam_dictcheck: '1'
    var_password_pam_difok: '2'
    var_password_pam_maxrepeat: '3'
    var_password_pam_maxsequence: '3'
    var_password_pam_minlen: '14'
    var_password_hashing_algorithm: YESCRYPT|SHA512
    var_password_hashing_algorithm_pam: yescrypt|sha512
    var_account_disable_post_pw_expiration: '45'
    var_accounts_maximum_age_login_defs: '365'
    var_accounts_password_warn_age_login_defs: '7'
    var_pam_wheel_group_for_su: sugroup
    var_accounts_tmout: '900'
    var_user_initialization_files_regex: ^\.[\w\- ]+$
    var_accounts_user_umask: '027'
    sysctl_net_ipv6_conf_all_accept_ra_value: '0'
    sysctl_net_ipv6_conf_all_accept_redirects_value: '0'
    sysctl_net_ipv6_conf_all_accept_source_route_value: '0'
    sysctl_net_ipv6_conf_all_forwarding_value: '0'
    sysctl_net_ipv6_conf_default_accept_ra_value: '0'
    sysctl_net_ipv6_conf_default_accept_redirects_value: '0'
    sysctl_net_ipv6_conf_default_accept_source_route_value: '0'
    sysctl_net_ipv6_conf_default_forwarding_value: '0'
    sysctl_net_ipv4_conf_all_accept_redirects_value: '0'
    sysctl_net_ipv4_conf_all_accept_source_route_value: '0'
    sysctl_net_ipv4_conf_all_forwarding_value: '0'
    sysctl_net_ipv4_conf_all_log_martians_value: '1'
    sysctl_net_ipv4_conf_all_rp_filter_value: '1'
    sysctl_net_ipv4_conf_all_secure_redirects_value: '0'
    sysctl_net_ipv4_conf_default_accept_redirects_value: '0'
    sysctl_net_ipv4_conf_default_accept_source_route_value: '0'
    sysctl_net_ipv4_conf_default_forwarding_value: '0'
    sysctl_net_ipv4_conf_default_log_martians_value: '1'
    sysctl_net_ipv4_conf_default_rp_filter_value: '1'
    sysctl_net_ipv4_conf_default_secure_redirects_value: '0'
    sysctl_net_ipv4_icmp_echo_ignore_broadcasts_value: '1'
    sysctl_net_ipv4_icmp_ignore_bogus_error_responses_value: '1'
    sysctl_net_ipv4_tcp_syncookies_value: '1'
    var_selinux_policy_name: targeted
    var_selinux_state: enforcing
    var_postfix_inet_interfaces: loopback-only
    var_multiple_time_servers: 0.rhel.pool.ntp.org,1.rhel.pool.ntp.org,2.rhel.pool.ntp.org,3.rhel.pool.ntp.org
    var_sshd_set_keepalive: '1'
    sshd_idle_timeout_value: '300'
    var_sshd_set_login_grace_time: '60'
    sshd_max_auth_tries_value: '4'
    var_sshd_max_sessions: '10'
    var_sshd_set_maxstartups: 10:30:60
    var_audit_backlog_limit: '8192'
    var_accounts_passwords_pam_faillock_dir: /var/run/faillock
    var_auditd_disk_error_action: syslog|single|halt
    var_auditd_disk_full_action: single|halt
    var_auditd_admin_space_left_action: single|halt
    var_auditd_max_log_file: '8'
    var_auditd_max_log_file_action: keep_logs
    var_auditd_space_left_action: email|exec|single|halt
  tasks:

  - name: Gather the package facts
    ansible.builtin.package_facts:
      manager: auto
    tags:
    - always

  - name: Ensure aide is installed
    ansible.builtin.package:
      name: aide
      state: present
    when: '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.10.1.3
    - DISA-STIG-RHEL-08-010359
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-11.5
    - PCI-DSSv4-11.5.2
    - enable_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - package_aide_installed

  - name: Build and Test AIDE Database - Ensure AIDE Is Installed
    ansible.builtin.package:
      name: '{{ item }}'
      state: present
    with_items:
    - aide
    when: '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.10.1.3
    - DISA-STIG-RHEL-08-010359
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-11.5
    - PCI-DSSv4-11.5.2
    - aide_build_database
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Configure AIDE to Verify the Audit Tools - Ensure AIDE is Installed
    ansible.builtin.package:
      name: '{{ item }}'
      state: present
    with_items:
    - aide
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-030650
    - NIST-800-53-AU-9(3)
    - NIST-800-53-AU-9(3).1
    - aide_check_audit_tools
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Configure Periodic Execution of AIDE - Ensure AIDE is installed
    ansible.builtin.package:
      name: aide
      state: present
    when: '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.10.1.3
    - NIST-800-53-CM-6(a)
    - NIST-800-53-SI-7
    - NIST-800-53-SI-7(1)
    - PCI-DSS-Req-11.5
    - PCI-DSSv4-11.5.2
    - aide_periodic_cron_checking
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Configure Periodic Execution of AIDE - Install cron
    ansible.builtin.package:
      name: cronie
      state: present
    when: '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.10.1.3
    - NIST-800-53-CM-6(a)
    - NIST-800-53-SI-7
    - NIST-800-53-SI-7(1)
    - PCI-DSS-Req-11.5
    - PCI-DSSv4-11.5.2
    - aide_periodic_cron_checking
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: 'Remove the GDM Package Group: Ensure gdm is removed'
    ansible.builtin.package:
      name: gdm
      state: absent
    when: '"gdm" in ansible_facts.packages'
    tags:
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - disable_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - package_gdm_removed

  - name: Ensure sudo is installed
    ansible.builtin.package:
      name: sudo
      state: present
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - enable_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - package_sudo_installed

  - name: Ensure authselect is installed
    ansible.builtin.package:
      name: authselect
      state: present
    tags:
    - enable_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - package_authselect_installed

  - name: Ensure pam is installed
    ansible.builtin.package:
      name: pam
      state: present
    tags:
    - enable_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - package_pam_installed

  - name: Ensure libpwquality is installed
    ansible.builtin.package:
      name: libpwquality
      state: present
    when: '"pam" in ansible_facts.packages'
    tags:
    - enable_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - package_pam_pwquality_installed

  - name: Ensure rsyslog is installed
    ansible.builtin.package:
      name: rsyslog
      state: present
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-030670
    - NIST-800-53-CM-6(a)
    - enable_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - package_rsyslog_installed

  - name: Ensure systemd-journal-remote is installed
    ansible.builtin.package:
      name: systemd-journal-remote
      state: present
    when: '"kernel" in ansible_facts.packages'
    tags:
    - enable_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - package_systemd-journal-remote_installed

  - name: Ensure firewalld is installed
    ansible.builtin.package:
      name: firewalld
      state: present
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040100
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-1.2
    - PCI-DSSv4-1.2.1
    - enable_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - package_firewalld_installed

  - name: Deactivate Wireless Network Interfaces - Ensure NetworkManager is installed
    ansible.builtin.package:
      name: '{{ item }}'
      state: present
    with_items:
    - NetworkManager
    when: ( not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman",
      "container"] ) )
    tags:
    - DISA-STIG-RHEL-08-040110
    - NIST-800-171-3.1.16
    - NIST-800-53-AC-18(3)
    - NIST-800-53-AC-18(a)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - PCI-DSS-Req-1.3.3
    - PCI-DSSv4-1.3
    - PCI-DSSv4-1.3.3
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - unknown_strategy
    - wireless_disable_interfaces

  - name: Ensure libselinux is installed
    ansible.builtin.package:
      name: libselinux
      state: present
    when: '"kernel" in ansible_facts.packages'
    tags:
    - PCI-DSSv4-1.2
    - PCI-DSSv4-1.2.6
    - enable_strategy
    - high_severity
    - low_complexity
    - low_disruption
    - no_reboot_needed
    - package_libselinux_installed

  - name: 'Uninstall mcstrans Package: Ensure mcstrans is removed'
    ansible.builtin.package:
      name: mcstrans
      state: absent
    when: '"kernel" in ansible_facts.packages'
    tags:
    - disable_strategy
    - low_complexity
    - low_disruption
    - low_severity
    - no_reboot_needed
    - package_mcstrans_removed

  - name: 'Uninstall setroubleshoot Package: Ensure setroubleshoot is removed'
    ansible.builtin.package:
      name: setroubleshoot
      state: absent
    when: '"kernel" in ansible_facts.packages'
    tags:
    - disable_strategy
    - low_complexity
    - low_disruption
    - low_severity
    - no_reboot_needed
    - package_setroubleshoot_removed

  - name: Ensure cron is installed
    ansible.builtin.package:
      name: cron
      state: present
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - enable_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - package_cron_installed

  - name: 'Uninstall DHCP Server Package: Ensure dhcp is removed'
    ansible.builtin.package:
      name: dhcp
      state: absent
    tags:
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.4
    - disable_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - package_dhcp_removed

  - name: 'Uninstall bind Package: Ensure bind is removed'
    ansible.builtin.package:
      name: bind
      state: absent
    tags:
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - disable_strategy
    - low_complexity
    - low_disruption
    - low_severity
    - no_reboot_needed
    - package_bind_removed

  - name: 'Remove ftp Package: Ensure ftp is removed'
    ansible.builtin.package:
      name: ftp
      state: absent
    tags:
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.4
    - disable_strategy
    - low_complexity
    - low_disruption
    - low_severity
    - no_reboot_needed
    - package_ftp_removed

  - name: 'Uninstall vsftpd Package: Ensure vsftpd is removed'
    ansible.builtin.package:
      name: vsftpd
      state: absent
    tags:
    - DISA-STIG-RHEL-08-040360
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-CM-7.1(ii)
    - NIST-800-53-IA-5(1)(c)
    - NIST-800-53-IA-5(1).1(v)
    - disable_strategy
    - high_severity
    - low_complexity
    - low_disruption
    - no_reboot_needed
    - package_vsftpd_removed

  - name: 'Uninstall httpd Package: Ensure httpd is removed'
    ansible.builtin.package:
      name: httpd
      state: absent
    tags:
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - disable_strategy
    - low_complexity
    - low_disruption
    - no_reboot_needed
    - package_httpd_removed
    - unknown_severity

  - name: 'Uninstall nginx Package: Ensure nginx is removed'
    ansible.builtin.package:
      name: nginx
      state: absent
    tags:
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - disable_strategy
    - low_complexity
    - low_disruption
    - no_reboot_needed
    - package_nginx_removed
    - unknown_severity

  - name: 'Uninstall cyrus-imapd Package: Ensure cyrus-imapd is removed'
    ansible.builtin.package:
      name: cyrus-imapd
      state: absent
    tags:
    - disable_strategy
    - low_complexity
    - low_disruption
    - no_reboot_needed
    - package_cyrus-imapd_removed
    - unknown_severity

  - name: 'Uninstall dovecot Package: Ensure dovecot is removed'
    ansible.builtin.package:
      name: dovecot
      state: absent
    tags:
    - disable_strategy
    - low_complexity
    - low_disruption
    - no_reboot_needed
    - package_dovecot_removed
    - unknown_severity

  - name: 'Ensure LDAP client is not installed: Ensure openldap-clients is removed'
    ansible.builtin.package:
      name: openldap-clients
      state: absent
    tags:
    - disable_strategy
    - low_complexity
    - low_disruption
    - low_severity
    - no_reboot_needed
    - package_openldap-clients_removed

  - name: Ensure chrony is installed
    ansible.builtin.package:
      name: chrony
      state: present
    when: '"kernel" in ansible_facts.packages'
    tags:
    - PCI-DSS-Req-10.4
    - PCI-DSSv4-10.6
    - PCI-DSSv4-10.6.1
    - enable_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - package_chrony_installed

  - name: 'Uninstall rsync Package: Ensure rsync is removed'
    ansible.builtin.package:
      name: rsync
      state: absent
    tags:
    - disable_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - package_rsync_removed

  - name: 'Uninstall xinetd package if not used by network services: Ensure xinetd
      is removed'
    ansible.builtin.package:
      name: xinetd
      state: absent
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.4
    - disable_strategy
    - low_complexity
    - low_disruption
    - low_severity
    - no_reboot_needed
    - package_xinetd_removed

  - name: 'Remove NIS Client: Ensure ypbind is removed'
    ansible.builtin.package:
      name: ypbind
      state: absent
    tags:
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.4
    - disable_strategy
    - low_complexity
    - low_disruption
    - no_reboot_needed
    - package_ypbind_removed
    - unknown_severity

  - name: 'Uninstall ypserv Package: Ensure ypserv is removed'
    ansible.builtin.package:
      name: ypserv
      state: absent
    tags:
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-IA-5(1)(c)
    - PCI-DSS-Req-2.2.2
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.4
    - disable_strategy
    - high_severity
    - low_complexity
    - low_disruption
    - no_reboot_needed
    - package_ypserv_removed

  - name: 'Uninstall telnet-server Package: Ensure telnet-server is removed'
    ansible.builtin.package:
      name: telnet-server
      state: absent
    tags:
    - DISA-STIG-RHEL-08-040000
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - PCI-DSS-Req-2.2.2
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.4
    - disable_strategy
    - high_severity
    - low_complexity
    - low_disruption
    - no_reboot_needed
    - package_telnet-server_removed

  - name: 'Remove telnet Clients: Ensure telnet is removed'
    ansible.builtin.package:
      name: telnet
      state: absent
    tags:
    - NIST-800-171-3.1.13
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.4
    - disable_strategy
    - low_complexity
    - low_disruption
    - low_severity
    - no_reboot_needed
    - package_telnet_removed

  - name: 'Uninstall tftp-server Package: Ensure tftp-server is removed'
    ansible.builtin.package:
      name: tftp-server
      state: absent
    tags:
    - DISA-STIG-RHEL-08-040190
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.4
    - disable_strategy
    - high_severity
    - low_complexity
    - low_disruption
    - no_reboot_needed
    - package_tftp-server_removed

  - name: 'Remove tftp Daemon: Ensure tftp is removed'
    ansible.builtin.package:
      name: tftp
      state: absent
    tags:
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.4
    - disable_strategy
    - low_complexity
    - low_disruption
    - low_severity
    - no_reboot_needed
    - package_tftp_removed

  - name: 'Uninstall squid Package: Ensure squid is removed'
    ansible.builtin.package:
      name: squid
      state: absent
    tags:
    - disable_strategy
    - low_complexity
    - low_disruption
    - no_reboot_needed
    - package_squid_removed
    - unknown_severity

  - name: 'Uninstall Samba Package: Ensure samba is removed'
    ansible.builtin.package:
      name: samba
      state: absent
    tags:
    - disable_strategy
    - low_complexity
    - low_disruption
    - no_reboot_needed
    - package_samba_removed
    - unknown_severity

  - name: 'Uninstall net-snmp Package: Ensure net-snmp is removed'
    ansible.builtin.package:
      name: net-snmp
      state: absent
    tags:
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.4
    - disable_strategy
    - low_complexity
    - low_disruption
    - no_reboot_needed
    - package_net-snmp_removed
    - unknown_severity

  - name: 'Remove the X Windows Xwayland Package: Ensure xorg-x11-server-Xwayland
      is removed'
    ansible.builtin.package:
      name: xorg-x11-server-Xwayland
      state: absent
    when: not ( "gdm" in ansible_facts.packages )
    tags:
    - disable_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - package_xorg-x11-server-Xwayland_removed

  - name: Ensure audit-libs is installed
    ansible.builtin.package:
      name: audit-libs
      state: present
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-7(a)
    - NIST-800-53-AU-12(2)
    - NIST-800-53-AU-14
    - NIST-800-53-AU-2(a)
    - NIST-800-53-AU-7(1)
    - NIST-800-53-AU-7(2)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.1
    - enable_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - package_audit-libs_installed

  - name: Ensure audit is installed
    ansible.builtin.package:
      name: audit
      state: present
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-030180
    - NIST-800-53-AC-7(a)
    - NIST-800-53-AU-12(2)
    - NIST-800-53-AU-14
    - NIST-800-53-AU-2(a)
    - NIST-800-53-AU-7(1)
    - NIST-800-53-AU-7(2)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.1
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - enable_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - package_audit_installed

  - name: Gather the package facts
    ansible.builtin.package_facts:
      manager: auto
    tags:
    - always

  - name: Enable rsyslog Service - Enable service rsyslog
    block:

    - name: Enable rsyslog Service - Enable Service rsyslog
      ansible.builtin.systemd:
        name: rsyslog
        enabled: true
        state: started
        masked: false
      when:
      - '"rsyslog" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-010561
    - NIST-800-53-AU-4(1)
    - NIST-800-53-CM-6(a)
    - enable_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - service_rsyslog_enabled
    - special_service_block
    when: '"kernel" in ansible_facts.packages'

  - name: Enable systemd-journal-upload Service - Enable service systemd-journal-upload
    block:

    - name: Enable systemd-journal-upload Service - Enable Service systemd-journal-upload
      ansible.builtin.systemd:
        name: systemd-journal-upload
        enabled: true
        state: started
        masked: false
      when:
      - '"systemd-journal-remote" in ansible_facts.packages'
    tags:
    - enable_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - service_systemd-journal-upload_enabled
    - special_service_block
    when:
    - '"kernel" in ansible_facts.packages'
    - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      and "systemd-journal-remote" in ansible_facts.packages )

  - name: Enable systemd-journald Service - Enable service systemd-journald
    block:

    - name: Enable systemd-journald Service - Enable Service systemd-journald
      ansible.builtin.systemd:
        name: systemd-journald
        enabled: true
        state: started
        masked: false
      when:
      - '"systemd" in ansible_facts.packages'
    tags:
    - NIST-800-53-SC-24
    - enable_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - service_systemd-journald_enabled
    - special_service_block
    when: '"kernel" in ansible_facts.packages'

  - name: Verify firewalld Enabled - Enable service firewalld
    block:

    - name: Verify firewalld Enabled - Enable Service firewalld
      ansible.builtin.systemd:
        name: firewalld
        enabled: true
        state: started
        masked: false
      when:
      - '"firewalld" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040101
    - NIST-800-171-3.1.3
    - NIST-800-171-3.4.7
    - NIST-800-53-AC-4
    - NIST-800-53-CA-3(5)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-7(21)
    - PCI-DSSv4-1.2
    - PCI-DSSv4-1.2.1
    - enable_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - service_firewalld_enabled
    - special_service_block
    when:
    - '"kernel" in ansible_facts.packages'
    - '"firewalld" in ansible_facts.packages'

  - name: Disable Bluetooth Service - Disable service bluetooth
    block:

    - name: Disable Bluetooth Service - Collect systemd Services Present in the System
      ansible.builtin.command: systemctl -q list-unit-files --type service
      register: service_exists
      changed_when: false
      failed_when: service_exists.rc not in [0, 1]
      check_mode: false

    - name: Disable Bluetooth Service - Ensure bluetooth.service is Masked
      ansible.builtin.systemd:
        name: bluetooth.service
        state: stopped
        enabled: false
        masked: true
      when: service_exists.stdout_lines is search("bluetooth.service", multiline=True)

    - name: Unit Socket Exists - bluetooth.socket
      ansible.builtin.command: systemctl -q list-unit-files bluetooth.socket
      register: socket_file_exists
      changed_when: false
      failed_when: socket_file_exists.rc not in [0, 1]
      check_mode: false

    - name: Disable Bluetooth Service - Disable Socket bluetooth
      ansible.builtin.systemd:
        name: bluetooth.socket
        enabled: false
        state: stopped
        masked: true
      when: socket_file_exists.stdout_lines is search("bluetooth.socket", multiline=True)
    tags:
    - NIST-800-171-3.1.16
    - NIST-800-53-AC-18(3)
    - NIST-800-53-AC-18(a)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - disable_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - service_bluetooth_disabled
    - special_service_block
    when: '"kernel" in ansible_facts.packages'

  - name: Disable the Automounter - Disable service autofs
    block:

    - name: Disable the Automounter - Collect systemd Services Present in the System
      ansible.builtin.command: systemctl -q list-unit-files --type service
      register: service_exists
      changed_when: false
      failed_when: service_exists.rc not in [0, 1]
      check_mode: false

    - name: Disable the Automounter - Ensure autofs.service is Masked
      ansible.builtin.systemd:
        name: autofs.service
        state: stopped
        enabled: false
        masked: true
      when: service_exists.stdout_lines is search("autofs.service", multiline=True)

    - name: Unit Socket Exists - autofs.socket
      ansible.builtin.command: systemctl -q list-unit-files autofs.socket
      register: socket_file_exists
      changed_when: false
      failed_when: socket_file_exists.rc not in [0, 1]
      check_mode: false

    - name: Disable the Automounter - Disable Socket autofs
      ansible.builtin.systemd:
        name: autofs.socket
        enabled: false
        state: stopped
        masked: true
      when: socket_file_exists.stdout_lines is search("autofs.socket", multiline=True)
    tags:
    - DISA-STIG-RHEL-08-040070
    - NIST-800-171-3.4.6
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - disable_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - service_autofs_disabled
    - special_service_block
    when: ( "autofs" in ansible_facts.packages and "kernel" in ansible_facts.packages
      )

  - name: Disable Avahi Server Software - Disable service avahi-daemon
    block:

    - name: Disable Avahi Server Software - Collect systemd Services Present in the
        System
      ansible.builtin.command: systemctl -q list-unit-files --type service
      register: service_exists
      changed_when: false
      failed_when: service_exists.rc not in [0, 1]
      check_mode: false

    - name: Disable Avahi Server Software - Ensure avahi-daemon.service is Masked
      ansible.builtin.systemd:
        name: avahi-daemon.service
        state: stopped
        enabled: false
        masked: true
      when: service_exists.stdout_lines is search("avahi-daemon.service", multiline=True)

    - name: Unit Socket Exists - avahi-daemon.socket
      ansible.builtin.command: systemctl -q list-unit-files avahi-daemon.socket
      register: socket_file_exists
      changed_when: false
      failed_when: socket_file_exists.rc not in [0, 1]
      check_mode: false

    - name: Disable Avahi Server Software - Disable Socket avahi-daemon
      ansible.builtin.systemd:
        name: avahi-daemon.socket
        enabled: false
        state: stopped
        masked: true
      when: socket_file_exists.stdout_lines is search("avahi-daemon.socket", multiline=True)
    tags:
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.4
    - disable_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - service_avahi-daemon_disabled
    - special_service_block
    when: ( "avahi" in ansible_facts.packages and "kernel" in ansible_facts.packages
      )

  - name: Disable Cockpit Management Server - Disable service cockpit
    block:

    - name: Disable Cockpit Management Server - Collect systemd Services Present in
        the System
      ansible.builtin.command: systemctl -q list-unit-files --type service
      register: service_exists
      changed_when: false
      failed_when: service_exists.rc not in [0, 1]
      check_mode: false

    - name: Disable Cockpit Management Server - Ensure cockpit.service is Masked
      ansible.builtin.systemd:
        name: cockpit.service
        state: stopped
        enabled: false
        masked: true
      when: service_exists.stdout_lines is search("cockpit.service", multiline=True)

    - name: Unit Socket Exists - cockpit.socket
      ansible.builtin.command: systemctl -q list-unit-files cockpit.socket
      register: socket_file_exists
      changed_when: false
      failed_when: socket_file_exists.rc not in [0, 1]
      check_mode: false

    - name: Disable Cockpit Management Server - Disable Socket cockpit
      ansible.builtin.systemd:
        name: cockpit.socket
        enabled: false
        state: stopped
        masked: true
      when: socket_file_exists.stdout_lines is search("cockpit.socket", multiline=True)
    tags:
    - disable_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - service_cockpit_disabled
    - special_service_block
    when: '"kernel" in ansible_facts.packages'

  - name: Enable cron Service - Enable service crond
    block:

    - name: Enable cron Service - Enable Service crond
      ansible.builtin.systemd:
        name: crond
        enabled: true
        state: started
        masked: false
      when:
      - '"cronie" in ansible_facts.packages'
    tags:
    - NIST-800-53-CM-6(a)
    - enable_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - service_crond_enabled
    - special_service_block
    when: '"kernel" in ansible_facts.packages'

  - name: Disable dnsmasq Service - Disable service dnsmasq
    block:

    - name: Disable dnsmasq Service - Collect systemd Services Present in the System
      ansible.builtin.command: systemctl -q list-unit-files --type service
      register: service_exists
      changed_when: false
      failed_when: service_exists.rc not in [0, 1]
      check_mode: false

    - name: Disable dnsmasq Service - Ensure dnsmasq.service is Masked
      ansible.builtin.systemd:
        name: dnsmasq.service
        state: stopped
        enabled: false
        masked: true
      when: service_exists.stdout_lines is search("dnsmasq.service", multiline=True)

    - name: Unit Socket Exists - dnsmasq.socket
      ansible.builtin.command: systemctl -q list-unit-files dnsmasq.socket
      register: socket_file_exists
      changed_when: false
      failed_when: socket_file_exists.rc not in [0, 1]
      check_mode: false

    - name: Disable dnsmasq Service - Disable Socket dnsmasq
      ansible.builtin.systemd:
        name: dnsmasq.socket
        enabled: false
        state: stopped
        masked: true
      when: socket_file_exists.stdout_lines is search("dnsmasq.socket", multiline=True)
    tags:
    - disable_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - service_dnsmasq_disabled
    - special_service_block
    when: '"kernel" in ansible_facts.packages'

  - name: Disable rpcbind Service - Disable service rpcbind
    block:

    - name: Disable rpcbind Service - Collect systemd Services Present in the System
      ansible.builtin.command: systemctl -q list-unit-files --type service
      register: service_exists
      changed_when: false
      failed_when: service_exists.rc not in [0, 1]
      check_mode: false

    - name: Disable rpcbind Service - Ensure rpcbind.service is Masked
      ansible.builtin.systemd:
        name: rpcbind.service
        state: stopped
        enabled: false
        masked: true
      when: service_exists.stdout_lines is search("rpcbind.service", multiline=True)

    - name: Unit Socket Exists - rpcbind.socket
      ansible.builtin.command: systemctl -q list-unit-files rpcbind.socket
      register: socket_file_exists
      changed_when: false
      failed_when: socket_file_exists.rc not in [0, 1]
      check_mode: false

    - name: Disable rpcbind Service - Disable Socket rpcbind
      ansible.builtin.systemd:
        name: rpcbind.socket
        enabled: false
        state: stopped
        masked: true
      when: socket_file_exists.stdout_lines is search("rpcbind.socket", multiline=True)
    tags:
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.4
    - disable_strategy
    - low_complexity
    - low_disruption
    - low_severity
    - no_reboot_needed
    - service_rpcbind_disabled
    - special_service_block
    when: '"kernel" in ansible_facts.packages'

  - name: Disable Network File System (nfs) - Disable service nfs-server
    block:

    - name: Disable Network File System (nfs) - Collect systemd Services Present in
        the System
      ansible.builtin.command: systemctl -q list-unit-files --type service
      register: service_exists
      changed_when: false
      failed_when: service_exists.rc not in [0, 1]
      check_mode: false

    - name: Disable Network File System (nfs) - Ensure nfs-server.service is Masked
      ansible.builtin.systemd:
        name: nfs-server.service
        state: stopped
        enabled: false
        masked: true
      when: service_exists.stdout_lines is search("nfs-server.service", multiline=True)

    - name: Unit Socket Exists - nfs-server.socket
      ansible.builtin.command: systemctl -q list-unit-files nfs-server.socket
      register: socket_file_exists
      changed_when: false
      failed_when: socket_file_exists.rc not in [0, 1]
      check_mode: false

    - name: Disable Network File System (nfs) - Disable Socket nfs-server
      ansible.builtin.systemd:
        name: nfs-server.socket
        enabled: false
        state: stopped
        masked: true
      when: socket_file_exists.stdout_lines is search("nfs-server.socket", multiline=True)
    tags:
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - disable_strategy
    - low_complexity
    - low_disruption
    - no_reboot_needed
    - service_nfs_disabled
    - special_service_block
    - unknown_severity
    when: '"kernel" in ansible_facts.packages'

  - name: Disable the CUPS Service - Disable service cups
    block:

    - name: Disable the CUPS Service - Collect systemd Services Present in the System
      ansible.builtin.command: systemctl -q list-unit-files --type service
      register: service_exists
      changed_when: false
      failed_when: service_exists.rc not in [0, 1]
      check_mode: false

    - name: Disable the CUPS Service - Ensure cups.service is Masked
      ansible.builtin.systemd:
        name: cups.service
        state: stopped
        enabled: false
        masked: true
      when: service_exists.stdout_lines is search("cups.service", multiline=True)

    - name: Unit Socket Exists - cups.socket
      ansible.builtin.command: systemctl -q list-unit-files cups.socket
      register: socket_file_exists
      changed_when: false
      failed_when: socket_file_exists.rc not in [0, 1]
      check_mode: false

    - name: Disable the CUPS Service - Disable Socket cups
      ansible.builtin.systemd:
        name: cups.socket
        enabled: false
        state: stopped
        masked: true
      when: socket_file_exists.stdout_lines is search("cups.socket", multiline=True)
    tags:
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - disable_strategy
    - low_complexity
    - low_disruption
    - no_reboot_needed
    - service_cups_disabled
    - special_service_block
    - unknown_severity
    when: '"kernel" in ansible_facts.packages'

  - name: Enable auditd Service - Enable service auditd
    block:

    - name: Enable auditd Service - Enable Service auditd
      ansible.builtin.systemd:
        name: auditd
        enabled: true
        state: started
        masked: false
      when:
      - '"audit" in ansible_facts.packages'
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030181
    - NIST-800-171-3.3.1
    - NIST-800-171-3.3.2
    - NIST-800-171-3.3.6
    - NIST-800-53-AC-2(g)
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-10
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-14(1)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-AU-3
    - NIST-800-53-CM-6(a)
    - NIST-800-53-SI-4(23)
    - PCI-DSS-Req-10.1
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - enable_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - service_auditd_enabled
    - special_service_block
    when:
    - '"kernel" in ansible_facts.packages'
    - '"audit" in ansible_facts.packages'

  - name: Gather the service facts
    ansible.builtin.service_facts: null
    tags:
    - always

  - name: Build and Test AIDE Database - Check Whether the Stock AIDE Database Exists
    ansible.builtin.stat:
      path: /var/lib/aide/aide.db.new.gz
    register: aide_database_stat
    when: '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.10.1.3
    - DISA-STIG-RHEL-08-010359
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-11.5
    - PCI-DSSv4-11.5.2
    - aide_build_database
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Build and Test AIDE Database - Build and Test AIDE Database
    ansible.builtin.command: /usr/sbin/aide --init
    changed_when: true
    when:
    - '"kernel" in ansible_facts.packages'
    - not (aide_database_stat.stat.exists is defined and aide_database_stat.stat.exists)
    register: aide_database_init
    tags:
    - CJIS-5.10.1.3
    - DISA-STIG-RHEL-08-010359
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-11.5
    - PCI-DSSv4-11.5.2
    - aide_build_database
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Build and Test AIDE Database - Stage AIDE Database
    ansible.builtin.copy:
      src: /var/lib/aide/aide.db.new.gz
      dest: /var/lib/aide/aide.db.gz
      backup: true
      remote_src: true
    when:
    - '"kernel" in ansible_facts.packages'
    - aide_database_init is changed
    - not ansible_check_mode
    tags:
    - CJIS-5.10.1.3
    - DISA-STIG-RHEL-08-010359
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-11.5
    - PCI-DSSv4-11.5.2
    - aide_build_database
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Set "Configure AIDE to Verify the Audit Tools - audit_tools fact"
    ansible.builtin.set_fact:
      audit_tools:
      - /usr/sbin/auditctl
      - /usr/sbin/auditd
      - /usr/sbin/augenrules
      - /usr/sbin/aureport
      - /usr/sbin/ausearch
      - /usr/sbin/autrace
      - /usr/sbin/rsyslogd
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-030650
    - NIST-800-53-AU-9(3)
    - NIST-800-53-AU-9(3).1
    - aide_check_audit_tools
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Configure AIDE to Verify the Audit Tools - Ensure Existing AIDE Configuration
      for Audit Tools are Correct
    ansible.builtin.lineinfile:
      path: /etc/aide.conf
      regexp: ^{{ item }}\s
      line: '{{ item }} p+i+n+u+g+s+b+acl+selinux+xattrs+sha512'
      create: true
    with_items: '{{ audit_tools }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - '"aide" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-030650
    - NIST-800-53-AU-9(3)
    - NIST-800-53-AU-9(3).1
    - aide_check_audit_tools
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Configure AIDE to Verify the Audit Tools - Configure AIDE to Properly Protect
      Audit Tools
    ansible.builtin.lineinfile:
      path: /etc/aide.conf
      line: '{{ item }} p+i+n+u+g+s+b+acl+selinux+xattrs+sha512'
      create: true
    with_items: '{{ audit_tools }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - '"aide" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-030650
    - NIST-800-53-AU-9(3)
    - NIST-800-53-AU-9(3).1
    - aide_check_audit_tools
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Configure Periodic Execution of AIDE - Setup Cron Tab
    ansible.builtin.cron:
      name: run AIDE check
      minute: 5
      hour: 4
      user: root
      job: /usr/sbin/aide --check
    register: crontab_check
    when:
    - '"kernel" in ansible_facts.packages'
    - '''cronie'' in ansible_facts.packages'
    tags:
    - CJIS-5.10.1.3
    - NIST-800-53-CM-6(a)
    - NIST-800-53-SI-7
    - NIST-800-53-SI-7(1)
    - PCI-DSS-Req-11.5
    - PCI-DSSv4-11.5.2
    - aide_periodic_cron_checking
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Implement Custom Crypto Policy Modules for CIS Benchmark - Set the base
      crypto policy
    ansible.builtin.set_fact:
      expected_crypto_policy: DEFAULT:NO-SHA1
    tags:
    - configure_custom_crypto_policy_cis
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required

  - name: Implement Custom Crypto Policy Modules for CIS Benchmark - Create custom
      crypto policy module NO-SSHCBC
    ansible.builtin.lineinfile:
      path: /etc/crypto-policies/policies/modules/NO-SSHCBC.pmod
      owner: root
      group: root
      mode: '0644'
      line: cipher@SSH = -*-CBC
      create: true
      regexp: cipher@SSH
    tags:
    - configure_custom_crypto_policy_cis
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required

  - name: Implement Custom Crypto Policy Modules for CIS Benchmark - Update the expected
      policy
    ansible.builtin.set_fact:
      expected_crypto_policy: '{{ expected_crypto_policy + '':NO-SSHCBC'' }}'
    tags:
    - configure_custom_crypto_policy_cis
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required

  - name: Implement Custom Crypto Policy Modules for CIS Benchmark - Create custom
      crypto policy module NO-SSHWEAKCIPHERS
    ansible.builtin.lineinfile:
      path: /etc/crypto-policies/policies/modules/NO-SSHWEAKCIPHERS.pmod
      owner: root
      group: root
      mode: '0644'
      line: cipher@SSH = -3DES-CBC -AES-128-CBC -AES-192-CBC -AES-256-CBC -CHACHA20-POLY1305
      create: true
      regexp: cipher@SSH
    tags:
    - configure_custom_crypto_policy_cis
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required

  - name: Implement Custom Crypto Policy Modules for CIS Benchmark - Update the expected
      policy
    ansible.builtin.set_fact:
      expected_crypto_policy: '{{ expected_crypto_policy + '':NO-SSHWEAKCIPHERS''
        }}'
    tags:
    - configure_custom_crypto_policy_cis
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required

  - name: Implement Custom Crypto Policy Modules for CIS Benchmark - Create custom
      crypto policy module NO-SSHWEAKMACS
    ansible.builtin.lineinfile:
      path: /etc/crypto-policies/policies/modules/NO-SSHWEAKMACS.pmod
      owner: root
      group: root
      mode: '0644'
      line: mac@SSH = -HMAC-MD5* -UMAC-64* -UMAC-128*
      create: true
      regexp: mac@SSH
    tags:
    - configure_custom_crypto_policy_cis
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required

  - name: Implement Custom Crypto Policy Modules for CIS Benchmark - Update the expected
      policy
    ansible.builtin.set_fact:
      expected_crypto_policy: '{{ expected_crypto_policy + '':NO-SSHWEAKMACS'' }}'
    tags:
    - configure_custom_crypto_policy_cis
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required

  - name: Implement Custom Crypto Policy Modules for CIS Benchmark - Create custom
      crypto policy module NO-WEAKMAC
    ansible.builtin.lineinfile:
      path: /etc/crypto-policies/policies/modules/NO-WEAKMAC.pmod
      owner: root
      group: root
      mode: '0644'
      line: mac = -*-128*
      create: true
      regexp: mac
    tags:
    - configure_custom_crypto_policy_cis
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required

  - name: Implement Custom Crypto Policy Modules for CIS Benchmark - Update the expected
      policy
    ansible.builtin.set_fact:
      expected_crypto_policy: '{{ expected_crypto_policy + '':NO-WEAKMAC'' }}'
    tags:
    - configure_custom_crypto_policy_cis
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required

  - name: Implement Custom Crypto Policy Modules for CIS Benchmark - Check current
      crypto policy
    ansible.builtin.command: update-crypto-policies --show
    register: current_crypto_policy
    changed_when: false
    failed_when: false
    check_mode: false
    tags:
    - configure_custom_crypto_policy_cis
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required

  - name: Implement Custom Crypto Policy Modules for CIS Benchmark - Update crypto-policies
    ansible.builtin.command: update-crypto-policies --set {{ expected_crypto_policy
      }}
    when: current_crypto_policy.stdout.strip() != expected_crypto_policy
    tags:
    - configure_custom_crypto_policy_cis
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required

  - name: Configure SSH to use System Crypto Policy
    ansible.builtin.lineinfile:
      dest: /etc/sysconfig/sshd
      state: absent
      regexp: (?i)^\s*CRYPTO_POLICY.*$
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-17(2)
    - NIST-800-53-AC-17(a)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-MA-4(6)
    - NIST-800-53-SC-13
    - PCI-DSS-Req-2.2
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.7
    - configure_ssh_crypto_policy
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required

  - name: Make sure that the dconf databases are up-to-date with regards to respective
      keyfiles - Get database modification time for gdm
    ansible.builtin.stat:
      path: /etc/dconf/db/gdm
    register: gdm_db
    when:
    - '"gdm" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - PCI-DSS-Req-6.2
    - PCI-DSSv4-8.2
    - PCI-DSSv4-8.2.8
    - dconf_db_up_to_date
    - high_severity
    - low_complexity
    - medium_disruption
    - no_reboot_needed
    - unknown_strategy

  - name: Make sure that the dconf databases are up-to-date with regards to respective
      keyfiles - Get keyfiles for gdm
    ansible.builtin.find:
      paths: /etc/dconf/db/gdm.d/
    register: gdm_keyfiles
    when:
    - '"gdm" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - PCI-DSS-Req-6.2
    - PCI-DSSv4-8.2
    - PCI-DSSv4-8.2.8
    - dconf_db_up_to_date
    - high_severity
    - low_complexity
    - medium_disruption
    - no_reboot_needed
    - unknown_strategy

  - name: Make sure that the dconf databases are up-to-date with regards to respective
      keyfiles - Run dconf update for gdm
    ansible.builtin.command:
      cmd: dconf update
    when:
    - '"gdm" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - not gdm_db.stat.exists or gdm_keyfiles.files | length > 0 and gdm_keyfiles.files
      | map(attribute='mtime') | max > gdm_db.stat.mtime
    tags:
    - PCI-DSS-Req-6.2
    - PCI-DSSv4-8.2
    - PCI-DSSv4-8.2.8
    - dconf_db_up_to_date
    - high_severity
    - low_complexity
    - medium_disruption
    - no_reboot_needed
    - unknown_strategy

  - name: Make sure that the dconf databases are up-to-date with regards to respective
      keyfiles - Get database modification time for local
    ansible.builtin.stat:
      path: /etc/dconf/db/local
    register: local_db
    when:
    - '"gdm" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - PCI-DSS-Req-6.2
    - PCI-DSSv4-8.2
    - PCI-DSSv4-8.2.8
    - dconf_db_up_to_date
    - high_severity
    - low_complexity
    - medium_disruption
    - no_reboot_needed
    - unknown_strategy

  - name: Make sure that the dconf databases are up-to-date with regards to respective
      keyfiles - Get keyfiles for local
    ansible.builtin.find:
      paths: /etc/dconf/db/local.d/
    register: local_keyfiles
    when:
    - '"gdm" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - PCI-DSS-Req-6.2
    - PCI-DSSv4-8.2
    - PCI-DSSv4-8.2.8
    - dconf_db_up_to_date
    - high_severity
    - low_complexity
    - medium_disruption
    - no_reboot_needed
    - unknown_strategy

  - name: Make sure that the dconf databases are up-to-date with regards to respective
      keyfiles - Run dconf update for local
    ansible.builtin.command:
      cmd: dconf update
    when:
    - '"gdm" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - not local_db.stat.exists or local_keyfiles.files | length > 0 and local_keyfiles.files
      | map(attribute='mtime') | max > local_db.stat.mtime
    tags:
    - PCI-DSS-Req-6.2
    - PCI-DSSv4-8.2
    - PCI-DSSv4-8.2.8
    - dconf_db_up_to_date
    - high_severity
    - low_complexity
    - medium_disruption
    - no_reboot_needed
    - unknown_strategy

  - name: 'Disable XWayland: Disable XWayland'
    community.general.ini_file:
      path: /etc/gdm/custom.conf
      section: daemon
      option: WaylandEnable
      value: 'false'
      create: true
      state: present
    when: '"gdm" in ansible_facts.packages'
    tags:
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy
    - xwayland_disabled

  - name: Disable the GNOME3 Login User List
    community.general.ini_file:
      dest: /etc/dconf/db/gdm.d/00-security-settings
      section: org/gnome/login-screen
      option: disable-user-list
      value: 'true'
      no_extra_spaces: true
      create: true
    register: result_ini
    when: '"gdm" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-020032
    - NIST-800-53-AC-23
    - NIST-800-53-CM-6(a)
    - dconf_gnome_disable_user_list
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - unknown_strategy

  - name: Prevent user modification of GNOME3 disablement of Login User List
    ansible.builtin.lineinfile:
      path: /etc/dconf/db/gdm.d/locks/00-security-settings-lock
      regexp: ^/org/gnome/login-screen/disable-user-list$
      line: /org/gnome/login-screen/disable-user-list
      create: true
    register: result_lineinfile
    when: '"gdm" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-020032
    - NIST-800-53-AC-23
    - NIST-800-53-CM-6(a)
    - dconf_gnome_disable_user_list
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - unknown_strategy

  - name: Dconf Update
    ansible.builtin.command: dconf update
    when:
    - '"gdm" in ansible_facts.packages'
    - result_ini is changed or result_lineinfile is changed
    tags:
    - DISA-STIG-RHEL-08-020032
    - NIST-800-53-AC-23
    - NIST-800-53-CM-6(a)
    - dconf_gnome_disable_user_list
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - unknown_strategy

  - name: Disable XDMCP in GDM
    community.general.ini_file:
      path: /etc/gdm/custom.conf
      section: xdmcp
      option: Enable
      value: 'false'
      create: true
      mode: 420
    when: '"gdm" in ansible_facts.packages'
    tags:
    - gnome_gdm_disable_xdmcp
    - high_severity
    - low_complexity
    - medium_disruption
    - no_reboot_needed
    - unknown_strategy

  - name: Disable GNOME3 Automounting - automount
    community.general.ini_file:
      dest: /etc/dconf/db/local.d/00-security-settings
      section: org/gnome/desktop/media-handling
      option: automount
      value: 'false'
      create: true
      no_extra_spaces: true
    register: result_ini
    when: '"gdm" in ansible_facts.packages'
    tags:
    - NIST-800-171-3.1.7
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - PCI-DSSv4-3.4
    - PCI-DSSv4-3.4.2
    - dconf_gnome_disable_automount
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - unknown_strategy

  - name: Prevent user modification of GNOME3 Automounting - automount
    ansible.builtin.lineinfile:
      path: /etc/dconf/db/local.d/locks/00-security-settings-lock
      regexp: ^/org/gnome/desktop/media-handling/automount$
      line: /org/gnome/desktop/media-handling/automount
      create: true
    register: result_lineinfile
    when: '"gdm" in ansible_facts.packages'
    tags:
    - NIST-800-171-3.1.7
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - PCI-DSSv4-3.4
    - PCI-DSSv4-3.4.2
    - dconf_gnome_disable_automount
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - unknown_strategy

  - name: Dconf Update
    ansible.builtin.command: dconf update
    when:
    - '"gdm" in ansible_facts.packages'
    - result_ini is changed or result_lineinfile is changed
    tags:
    - NIST-800-171-3.1.7
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - PCI-DSSv4-3.4
    - PCI-DSSv4-3.4.2
    - dconf_gnome_disable_automount
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - unknown_strategy

  - name: Disable GNOME3 Automounting - automount-open
    community.general.ini_file:
      dest: /etc/dconf/db/local.d/00-security-settings
      section: org/gnome/desktop/media-handling
      option: automount-open
      value: 'false'
      create: true
      no_extra_spaces: true
    register: result_ini
    when: '"gdm" in ansible_facts.packages'
    tags:
    - NIST-800-171-3.1.7
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - PCI-DSSv4-3.4
    - PCI-DSSv4-3.4.2
    - dconf_gnome_disable_automount_open
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - unknown_strategy

  - name: Prevent user modification of GNOME3 Automounting - automount-open
    ansible.builtin.lineinfile:
      path: /etc/dconf/db/local.d/locks/00-security-settings-lock
      regexp: ^/org/gnome/desktop/media-handling/automount-open$
      line: /org/gnome/desktop/media-handling/automount-open
      create: true
    register: result_lineinfile
    when: '"gdm" in ansible_facts.packages'
    tags:
    - NIST-800-171-3.1.7
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - PCI-DSSv4-3.4
    - PCI-DSSv4-3.4.2
    - dconf_gnome_disable_automount_open
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - unknown_strategy

  - name: Dconf Update
    ansible.builtin.command: dconf update
    when:
    - '"gdm" in ansible_facts.packages'
    - result_ini is changed or result_lineinfile is changed
    tags:
    - NIST-800-171-3.1.7
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - PCI-DSSv4-3.4
    - PCI-DSSv4-3.4.2
    - dconf_gnome_disable_automount_open
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - unknown_strategy

  - name: Disable GNOME3 Automounting - autorun-never
    community.general.ini_file:
      dest: /etc/dconf/db/local.d/00-security-settings
      section: org/gnome/desktop/media-handling
      option: autorun-never
      value: 'true'
      create: true
      no_extra_spaces: true
    register: result_ini
    when: '"gdm" in ansible_facts.packages'
    tags:
    - NIST-800-171-3.1.7
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - dconf_gnome_disable_autorun
    - low_complexity
    - low_severity
    - medium_disruption
    - no_reboot_needed
    - unknown_strategy

  - name: Prevent user modification of GNOME3 Automounting - autorun-never
    ansible.builtin.lineinfile:
      path: /etc/dconf/db/local.d/locks/00-security-settings-lock
      regexp: ^/org/gnome/desktop/media-handling/autorun-never$
      line: /org/gnome/desktop/media-handling/autorun-never
      create: true
    register: result_lineinfile
    when: '"gdm" in ansible_facts.packages'
    tags:
    - NIST-800-171-3.1.7
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - dconf_gnome_disable_autorun
    - low_complexity
    - low_severity
    - medium_disruption
    - no_reboot_needed
    - unknown_strategy

  - name: Dconf Update
    ansible.builtin.command: dconf update
    when:
    - '"gdm" in ansible_facts.packages'
    - result_ini is changed or result_lineinfile is changed
    tags:
    - NIST-800-171-3.1.7
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - dconf_gnome_disable_autorun
    - low_complexity
    - low_severity
    - medium_disruption
    - no_reboot_needed
    - unknown_strategy

  - name: Set GNOME3 Screensaver Inactivity Timeout
    community.general.ini_file:
      dest: /etc/dconf/db/local.d/00-security-settings
      section: org/gnome/desktop/session
      option: idle-delay
      value: uint32 {{ inactivity_timeout_value }}
      create: true
      no_extra_spaces: true
    register: result_ini
    when: '"gdm" in ansible_facts.packages'
    tags:
    - CJIS-5.5.5
    - DISA-STIG-RHEL-08-020060
    - NIST-800-171-3.1.10
    - NIST-800-53-AC-11(a)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-8.1.8
    - PCI-DSSv4-8.2
    - PCI-DSSv4-8.2.8
    - dconf_gnome_screensaver_idle_delay
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - unknown_strategy

  - name: Dconf Update
    ansible.builtin.command: dconf update
    when:
    - '"gdm" in ansible_facts.packages'
    - result_ini is changed
    tags:
    - CJIS-5.5.5
    - DISA-STIG-RHEL-08-020060
    - NIST-800-171-3.1.10
    - NIST-800-53-AC-11(a)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-8.1.8
    - PCI-DSSv4-8.2
    - PCI-DSSv4-8.2.8
    - dconf_gnome_screensaver_idle_delay
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - unknown_strategy

  - name: Set GNOME3 Screensaver Lock Delay After Activation Period
    community.general.ini_file:
      dest: /etc/dconf/db/local.d/00-security-settings
      section: org/gnome/desktop/screensaver
      option: lock-delay
      value: uint32 {{ var_screensaver_lock_delay }}
      create: true
      no_extra_spaces: true
    register: result_ini
    when: '"gdm" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-020031
    - NIST-800-171-3.1.10
    - NIST-800-53-AC-11(a)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-8.1.8
    - PCI-DSSv4-8.2
    - PCI-DSSv4-8.2.8
    - dconf_gnome_screensaver_lock_delay
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - unknown_strategy

  - name: Dconf Update
    ansible.builtin.command: dconf update
    when:
    - '"gdm" in ansible_facts.packages'
    - result_ini is changed
    tags:
    - DISA-STIG-RHEL-08-020031
    - NIST-800-171-3.1.10
    - NIST-800-53-AC-11(a)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-8.1.8
    - PCI-DSSv4-8.2
    - PCI-DSSv4-8.2.8
    - dconf_gnome_screensaver_lock_delay
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - unknown_strategy

  - name: Prevent user modification of GNOME lock-delay
    ansible.builtin.lineinfile:
      path: /etc/dconf/db/local.d/locks/00-security-settings-lock
      regexp: ^/org/gnome/desktop/screensaver/lock-delay$
      line: /org/gnome/desktop/screensaver/lock-delay
      create: true
    register: result_lineinfile
    when: '"gdm" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-020080
    - NIST-800-171-3.1.10
    - NIST-800-53-CM-6(a)
    - dconf_gnome_screensaver_user_locks
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - unknown_strategy

  - name: Dconf Update
    ansible.builtin.command: dconf update
    when:
    - '"gdm" in ansible_facts.packages'
    - result_lineinfile is changed
    tags:
    - DISA-STIG-RHEL-08-020080
    - NIST-800-171-3.1.10
    - NIST-800-53-CM-6(a)
    - dconf_gnome_screensaver_user_locks
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - unknown_strategy

  - name: Prevent user modification of GNOME Session idle-delay
    ansible.builtin.lineinfile:
      path: /etc/dconf/db/local.d/locks/00-security-settings-lock
      regexp: ^/org/gnome/desktop/session/idle-delay$
      line: /org/gnome/desktop/session/idle-delay
      create: true
    register: result_lineinfile
    when: '"gdm" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-020081
    - NIST-800-171-3.1.10
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-8.1.8
    - PCI-DSSv4-8.2
    - PCI-DSSv4-8.2.8
    - dconf_gnome_session_idle_user_locks
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - unknown_strategy

  - name: Dconf Update
    ansible.builtin.command: dconf update
    when:
    - '"gdm" in ansible_facts.packages'
    - result_lineinfile is changed
    tags:
    - DISA-STIG-RHEL-08-020081
    - NIST-800-171-3.1.10
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-8.1.8
    - PCI-DSSv4-8.2
    - PCI-DSSv4-8.2.8
    - dconf_gnome_session_idle_user_locks
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - unknown_strategy

  - name: Ensure use_pty is enabled in /etc/sudoers
    ansible.builtin.lineinfile:
      path: /etc/sudoers
      regexp: ^[\s]*Defaults.*\buse_pty\b.*$
      line: Defaults use_pty
      validate: /usr/sbin/visudo -cf %s
    when:
    - '"kernel" in ansible_facts.packages'
    - '"sudo" in ansible_facts.packages'
    tags:
    - PCI-DSS-Req-10.2.5
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy
    - sudo_add_use_pty

  - name: Ensure logfile is enabled with the appropriate value in /etc/sudoers
    ansible.builtin.lineinfile:
      path: /etc/sudoers
      regexp: ^[\s]*Defaults\s(.*)\blogfile=[-]?.+\b(.*)$
      line: Defaults \1logfile={{ var_sudo_logfile }}\2
      validate: /usr/sbin/visudo -cf %s
      backrefs: true
    register: edit_sudoers_logfile_option
    when:
    - '"kernel" in ansible_facts.packages'
    - '"sudo" in ansible_facts.packages'
    tags:
    - PCI-DSS-Req-10.2.5
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - low_complexity
    - low_disruption
    - low_severity
    - no_reboot_needed
    - restrict_strategy
    - sudo_custom_logfile

  - name: Enable logfile option with appropriate value in /etc/sudoers
    ansible.builtin.lineinfile:
      path: /etc/sudoers
      line: Defaults logfile={{ var_sudo_logfile }}
      validate: /usr/sbin/visudo -cf %s
    when:
    - '"kernel" in ansible_facts.packages'
    - '"sudo" in ansible_facts.packages'
    - edit_sudoers_logfile_option is defined and not edit_sudoers_logfile_option.changed
    tags:
    - PCI-DSS-Req-10.2.5
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - low_complexity
    - low_disruption
    - low_severity
    - no_reboot_needed
    - restrict_strategy
    - sudo_custom_logfile

  - name: Find /etc/sudoers.d/ files
    ansible.builtin.find:
      paths:
      - /etc/sudoers.d/
    register: sudoers
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-010381
    - NIST-800-53-CM-6(a)
    - NIST-800-53-IA-11
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy
    - sudo_remove_no_authenticate

  - name: Remove lines containing !authenticate from sudoers files
    ansible.builtin.replace:
      regexp: (^(?!#).*[\s]+\!authenticate.*$)
      replace: '# \g<1>'
      path: '{{ item.path }}'
      validate: /usr/sbin/visudo -cf %s
    with_items:
    - path: /etc/sudoers
    - '{{ sudoers.files }}'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-010381
    - NIST-800-53-CM-6(a)
    - NIST-800-53-IA-11
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy
    - sudo_remove_no_authenticate

  - name: Find /etc/sudoers.d/ files
    ansible.builtin.find:
      paths:
      - /etc/sudoers.d/
    register: sudoers
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-010380
    - NIST-800-53-CM-6(a)
    - NIST-800-53-IA-11
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy
    - sudo_remove_nopasswd

  - name: Remove lines containing NOPASSWD from sudoers files
    ansible.builtin.replace:
      regexp: (^(?!#).*[\s]+NOPASSWD[\s]*\:.*$)
      replace: '# \g<1>'
      path: '{{ item.path }}'
      validate: /usr/sbin/visudo -cf %s
    with_items:
    - path: /etc/sudoers
    - '{{ sudoers.files }}'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-010380
    - NIST-800-53-CM-6(a)
    - NIST-800-53-IA-11
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy
    - sudo_remove_nopasswd

  - name: Require Re-Authentication When Using the sudo Command - Find /etc/sudoers.d/*
      files containing 'Defaults timestamp_timeout'
    ansible.builtin.find:
      path: /etc/sudoers.d
      patterns: '*'
      contains: ^[\s]*Defaults\s.*\btimestamp_timeout[\s]*=.*
    register: sudoers_d_defaults_timestamp_timeout
    when:
    - '"kernel" in ansible_facts.packages'
    - '"sudo" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-010384
    - NIST-800-53-IA-11
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy
    - sudo_require_reauthentication

  - name: Require Re-Authentication When Using the sudo Command - Remove 'Defaults
      timestamp_timeout' from /etc/sudoers.d/* files
    ansible.builtin.lineinfile:
      path: '{{ item.path }}'
      regexp: ^[\s]*Defaults\s.*\btimestamp_timeout[\s]*=.*
      state: absent
    with_items: '{{ sudoers_d_defaults_timestamp_timeout.files }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - '"sudo" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-010384
    - NIST-800-53-IA-11
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy
    - sudo_require_reauthentication

  - name: Require Re-Authentication When Using the sudo Command - Ensure timestamp_timeout
      has the appropriate value in /etc/sudoers
    ansible.builtin.lineinfile:
      path: /etc/sudoers
      regexp: ^[\s]*Defaults\s(.*)\btimestamp_timeout[\s]*=[\s]*[-]?\w+\b(.*)$
      line: Defaults \1timestamp_timeout={{ var_sudo_timestamp_timeout }}\2
      validate: /usr/sbin/visudo -cf %s
      backrefs: true
    register: edit_sudoers_timestamp_timeout_option
    when:
    - '"kernel" in ansible_facts.packages'
    - '"sudo" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-010384
    - NIST-800-53-IA-11
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy
    - sudo_require_reauthentication

  - name: Require Re-Authentication When Using the sudo Command - Enable timestamp_timeout
      option with correct value in /etc/sudoers
    ansible.builtin.lineinfile:
      path: /etc/sudoers
      line: Defaults timestamp_timeout={{ var_sudo_timestamp_timeout }}
      validate: /usr/sbin/visudo -cf %s
    when:
    - '"kernel" in ansible_facts.packages'
    - '"sudo" in ansible_facts.packages'
    - |
      edit_sudoers_timestamp_timeout_option is defined and not edit_sudoers_timestamp_timeout_option.changed
    tags:
    - DISA-STIG-RHEL-08-010384
    - NIST-800-53-IA-11
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy
    - sudo_require_reauthentication

  - name: Require Re-Authentication When Using the sudo Command - Remove timestamp_timeout
      wrong values in /etc/sudoers
    ansible.builtin.lineinfile:
      path: /etc/sudoers
      regexp: ^[\s]*Defaults\s.*\btimestamp_timeout[\s]*=[\s]*(?!{{ var_sudo_timestamp_timeout
        }}\b)[-]?\w+\b.*$
      state: absent
      validate: /usr/sbin/visudo -cf %s
    when:
    - '"kernel" in ansible_facts.packages'
    - '"sudo" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-010384
    - NIST-800-53-IA-11
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy
    - sudo_require_reauthentication

  - name: Disable Installation of Weak Dependencies in DNF - Disable weak dependencies
    community.general.ini_file:
      path: /etc/dnf/dnf.conf
      section: main
      option: install_weak_deps
      value: 0
      create: true
      state: present
    when: '"dnf" in ansible_facts.packages'
    tags:
    - disable_weak_deps
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Read permission of GPG key directory
    ansible.builtin.stat:
      path: /etc/pki/rpm-gpg/
    register: gpg_key_directory_permission
    check_mode: false
    tags:
    - CJIS-5.10.4.1
    - DISA-STIG-RHEL-08-010019
    - NIST-800-171-3.4.8
    - NIST-800-53-CM-5(3)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-SC-12
    - NIST-800-53-SC-12(3)
    - NIST-800-53-SI-7
    - PCI-DSS-Req-6.2
    - PCI-DSSv4-6.3
    - PCI-DSSv4-6.3.3
    - ensure_almalinux_gpgkey_installed
    - high_severity
    - medium_complexity
    - medium_disruption
    - no_reboot_needed
    - restrict_strategy

  - name: Read signatures in GPG key
    ansible.builtin.command: gpg --show-keys --with-fingerprint --with-colons "/etc/pki/rpm-gpg/RPM-GPG-KEY-AlmaLinux"
    changed_when: false
    register: gpg_fingerprints
    check_mode: false
    tags:
    - CJIS-5.10.4.1
    - DISA-STIG-RHEL-08-010019
    - NIST-800-171-3.4.8
    - NIST-800-53-CM-5(3)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-SC-12
    - NIST-800-53-SC-12(3)
    - NIST-800-53-SI-7
    - PCI-DSS-Req-6.2
    - PCI-DSSv4-6.3
    - PCI-DSSv4-6.3.3
    - ensure_almalinux_gpgkey_installed
    - high_severity
    - medium_complexity
    - medium_disruption
    - no_reboot_needed
    - restrict_strategy

  - name: Set Fact - Installed GPG Fingerprints
    ansible.builtin.set_fact:
      gpg_installed_fingerprints: |-
        {{ gpg_fingerprints.stdout | regex_findall('^pub.*
        (?:^fpr[:]*)([0-9A-Fa-f]*)', '\1') | list }}
    tags:
    - CJIS-5.10.4.1
    - DISA-STIG-RHEL-08-010019
    - NIST-800-171-3.4.8
    - NIST-800-53-CM-5(3)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-SC-12
    - NIST-800-53-SC-12(3)
    - NIST-800-53-SI-7
    - PCI-DSS-Req-6.2
    - PCI-DSSv4-6.3
    - PCI-DSSv4-6.3.3
    - ensure_almalinux_gpgkey_installed
    - high_severity
    - medium_complexity
    - medium_disruption
    - no_reboot_needed
    - restrict_strategy

  - name: Set Fact - Valid fingerprints
    ansible.builtin.set_fact:
      gpg_valid_fingerprints:
      - 5E9B8F5617B5066CE92057C3488FCF7C3ABB34F8
      - BC5EDDCADF502C077F1582882AE81E8ACED7258B
    tags:
    - CJIS-5.10.4.1
    - DISA-STIG-RHEL-08-010019
    - NIST-800-171-3.4.8
    - NIST-800-53-CM-5(3)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-SC-12
    - NIST-800-53-SC-12(3)
    - NIST-800-53-SI-7
    - PCI-DSS-Req-6.2
    - PCI-DSSv4-6.3
    - PCI-DSSv4-6.3.3
    - ensure_almalinux_gpgkey_installed
    - high_severity
    - medium_complexity
    - medium_disruption
    - no_reboot_needed
    - restrict_strategy

  - name: Import AlmaLinux GPG key
    ansible.builtin.rpm_key:
      state: present
      key: /etc/pki/rpm-gpg/RPM-GPG-KEY-AlmaLinux
    when:
    - gpg_key_directory_permission.stat.mode <= '0755'
    - (gpg_installed_fingerprints | difference(gpg_valid_fingerprints)) | length ==
      0
    - gpg_installed_fingerprints | length > 0
    - ansible_distribution == "AlmaLinux" and ansible_distribution_version == "8"
    tags:
    - CJIS-5.10.4.1
    - DISA-STIG-RHEL-08-010019
    - NIST-800-171-3.4.8
    - NIST-800-53-CM-5(3)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-SC-12
    - NIST-800-53-SC-12(3)
    - NIST-800-53-SI-7
    - PCI-DSS-Req-6.2
    - PCI-DSSv4-6.3
    - PCI-DSSv4-6.3.3
    - ensure_almalinux_gpgkey_installed
    - high_severity
    - medium_complexity
    - medium_disruption
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure GPG check is globally activated
    community.general.ini_file:
      dest: /etc/yum.conf
      section: main
      option: gpgcheck
      value: 1
      no_extra_spaces: true
      create: false
    when: '"yum" in ansible_facts.packages'
    tags:
    - CJIS-5.10.4.1
    - NIST-800-171-3.4.8
    - NIST-800-53-CM-11(a)
    - NIST-800-53-CM-11(b)
    - NIST-800-53-CM-5(3)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-SA-12
    - NIST-800-53-SA-12(10)
    - NIST-800-53-SC-12
    - NIST-800-53-SC-12(3)
    - NIST-800-53-SI-7
    - PCI-DSS-Req-6.2
    - PCI-DSSv4-6.3
    - PCI-DSSv4-6.3.3
    - configure_strategy
    - ensure_gpgcheck_globally_activated
    - high_severity
    - low_complexity
    - medium_disruption
    - no_reboot_needed

  - name: Grep for yum repo section names
    ansible.builtin.shell: |
      set -o pipefail
      grep -HEr '^\[.+\]' -r /etc/yum.repos.d/
    register: repo_grep_results
    failed_when: repo_grep_results.rc not in [0, 1]
    changed_when: false
    tags:
    - CJIS-5.10.4.1
    - NIST-800-171-3.4.8
    - NIST-800-53-CM-11(a)
    - NIST-800-53-CM-11(b)
    - NIST-800-53-CM-5(3)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-SA-12
    - NIST-800-53-SA-12(10)
    - NIST-800-53-SC-12
    - NIST-800-53-SC-12(3)
    - NIST-800-53-SI-7
    - PCI-DSS-Req-6.2
    - PCI-DSSv4-6.3
    - PCI-DSSv4-6.3.3
    - enable_strategy
    - ensure_gpgcheck_never_disabled
    - high_severity
    - low_complexity
    - medium_disruption
    - no_reboot_needed

  - name: Set gpgcheck=1 for each yum repo
    community.general.ini_file:
      path: '{{ item[0] }}'
      section: '{{ item[1] }}'
      option: gpgcheck
      value: '1'
      no_extra_spaces: true
    loop: '{{ repo_grep_results.stdout |regex_findall( ''(.+\.repo):\[(.+)\]\n?''
      ) if repo_grep_results is not skipped else [] }}'
    when: repo_grep_results is not skipped
    tags:
    - CJIS-5.10.4.1
    - NIST-800-171-3.4.8
    - NIST-800-53-CM-11(a)
    - NIST-800-53-CM-11(b)
    - NIST-800-53-CM-5(3)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-SA-12
    - NIST-800-53-SA-12(10)
    - NIST-800-53-SC-12
    - NIST-800-53-SC-12(3)
    - NIST-800-53-SI-7
    - PCI-DSS-Req-6.2
    - PCI-DSSv4-6.3
    - PCI-DSSv4-6.3.3
    - enable_strategy
    - ensure_gpgcheck_never_disabled
    - high_severity
    - low_complexity
    - medium_disruption
    - no_reboot_needed

  - name: Enable authselect - Check Current authselect Profile
    ansible.builtin.command:
      cmd: authselect current
    register: result_authselect_current
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-needed_rules
    - NIST-800-53-AC-3
    - PCI-DSSv4-8.3
    - PCI-DSSv4-8.3.4
    - configure_strategy
    - enable_authselect
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed

  - name: Enable authselect - Try to Select an authselect Profile
    ansible.builtin.command:
      cmd: authselect select "{{ var_authselect_profile }}"
    register: result_authselect_select
    changed_when: result_authselect_select.rc == 0
    failed_when: false
    when:
    - '"kernel" in ansible_facts.packages'
    - result_authselect_current.rc != 0
    tags:
    - DISA-STIG-needed_rules
    - NIST-800-53-AC-3
    - PCI-DSSv4-8.3
    - PCI-DSSv4-8.3.4
    - configure_strategy
    - enable_authselect
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed

  - name: Enable authselect - Verify If pam Has Been Altered
    ansible.builtin.command:
      cmd: rpm -qV pam
    register: result_altered_authselect
    changed_when: false
    failed_when: false
    when:
    - '"kernel" in ansible_facts.packages'
    - result_authselect_select is not skipped
    - result_authselect_select.rc != 0
    tags:
    - DISA-STIG-needed_rules
    - NIST-800-53-AC-3
    - PCI-DSSv4-8.3
    - PCI-DSSv4-8.3.4
    - configure_strategy
    - enable_authselect
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed

  - name: Enable authselect - Informative Message Based on authselect Integrity Check
    ansible.builtin.assert:
      that:
      - result_authselect_current.rc == 0 or result_altered_authselect is skipped
        or result_altered_authselect.rc == 0
      fail_msg:
      - authselect is not used but files from the 'pam' package have been altered,
        so the authselect configuration won't be forced.
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-needed_rules
    - NIST-800-53-AC-3
    - PCI-DSSv4-8.3
    - PCI-DSSv4-8.3.4
    - configure_strategy
    - enable_authselect
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed

  - name: Enable authselect - Force authselect Profile Selection
    ansible.builtin.command:
      cmd: authselect select --force "{{ var_authselect_profile }}"
    when:
    - '"kernel" in ansible_facts.packages'
    - result_authselect_current.rc != 0
    - result_authselect_select.rc != 0
    - result_altered_authselect.rc == 0
    tags:
    - DISA-STIG-needed_rules
    - NIST-800-53-AC-3
    - PCI-DSSv4-8.3
    - PCI-DSSv4-8.3.4
    - configure_strategy
    - enable_authselect
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure Local Login Warning Banner Is Configured Properly - Copy using inline
      content
    ansible.builtin.copy:
      content: '{{ cis_banner_text }}'
      dest: /etc/issue
    when: '"kernel" in ansible_facts.packages'
    tags:
    - banner_etc_issue_cis
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure Remote Login Warning Banner Is Configured Properly - Copy using inline
      content
    ansible.builtin.copy:
      content: '{{ cis_banner_text }}'
      dest: /etc/issue.net
    when: '"kernel" in ansible_facts.packages'
    tags:
    - banner_etc_issue_net_cis
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure Message Of The Day Is Configured Properly - Copy using inline content
    ansible.builtin.copy:
      content: '{{ cis_banner_text }}'
      dest: /etc/motd
    when: '"kernel" in ansible_facts.packages'
    tags:
    - banner_etc_motd_cis
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Set the file_groupowner_etc_issue_newgroup variable if represented by gid
    ansible.builtin.set_fact:
      file_groupowner_etc_issue_newgroup: '0'
    tags:
    - configure_strategy
    - file_groupowner_etc_issue
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /etc/issue
    ansible.builtin.stat:
      path: /etc/issue
    register: file_exists
    tags:
    - configure_strategy
    - file_groupowner_etc_issue
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure group owner on /etc/issue
    ansible.builtin.file:
      path: /etc/issue
      follow: false
      group: '{{ file_groupowner_etc_issue_newgroup }}'
    when: file_exists.stat is defined and file_exists.stat.exists
    tags:
    - configure_strategy
    - file_groupowner_etc_issue
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set the file_groupowner_etc_issue_net_newgroup variable if represented by
      gid
    ansible.builtin.set_fact:
      file_groupowner_etc_issue_net_newgroup: '0'
    tags:
    - PCI-DSSv4-1.2
    - PCI-DSSv4-1.2.8
    - configure_strategy
    - file_groupowner_etc_issue_net
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /etc/issue.net
    ansible.builtin.stat:
      path: /etc/issue.net
    register: file_exists
    tags:
    - PCI-DSSv4-1.2
    - PCI-DSSv4-1.2.8
    - configure_strategy
    - file_groupowner_etc_issue_net
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure group owner on /etc/issue.net
    ansible.builtin.file:
      path: /etc/issue.net
      follow: false
      group: '{{ file_groupowner_etc_issue_net_newgroup }}'
    when: file_exists.stat is defined and file_exists.stat.exists
    tags:
    - PCI-DSSv4-1.2
    - PCI-DSSv4-1.2.8
    - configure_strategy
    - file_groupowner_etc_issue_net
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set the file_groupowner_etc_motd_newgroup variable if represented by gid
    ansible.builtin.set_fact:
      file_groupowner_etc_motd_newgroup: '0'
    tags:
    - configure_strategy
    - file_groupowner_etc_motd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /etc/motd
    ansible.builtin.stat:
      path: /etc/motd
    register: file_exists
    tags:
    - configure_strategy
    - file_groupowner_etc_motd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure group owner on /etc/motd
    ansible.builtin.file:
      path: /etc/motd
      follow: false
      group: '{{ file_groupowner_etc_motd_newgroup }}'
    when: file_exists.stat is defined and file_exists.stat.exists
    tags:
    - configure_strategy
    - file_groupowner_etc_motd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set the file_owner_etc_issue_newown variable if represented by uid
    ansible.builtin.set_fact:
      file_owner_etc_issue_newown: '0'
    tags:
    - configure_strategy
    - file_owner_etc_issue
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /etc/issue
    ansible.builtin.stat:
      path: /etc/issue
    register: file_exists
    tags:
    - configure_strategy
    - file_owner_etc_issue
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure owner on /etc/issue
    ansible.builtin.file:
      path: /etc/issue
      follow: false
      owner: '{{ file_owner_etc_issue_newown }}'
    when: file_exists.stat is defined and file_exists.stat.exists
    tags:
    - configure_strategy
    - file_owner_etc_issue
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set the file_owner_etc_issue_net_newown variable if represented by uid
    ansible.builtin.set_fact:
      file_owner_etc_issue_net_newown: '0'
    tags:
    - PCI-DSSv4-1.2
    - PCI-DSSv4-1.2.8
    - configure_strategy
    - file_owner_etc_issue_net
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /etc/issue.net
    ansible.builtin.stat:
      path: /etc/issue.net
    register: file_exists
    tags:
    - PCI-DSSv4-1.2
    - PCI-DSSv4-1.2.8
    - configure_strategy
    - file_owner_etc_issue_net
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure owner on /etc/issue.net
    ansible.builtin.file:
      path: /etc/issue.net
      follow: false
      owner: '{{ file_owner_etc_issue_net_newown }}'
    when: file_exists.stat is defined and file_exists.stat.exists
    tags:
    - PCI-DSSv4-1.2
    - PCI-DSSv4-1.2.8
    - configure_strategy
    - file_owner_etc_issue_net
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set the file_owner_etc_motd_newown variable if represented by uid
    ansible.builtin.set_fact:
      file_owner_etc_motd_newown: '0'
    tags:
    - configure_strategy
    - file_owner_etc_motd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /etc/motd
    ansible.builtin.stat:
      path: /etc/motd
    register: file_exists
    tags:
    - configure_strategy
    - file_owner_etc_motd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure owner on /etc/motd
    ansible.builtin.file:
      path: /etc/motd
      follow: false
      owner: '{{ file_owner_etc_motd_newown }}'
    when: file_exists.stat is defined and file_exists.stat.exists
    tags:
    - configure_strategy
    - file_owner_etc_motd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /etc/issue
    ansible.builtin.stat:
      path: /etc/issue
    register: file_exists
    tags:
    - configure_strategy
    - file_permissions_etc_issue
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure permission u-xs,g-xws,o-xwt on /etc/issue
    ansible.builtin.file:
      path: /etc/issue
      mode: u-xs,g-xws,o-xwt
    when: file_exists.stat is defined and file_exists.stat.exists
    tags:
    - configure_strategy
    - file_permissions_etc_issue
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /etc/issue.net
    ansible.builtin.stat:
      path: /etc/issue.net
    register: file_exists
    tags:
    - PCI-DSSv4-1.2
    - PCI-DSSv4-1.2.8
    - configure_strategy
    - file_permissions_etc_issue_net
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure permission u-xs,g-xws,o-xwt on /etc/issue.net
    ansible.builtin.file:
      path: /etc/issue.net
      mode: u-xs,g-xws,o-xwt
    when: file_exists.stat is defined and file_exists.stat.exists
    tags:
    - PCI-DSSv4-1.2
    - PCI-DSSv4-1.2.8
    - configure_strategy
    - file_permissions_etc_issue_net
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /etc/motd
    ansible.builtin.stat:
      path: /etc/motd
    register: file_exists
    tags:
    - configure_strategy
    - file_permissions_etc_motd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure permission u-xs,g-xws,o-xwt on /etc/motd
    ansible.builtin.file:
      path: /etc/motd
      mode: u-xs,g-xws,o-xwt
    when: file_exists.stat is defined and file_exists.stat.exists
    tags:
    - configure_strategy
    - file_permissions_etc_motd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Enable GNOME3 Login Warning Banner
    community.general.ini_file:
      dest: /etc/dconf/db/gdm.d/00-security-settings
      section: org/gnome/login-screen
      option: banner-message-enable
      value: 'true'
      create: true
      no_extra_spaces: true
    register: result_ini
    when: '"gdm" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-010049
    - NIST-800-171-3.1.9
    - NIST-800-53-AC-8(a)
    - NIST-800-53-AC-8(b)
    - NIST-800-53-AC-8(c)
    - dconf_gnome_banner_enabled
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - unknown_strategy

  - name: Prevent user modification of GNOME banner-message-enabled
    ansible.builtin.lineinfile:
      path: /etc/dconf/db/gdm.d/locks/00-security-settings-lock
      regexp: ^/org/gnome/login-screen/banner-message-enable$
      line: /org/gnome/login-screen/banner-message-enable
      create: true
    register: result_lineinfile
    when: '"gdm" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-010049
    - NIST-800-171-3.1.9
    - NIST-800-53-AC-8(a)
    - NIST-800-53-AC-8(b)
    - NIST-800-53-AC-8(c)
    - dconf_gnome_banner_enabled
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - unknown_strategy

  - name: Dconf Update
    ansible.builtin.command: dconf update
    when:
    - '"gdm" in ansible_facts.packages'
    - result_ini is changed or result_lineinfile is changed
    tags:
    - DISA-STIG-RHEL-08-010049
    - NIST-800-171-3.1.9
    - NIST-800-53-AC-8(a)
    - NIST-800-53-AC-8(b)
    - NIST-800-53-AC-8(c)
    - dconf_gnome_banner_enabled
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - unknown_strategy

  - name: Set the GNOME3 Login Warning Banner Text
    ansible.builtin.file:
      path: /etc/dconf/db/{{ item }}
      owner: root
      group: root
      mode: 493
      state: directory
    with_items:
    - gdm.d
    - gdm.d/locks
    when: '"gdm" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-010050
    - NIST-800-171-3.1.9
    - NIST-800-53-AC-8(a)
    - NIST-800-53-AC-8(c)
    - dconf_gnome_login_banner_text
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - unknown_strategy

  - name: Set the GNOME3 Login Warning Banner Text
    ansible.builtin.file:
      path: /etc/dconf/db/gdm.d/{{ item }}
      owner: root
      group: root
      mode: 420
      state: touch
    with_items:
    - 00-security-settings
    - locks/00-security-settings-lock
    when: '"gdm" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-010050
    - NIST-800-171-3.1.9
    - NIST-800-53-AC-8(a)
    - NIST-800-53-AC-8(c)
    - dconf_gnome_login_banner_text
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - unknown_strategy

  - name: Set the GNOME3 Login Warning Banner Text
    community.general.ini_file:
      dest: /etc/dconf/db/gdm.d/00-security-settings
      section: org/gnome/login-screen
      option: banner-message-text
      value: '''{{ dconf_login_banner_contents }}'''
      create: true
      no_extra_spaces: true
    register: result_ini
    when: '"gdm" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-010050
    - NIST-800-171-3.1.9
    - NIST-800-53-AC-8(a)
    - NIST-800-53-AC-8(c)
    - dconf_gnome_login_banner_text
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - unknown_strategy

  - name: Prevent user modification of the GNOME3 Login Warning Banner Text
    ansible.builtin.lineinfile:
      path: /etc/dconf/db/gdm.d/locks/00-security-settings-lock
      regexp: ^/org/gnome/login-screen/banner-message-text$
      line: /org/gnome/login-screen/banner-message-text
      create: true
      state: present
    register: result_lineinfile
    when: '"gdm" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-010050
    - NIST-800-171-3.1.9
    - NIST-800-53-AC-8(a)
    - NIST-800-53-AC-8(c)
    - dconf_gnome_login_banner_text
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - unknown_strategy

  - name: Dconf Update
    ansible.builtin.command: dconf update
    when:
    - '"gdm" in ansible_facts.packages'
    - result_ini is changed or result_lineinfile is changed
    tags:
    - DISA-STIG-RHEL-08-010050
    - NIST-800-171-3.1.9
    - NIST-800-53-AC-8(a)
    - NIST-800-53-AC-8(c)
    - dconf_gnome_login_banner_text
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - unknown_strategy

  - name: Ensure Active Authselect Profile Includes PAM Modules - Check integrity
      of authselect current profile
    ansible.builtin.command:
      cmd: authselect check
    register: result_authselect_check_cmd
    changed_when: false
    check_mode: false
    failed_when: false
    when: '"pam" in ansible_facts.packages'
    tags:
    - accounts_password_pam_modules_in_authselect_profile
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure Active Authselect Profile Includes PAM Modules - Informative message
      based on the authselect integrity check result
    ansible.builtin.assert:
      that:
      - ansible_check_mode or result_authselect_check_cmd.rc == 0
      fail_msg:
      - authselect integrity check failed. Remediation aborted!
      - This remediation could not be applied because an authselect profile was not
        selected or the selected profile is not intact.
      - It is not recommended to manually edit the PAM files when authselect tool
        is available.
      - In cases where the default authselect profile does not cover a specific demand,
        a custom authselect profile is recommended.
      success_msg:
      - authselect integrity check passed
    when: '"pam" in ansible_facts.packages'
    tags:
    - accounts_password_pam_modules_in_authselect_profile
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure Active Authselect Profile Includes PAM Modules - Get authselect current
      profile
    ansible.builtin.shell:
      cmd: authselect current -r | awk '{ print $1 }'
    register: result_authselect_profile
    changed_when: false
    when:
    - '"pam" in ansible_facts.packages'
    - result_authselect_check_cmd is success
    tags:
    - accounts_password_pam_modules_in_authselect_profile
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure Active Authselect Profile Includes PAM Modules - Define the current
      authselect profile as a local fact
    ansible.builtin.set_fact:
      authselect_current_profile: '{{ result_authselect_profile.stdout }}'
      authselect_custom_profile: '{{ result_authselect_profile.stdout }}'
    when:
    - '"pam" in ansible_facts.packages'
    - result_authselect_profile is not skipped
    - result_authselect_profile.stdout is match("custom/")
    tags:
    - accounts_password_pam_modules_in_authselect_profile
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure Active Authselect Profile Includes PAM Modules - Define the new authselect
      custom profile as a local fact
    ansible.builtin.set_fact:
      authselect_current_profile: '{{ result_authselect_profile.stdout }}'
      authselect_custom_profile: custom/hardening
    when:
    - '"pam" in ansible_facts.packages'
    - result_authselect_profile is not skipped
    - result_authselect_profile.stdout is not match("custom/")
    tags:
    - accounts_password_pam_modules_in_authselect_profile
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure Active Authselect Profile Includes PAM Modules - Get authselect current
      features to also enable them in the custom profile
    ansible.builtin.shell:
      cmd: authselect current | tail -n+3 | awk '{ print $2 }'
    register: result_authselect_features
    changed_when: false
    check_mode: false
    when:
    - '"pam" in ansible_facts.packages'
    - result_authselect_profile is not skipped
    - authselect_current_profile is not match("custom/")
    tags:
    - accounts_password_pam_modules_in_authselect_profile
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure Active Authselect Profile Includes PAM Modules - Check if any custom
      profile with the same name was already created
    ansible.builtin.stat:
      path: /etc/authselect/{{ authselect_custom_profile }}
    register: result_authselect_custom_profile_present
    changed_when: false
    when:
    - '"pam" in ansible_facts.packages'
    - result_authselect_profile is not skipped
    - authselect_current_profile is not match("custom/")
    tags:
    - accounts_password_pam_modules_in_authselect_profile
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure Active Authselect Profile Includes PAM Modules - Create an authselect
      custom profile based on the current profile
    ansible.builtin.command:
      cmd: authselect create-profile hardening -b {{ authselect_current_profile }}
    when:
    - '"pam" in ansible_facts.packages'
    - result_authselect_profile is not skipped
    - result_authselect_check_cmd is success
    - authselect_current_profile is not match("^(custom/|local)")
    - not result_authselect_custom_profile_present.stat.exists
    tags:
    - accounts_password_pam_modules_in_authselect_profile
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure Active Authselect Profile Includes PAM Modules - Create an authselect
      custom profile based on sssd profile
    ansible.builtin.command:
      cmd: authselect create-profile hardening -b sssd
    when:
    - '"pam" in ansible_facts.packages'
    - result_authselect_profile is not skipped
    - result_authselect_check_cmd is success
    - authselect_current_profile is match("local")
    - not result_authselect_custom_profile_present.stat.exists
    tags:
    - accounts_password_pam_modules_in_authselect_profile
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure Active Authselect Profile Includes PAM Modules - Ensure authselect
      changes are applied
    ansible.builtin.command:
      cmd: authselect apply-changes -b --backup=before-hardening-custom-profile
    when:
    - '"pam" in ansible_facts.packages'
    - result_authselect_check_cmd is success
    - result_authselect_profile is not skipped
    - authselect_current_profile is not match("custom/")
    - authselect_custom_profile is not match(authselect_current_profile)
    tags:
    - accounts_password_pam_modules_in_authselect_profile
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure Active Authselect Profile Includes PAM Modules - Ensure the authselect
      custom profile is selected
    ansible.builtin.command:
      cmd: authselect select {{ authselect_custom_profile }}
    register: result_pam_authselect_select_profile
    when:
    - '"pam" in ansible_facts.packages'
    - result_authselect_check_cmd is success
    - result_authselect_profile is not skipped
    - authselect_current_profile is not match("custom/")
    - authselect_custom_profile is not match(authselect_current_profile)
    tags:
    - accounts_password_pam_modules_in_authselect_profile
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure Active Authselect Profile Includes PAM Modules - Restore the authselect
      features in the custom profile
    ansible.builtin.command:
      cmd: authselect enable-feature {{ item }}
    loop: '{{ result_authselect_features.stdout_lines }}'
    register: result_pam_authselect_restore_features
    when:
    - '"pam" in ansible_facts.packages'
    - result_authselect_profile is not skipped
    - result_authselect_features is not skipped
    - result_pam_authselect_select_profile is not skipped
    tags:
    - accounts_password_pam_modules_in_authselect_profile
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure Active Authselect Profile Includes PAM Modules - Ensure authselect
      changes are applied
    ansible.builtin.command:
      cmd: authselect apply-changes -b --backup=after-hardening-custom-profile
    when:
    - '"pam" in ansible_facts.packages'
    - result_authselect_check_cmd is success
    - result_authselect_profile is not skipped
    - result_pam_authselect_restore_features is not skipped
    tags:
    - accounts_password_pam_modules_in_authselect_profile
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure Active Authselect Profile Includes PAM Modules - Get authselect current
      profile
    ansible.builtin.command: head -1 /etc/authselect/authselect.conf
    register: result_authselect_profile_name
    changed_when: false
    when:
    - '"pam" in ansible_facts.packages'
    - result_authselect_check_cmd is success
    tags:
    - accounts_password_pam_modules_in_authselect_profile
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure Active Authselect Profile Includes PAM Modules - Determine PAM profile
      path
    ansible.builtin.set_fact:
      pam_profile_path: '{%- if result_authselect_profile_name.stdout is match(''^custom/'')
        -%} /etc/authselect/{{ result_authselect_profile_name.stdout }} {%- else -%}
        /usr/share/authselect/default/{{ result_authselect_profile_name.stdout }}
        {%- endif %}'
    when:
    - '"pam" in ansible_facts.packages'
    - result_authselect_check_cmd is success
    - result_authselect_profile_name is not skipped
    tags:
    - accounts_password_pam_modules_in_authselect_profile
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure Active Authselect Profile Includes PAM Modules - Ensure PAM modules
      are present in system-auth and password-auth
    block:

    - name: Ensure Active Authselect Profile Includes PAM Modules - Check if {{ item
        }} file exists
      ansible.builtin.stat:
        path: '{{ pam_profile_path }}/{{ item }}'
      register: pam_file_stat
      loop:
      - system-auth
      - password-auth
      when:
      - pam_profile_path is defined

    - name: Ensure Active Authselect Profile Includes PAM Modules - Set list of PAM
        files to process
      ansible.builtin.set_fact:
        pam_files_to_process: '{{ pam_file_stat.results | default([]) | selectattr(''stat.exists'',
          ''equalto'', true) | map(attribute=''item'') | list }}'

    - name: Ensure Active Authselect Profile Includes PAM Modules - Check if pam_faillock.so
        exists in auth section of {{ item }}
      ansible.builtin.lineinfile:
        path: '{{ pam_profile_path }}/{{ item }}'
        regexp: ^\s*auth\s+\S+\s+pam_faillock\.so\s+preauth
        state: absent
      check_mode: true
      changed_when: false
      register: pam_faillock_auth_check_result
      loop: '{{ pam_files_to_process | default([]) }}'
      when:
      - item is defined
      - pam_profile_path is defined

    - name: Ensure Active Authselect Profile Includes PAM Modules - Add pam_faillock.so
        preauth entry in auth section of {{ item }}
      ansible.builtin.lineinfile:
        path: '{{ pam_profile_path }}/{{ item }}'
        regexp: ^\s*auth\s+\S+\s+pam_faillock\.so\s+preauth
        insertbefore: ^auth
        line: auth     required    pam_faillock.so preauth
        state: present
      register: pam_faillock_auth_add_result
      loop: '{{ pam_files_to_process | default([]) }}'
      when:
      - item is defined
      - pam_profile_path is defined
      - pam_faillock_auth_check_result.results | selectattr('item', 'equalto', item)
        | map(attribute='found') | first | default(1) == 0

    - name: Ensure Active Authselect Profile Includes PAM Modules - Check if pam_faillock.so
        exists in account section of {{ item }}
      ansible.builtin.lineinfile:
        path: '{{ pam_profile_path }}/{{ item }}'
        regexp: ^\s*account\s+\S+\s+pam_faillock\.so
        state: absent
      check_mode: true
      changed_when: false
      register: pam_faillock_account_check_result
      loop: '{{ pam_files_to_process | default([]) }}'
      when:
      - item is defined
      - pam_profile_path is defined

    - name: Ensure Active Authselect Profile Includes PAM Modules - Add pam_faillock.so
        entry in account section of {{ item }}
      ansible.builtin.lineinfile:
        path: '{{ pam_profile_path }}/{{ item }}'
        regexp: ^\s*account\s+\S+\s+pam_faillock\.so
        insertafter: ^account
        line: account     required    pam_faillock.so
        state: present
      register: pam_faillock_account_add_result
      loop: '{{ pam_files_to_process | default([]) }}'
      when:
      - item is defined
      - pam_profile_path is defined
      - pam_faillock_account_check_result.results | selectattr('item', 'equalto',
        item) | map(attribute='found') | first | default(1) == 0

    - name: Ensure Active Authselect Profile Includes PAM Modules - Check if pam_pwquality.so
        exists in {{ item }}
      ansible.builtin.lineinfile:
        path: '{{ pam_profile_path }}/{{ item }}'
        regexp: ^\s*password\s+\S+\s+pam_pwquality\.so
        state: absent
      check_mode: true
      changed_when: false
      register: pam_pwquality_check_result
      loop: '{{ pam_files_to_process | default([]) }}'
      when:
      - item is defined
      - pam_profile_path is defined

    - name: Ensure Active Authselect Profile Includes PAM Modules - Add pam_pwquality.so
        entry in password section of {{ item }}
      ansible.builtin.lineinfile:
        path: '{{ pam_profile_path }}/{{ item }}'
        regexp: ^\s*password\s+\S+\s+pam_pwquality\.so
        insertbefore: ^password
        line: password     requisite    pam_pwquality.so
        state: present
      register: pam_pwquality_add_result
      loop: '{{ pam_files_to_process | default([]) }}'
      when:
      - item is defined
      - pam_profile_path is defined
      - pam_pwquality_check_result.results | selectattr('item', 'equalto', item) |
        map(attribute='found') | first | default(1) == 0

    - name: Ensure Active Authselect Profile Includes PAM Modules - Check if pam_pwhistory.so
        exists in {{ item }}
      ansible.builtin.lineinfile:
        path: '{{ pam_profile_path }}/{{ item }}'
        regexp: ^\s*password\s+\S+\s+pam_pwhistory\.so
        state: absent
      check_mode: true
      changed_when: false
      register: pam_pwhistory_check_result
      loop: '{{ pam_files_to_process | default([]) }}'
      when:
      - item is defined
      - pam_profile_path is defined

    - name: Ensure Active Authselect Profile Includes PAM Modules - Add pam_pwhistory.so
        entry after pam_pwquality in {{ item }}
      ansible.builtin.lineinfile:
        path: '{{ pam_profile_path }}/{{ item }}'
        regexp: ^\s*password\s+\S+\s+pam_pwhistory\.so
        insertafter: ^.*pam_pwquality\.so.*
        line: password     requisite    pam_pwhistory.so
        state: present
      register: pam_pwhistory_add_result
      loop: '{{ pam_files_to_process | default([]) }}'
      when:
      - item is defined
      - pam_profile_path is defined
      - pam_pwhistory_check_result.results | selectattr('item', 'equalto', item) |
        map(attribute='found') | first | default(1) == 0
      - pam_pwquality_check_result.results | selectattr('item', 'equalto', item) |
        map(attribute='found') | first | default(0) > 0

    - name: Ensure Active Authselect Profile Includes PAM Modules - Add pam_pwhistory.so
        entry at beginning of password section in {{ item }}
      ansible.builtin.lineinfile:
        path: '{{ pam_profile_path }}/{{ item }}'
        regexp: ^\s*password\s+\S+\s+pam_pwhistory\.so
        insertbefore: ^password
        line: password     requisite    pam_pwhistory.so
        state: present
      register: pam_pwhistory_add_result
      loop: '{{ pam_files_to_process | default([]) }}'
      when:
      - item is defined
      - pam_profile_path is defined
      - pam_pwhistory_check_result.results | selectattr('item', 'equalto', item) |
        map(attribute='found') | first | default(1) == 0
      - pam_pwquality_check_result.results | selectattr('item', 'equalto', item) |
        map(attribute='found') | first | default(1) == 0

    - name: Ensure Active Authselect Profile Includes PAM Modules - Check if pam_unix.so
        exists in password section of {{ item }}
      ansible.builtin.lineinfile:
        path: '{{ pam_profile_path }}/{{ item }}'
        regexp: ^\s*password\s+\S+\s+pam_unix\.so
        state: absent
      check_mode: true
      changed_when: false
      register: pam_unix_check_result
      loop: '{{ pam_files_to_process | default([]) }}'
      when:
      - item is defined
      - pam_profile_path is defined

    - name: Ensure Active Authselect Profile Includes PAM Modules - Add pam_unix.so
        entry after pam_pwhistory in {{ item }}
      ansible.builtin.lineinfile:
        path: '{{ pam_profile_path }}/{{ item }}'
        regexp: ^\s*password\s+\S+\s+pam_unix\.so
        insertafter: ^.*pam_pwhistory\.so.*
        line: password     sufficient    pam_unix.so
        state: present
      register: pam_unix_add_result
      loop: '{{ pam_files_to_process | default([]) }}'
      when:
      - item is defined
      - pam_profile_path is defined
      - pam_unix_check_result.results | selectattr('item', 'equalto', item) | map(attribute='found')
        | first | default(1) == 0
      - pam_pwhistory_check_result.results | selectattr('item', 'equalto', item) |
        map(attribute='found') | first | default(0) > 0

    - name: Ensure Active Authselect Profile Includes PAM Modules - Add pam_unix.so
        entry at end of password section in {{ item }}
      ansible.builtin.lineinfile:
        path: '{{ pam_profile_path }}/{{ item }}'
        regexp: ^\s*password\s+\S+\s+pam_unix\.so
        insertafter: ^password.*
        line: password     sufficient    pam_unix.so
        state: present
      register: pam_unix_add_result
      loop: '{{ pam_files_to_process | default([]) }}'
      when:
      - item is defined
      - pam_profile_path is defined
      - pam_unix_check_result.results | selectattr('item', 'equalto', item) | map(attribute='found')
        | first | default(1) == 0
      - pam_pwhistory_check_result.results | selectattr('item', 'equalto', item) |
        map(attribute='found') | first | default(1) == 0

    - name: Ensure Active Authselect Profile Includes PAM Modules - Store results
        for {{ item }}
      ansible.builtin.set_fact:
        pam_changes_{{ item | replace('-', '_') }}: |-
          {{ ((pam_faillock_auth_add_result.results | selectattr('item', 'equalto', item) | map(attribute='changed') | first | default(false)) or
             (pam_faillock_account_add_result.results | selectattr('item', 'equalto', item) | map(attribute='changed') | first | default(false)) or
             (pam_pwquality_add_result.results | selectattr('item', 'equalto', item) | map(attribute='changed') | first | default(false)) or
             (pam_pwhistory_add_result.results | selectattr('item', 'equalto', item) | map(attribute='changed') | first | default(false)) or
             (pam_unix_add_result.results | selectattr('item', 'equalto', item) | map(attribute='changed') | first | default(false))) }}
      loop: '{{ pam_files_to_process | default([]) }}'
      when:
      - item is defined
      - pam_profile_path is defined
    when:
    - '"pam" in ansible_facts.packages'
    - result_authselect_check_cmd is success
    - pam_profile_path is defined
    tags:
    - accounts_password_pam_modules_in_authselect_profile
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure Active Authselect Profile Includes PAM Modules - Ensure authselect
      changes are applied
    ansible.builtin.command:
      cmd: authselect apply-changes -b
    when:
    - '"pam" in ansible_facts.packages'
    - result_authselect_check_cmd is success
    - (pam_changes_system_auth is defined and pam_changes_system_auth) or (pam_changes_password_auth
      is defined and pam_changes_password_auth)
    tags:
    - accounts_password_pam_modules_in_authselect_profile
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/password-auth
      File. - Get current authselect profile
    ansible.builtin.command:
      cmd: authselect current --raw
    register: authselect_current_profile
    changed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-020026
    - NIST-800-53-AC-7 (a)
    - account_password_pam_faillock_password_auth
    - enable_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/password-auth
      File. - Force reselect authselect profile
    ansible.builtin.command:
      cmd: authselect select {{ authselect_current_profile.stdout }} --force
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-020026
    - NIST-800-53-AC-7 (a)
    - account_password_pam_faillock_password_auth
    - enable_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/password-auth
      File. - Check if system relies on authselect tool
    ansible.builtin.stat:
      path: /usr/bin/authselect
    register: result_authselect_present
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-020026
    - NIST-800-53-AC-7 (a)
    - account_password_pam_faillock_password_auth
    - enable_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/password-auth
      File. - Remediation where authselect tool is present
    block:

    - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/password-auth
        File. - Check integrity of authselect current profile
      ansible.builtin.command:
        cmd: authselect check
      register: result_authselect_check_cmd
      changed_when: false
      check_mode: false
      failed_when: false

    - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/password-auth
        File. - Informative message based on the authselect integrity check result
      ansible.builtin.assert:
        that:
        - ansible_check_mode or result_authselect_check_cmd.rc == 0
        fail_msg:
        - authselect integrity check failed. Remediation aborted!
        - This remediation could not be applied because an authselect profile was
          not selected or the selected profile is not intact.
        - It is not recommended to manually edit the PAM files when authselect tool
          is available.
        - In cases where the default authselect profile does not cover a specific
          demand, a custom authselect profile is recommended.
        success_msg:
        - authselect integrity check passed

    - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/password-auth
        File. - Get authselect current features
      ansible.builtin.shell:
        cmd: authselect current | tail -n+3 | awk '{ print $2 }'
      register: result_authselect_features
      changed_when: false
      check_mode: false
      when:
      - result_authselect_check_cmd is success

    - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/password-auth
        File. - Ensure "with-faillock" feature is enabled using authselect tool
      ansible.builtin.command:
        cmd: authselect enable-feature with-faillock
      register: result_authselect_enable_feature_cmd
      when:
      - result_authselect_check_cmd is success
      - result_authselect_features.stdout is not search("with-faillock")

    - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/password-auth
        File. - Ensure authselect changes are applied
      ansible.builtin.command:
        cmd: authselect apply-changes -b
      when:
      - result_authselect_enable_feature_cmd is not skipped
      - result_authselect_enable_feature_cmd is success
    when:
    - '"kernel" in ansible_facts.packages'
    - result_authselect_present.stat.exists
    tags:
    - DISA-STIG-RHEL-08-020026
    - NIST-800-53-AC-7 (a)
    - account_password_pam_faillock_password_auth
    - enable_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/password-auth
      File. - Remediation where authselect tool is not present
    block:

    - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/password-auth
        File. - Check if pam_faillock.so is already enabled
      ansible.builtin.lineinfile:
        path: /etc/pam.d/system-auth
        regexp: .*auth.*pam_faillock\.so (preauth|authfail)
        state: absent
      check_mode: true
      changed_when: false
      register: result_pam_faillock_is_enabled

    - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/password-auth
        File. - Enable pam_faillock.so preauth editing PAM files
      ansible.builtin.lineinfile:
        path: '{{ item }}'
        line: auth        required      pam_faillock.so preauth
        insertbefore: ^auth.*sufficient.*pam_unix\.so.*
        state: present
      loop:
      - /etc/pam.d/system-auth
      - /etc/pam.d/password-auth
      when:
      - result_pam_faillock_is_enabled.found == 0

    - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/password-auth
        File. - Enable pam_faillock.so authfail editing PAM files
      ansible.builtin.lineinfile:
        path: '{{ item }}'
        line: auth        required      pam_faillock.so authfail
        insertbefore: ^auth.*required.*pam_deny\.so.*
        state: present
      loop:
      - /etc/pam.d/system-auth
      - /etc/pam.d/password-auth
      when:
      - result_pam_faillock_is_enabled.found == 0

    - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/password-auth
        File. - Enable pam_faillock.so account section editing PAM files
      ansible.builtin.lineinfile:
        path: '{{ item }}'
        line: account     required      pam_faillock.so
        insertbefore: ^account.*required.*pam_unix\.so.*
        state: present
      loop:
      - /etc/pam.d/system-auth
      - /etc/pam.d/password-auth
      when:
      - result_pam_faillock_is_enabled.found == 0
    when:
    - '"kernel" in ansible_facts.packages'
    - not result_authselect_present.stat.exists
    tags:
    - DISA-STIG-RHEL-08-020026
    - NIST-800-53-AC-7 (a)
    - account_password_pam_faillock_password_auth
    - enable_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/system-auth
      File. - Check if system relies on authselect tool
    ansible.builtin.stat:
      path: /usr/bin/authselect
    register: result_authselect_present
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-020025
    - NIST-800-53-AC-7 (a)
    - account_password_pam_faillock_system_auth
    - enable_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/system-auth
      File. - Remediation where authselect tool is present
    block:

    - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/system-auth
        File. - Check integrity of authselect current profile
      ansible.builtin.command:
        cmd: authselect check
      register: result_authselect_check_cmd
      changed_when: false
      check_mode: false
      failed_when: false

    - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/system-auth
        File. - Informative message based on the authselect integrity check result
      ansible.builtin.assert:
        that:
        - ansible_check_mode or result_authselect_check_cmd.rc == 0
        fail_msg:
        - authselect integrity check failed. Remediation aborted!
        - This remediation could not be applied because an authselect profile was
          not selected or the selected profile is not intact.
        - It is not recommended to manually edit the PAM files when authselect tool
          is available.
        - In cases where the default authselect profile does not cover a specific
          demand, a custom authselect profile is recommended.
        success_msg:
        - authselect integrity check passed

    - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/system-auth
        File. - Get authselect current features
      ansible.builtin.shell:
        cmd: authselect current | tail -n+3 | awk '{ print $2 }'
      register: result_authselect_features
      changed_when: false
      check_mode: false
      when:
      - result_authselect_check_cmd is success

    - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/system-auth
        File. - Ensure "with-faillock" feature is enabled using authselect tool
      ansible.builtin.command:
        cmd: authselect enable-feature with-faillock
      register: result_authselect_enable_feature_cmd
      when:
      - result_authselect_check_cmd is success
      - result_authselect_features.stdout is not search("with-faillock")

    - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/system-auth
        File. - Ensure authselect changes are applied
      ansible.builtin.command:
        cmd: authselect apply-changes -b
      when:
      - result_authselect_enable_feature_cmd is not skipped
      - result_authselect_enable_feature_cmd is success
    when:
    - '"kernel" in ansible_facts.packages'
    - result_authselect_present.stat.exists
    tags:
    - DISA-STIG-RHEL-08-020025
    - NIST-800-53-AC-7 (a)
    - account_password_pam_faillock_system_auth
    - enable_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/system-auth
      File. - Remediation where authselect tool is not present
    block:

    - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/system-auth
        File. - Check if pam_faillock.so is already enabled
      ansible.builtin.lineinfile:
        path: /etc/pam.d/system-auth
        regexp: .*auth.*pam_faillock\.so (preauth|authfail)
        state: absent
      check_mode: true
      changed_when: false
      register: result_pam_faillock_is_enabled

    - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/system-auth
        File. - Enable pam_faillock.so preauth editing PAM files
      ansible.builtin.lineinfile:
        path: '{{ item }}'
        line: auth        required      pam_faillock.so preauth
        insertbefore: ^auth.*sufficient.*pam_unix\.so.*
        state: present
      loop:
      - /etc/pam.d/system-auth
      - /etc/pam.d/password-auth
      when:
      - result_pam_faillock_is_enabled.found == 0

    - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/system-auth
        File. - Enable pam_faillock.so authfail editing PAM files
      ansible.builtin.lineinfile:
        path: '{{ item }}'
        line: auth        required      pam_faillock.so authfail
        insertbefore: ^auth.*required.*pam_deny\.so.*
        state: present
      loop:
      - /etc/pam.d/system-auth
      - /etc/pam.d/password-auth
      when:
      - result_pam_faillock_is_enabled.found == 0

    - name: Configure the Use of the pam_faillock.so Module in the /etc/pam.d/system-auth
        File. - Enable pam_faillock.so account section editing PAM files
      ansible.builtin.lineinfile:
        path: '{{ item }}'
        line: account     required      pam_faillock.so
        insertbefore: ^account.*required.*pam_unix\.so.*
        state: present
      loop:
      - /etc/pam.d/system-auth
      - /etc/pam.d/password-auth
      when:
      - result_pam_faillock_is_enabled.found == 0
    when:
    - '"kernel" in ansible_facts.packages'
    - not result_authselect_present.stat.exists
    tags:
    - DISA-STIG-RHEL-08-020025
    - NIST-800-53-AC-7 (a)
    - account_password_pam_faillock_system_auth
    - enable_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure Password History Is Enforced for the Root User
    ansible.builtin.lineinfile:
      path: /etc/security/pwhistory.conf
      create: true
      regexp: ''
      line: enforce_for_root
      state: present
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    tags:
    - accounts_password_pam_pwhistory_enforce_for_root
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: 'Limit Password Reuse: password-auth - Check if system relies on authselect
      tool'
    ansible.builtin.stat:
      path: /usr/bin/authselect
    register: result_authselect_present
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    tags:
    - CJIS-5.6.2.1.1
    - NIST-800-171-3.5.8
    - NIST-800-53-IA-5(1)(e)
    - NIST-800-53-IA-5(f)
    - PCI-DSS-Req-8.2.5
    - PCI-DSSv4-8.3
    - PCI-DSSv4-8.3.7
    - accounts_password_pam_pwhistory_remember_password_auth
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed

  - name: 'Limit Password Reuse: password-auth - Collect the available authselect
      features'
    ansible.builtin.command:
      cmd: authselect list-features sssd
    register: result_authselect_available_features
    changed_when: false
    check_mode: false
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    - result_authselect_present.stat.exists
    tags:
    - CJIS-5.6.2.1.1
    - NIST-800-171-3.5.8
    - NIST-800-53-IA-5(1)(e)
    - NIST-800-53-IA-5(f)
    - PCI-DSS-Req-8.2.5
    - PCI-DSSv4-8.3
    - PCI-DSSv4-8.3.7
    - accounts_password_pam_pwhistory_remember_password_auth
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed

  - name: 'Limit Password Reuse: password-auth - Enable pam_pwhistory.so using authselect
      feature'
    block:

    - name: 'Limit Password Reuse: password-auth - Check integrity of authselect current
        profile'
      ansible.builtin.command:
        cmd: authselect check
      register: result_authselect_check_cmd
      changed_when: false
      check_mode: false
      failed_when: false

    - name: 'Limit Password Reuse: password-auth - Informative message based on the
        authselect integrity check result'
      ansible.builtin.assert:
        that:
        - ansible_check_mode or result_authselect_check_cmd.rc == 0
        fail_msg:
        - authselect integrity check failed. Remediation aborted!
        - This remediation could not be applied because an authselect profile was
          not selected or the selected profile is not intact.
        - It is not recommended to manually edit the PAM files when authselect tool
          is available.
        - In cases where the default authselect profile does not cover a specific
          demand, a custom authselect profile is recommended.
        success_msg:
        - authselect integrity check passed

    - name: 'Limit Password Reuse: password-auth - Get authselect current features'
      ansible.builtin.shell:
        cmd: authselect current | tail -n+3 | awk '{ print $2 }'
      register: result_authselect_features
      changed_when: false
      check_mode: false
      when:
      - result_authselect_check_cmd is success

    - name: 'Limit Password Reuse: password-auth - Ensure "with-pwhistory" feature
        is enabled using authselect tool'
      ansible.builtin.command:
        cmd: authselect enable-feature with-pwhistory
      register: result_authselect_enable_feature_cmd
      when:
      - result_authselect_check_cmd is success
      - result_authselect_features.stdout is not search("with-pwhistory")

    - name: 'Limit Password Reuse: password-auth - Ensure authselect changes are applied'
      ansible.builtin.command:
        cmd: authselect apply-changes -b
      when:
      - result_authselect_enable_feature_cmd is not skipped
      - result_authselect_enable_feature_cmd is success
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    - result_authselect_present.stat.exists
    - result_authselect_available_features.stdout is search("with-pwhistory")
    tags:
    - CJIS-5.6.2.1.1
    - NIST-800-171-3.5.8
    - NIST-800-53-IA-5(1)(e)
    - NIST-800-53-IA-5(f)
    - PCI-DSS-Req-8.2.5
    - PCI-DSSv4-8.3
    - PCI-DSSv4-8.3.7
    - accounts_password_pam_pwhistory_remember_password_auth
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed

  - name: 'Limit Password Reuse: password-auth - Enable pam_pwhistory.so in appropriate
      PAM files'
    block:

    - name: 'Limit Password Reuse: password-auth - Define the PAM file to be edited
        as a local fact'
      ansible.builtin.set_fact:
        pam_file_path: /etc/pam.d/password-auth

    - name: 'Limit Password Reuse: password-auth - Check if system relies on authselect
        tool'
      ansible.builtin.stat:
        path: /usr/bin/authselect
      register: result_authselect_present

    - name: 'Limit Password Reuse: password-auth - Ensure authselect custom profile
        is used if authselect is present'
      block:

      - name: 'Limit Password Reuse: password-auth - Check integrity of authselect
          current profile'
        ansible.builtin.command:
          cmd: authselect check
        register: result_authselect_check_cmd
        changed_when: false
        check_mode: false
        failed_when: false

      - name: 'Limit Password Reuse: password-auth - Informative message based on
          the authselect integrity check result'
        ansible.builtin.assert:
          that:
          - ansible_check_mode or result_authselect_check_cmd.rc == 0
          fail_msg:
          - authselect integrity check failed. Remediation aborted!
          - This remediation could not be applied because an authselect profile was
            not selected or the selected profile is not intact.
          - It is not recommended to manually edit the PAM files when authselect tool
            is available.
          - In cases where the default authselect profile does not cover a specific
            demand, a custom authselect profile is recommended.
          success_msg:
          - authselect integrity check passed

      - name: 'Limit Password Reuse: password-auth - Get authselect current profile'
        ansible.builtin.shell:
          cmd: authselect current -r | awk '{ print $1 }'
        register: result_authselect_profile
        changed_when: false
        when:
        - result_authselect_check_cmd is success

      - name: 'Limit Password Reuse: password-auth - Define the current authselect
          profile as a local fact'
        ansible.builtin.set_fact:
          authselect_current_profile: '{{ result_authselect_profile.stdout }}'
          authselect_custom_profile: '{{ result_authselect_profile.stdout }}'
        when:
        - result_authselect_profile is not skipped
        - result_authselect_profile.stdout is match("custom/")

      - name: 'Limit Password Reuse: password-auth - Define the new authselect custom
          profile as a local fact'
        ansible.builtin.set_fact:
          authselect_current_profile: '{{ result_authselect_profile.stdout }}'
          authselect_custom_profile: custom/hardening
        when:
        - result_authselect_profile is not skipped
        - result_authselect_profile.stdout is not match("custom/")

      - name: 'Limit Password Reuse: password-auth - Get authselect current features
          to also enable them in the custom profile'
        ansible.builtin.shell:
          cmd: authselect current | tail -n+3 | awk '{ print $2 }'
        register: result_authselect_features
        changed_when: false
        check_mode: false
        when:
        - result_authselect_profile is not skipped
        - authselect_current_profile is not match("custom/")

      - name: 'Limit Password Reuse: password-auth - Check if any custom profile with
          the same name was already created'
        ansible.builtin.stat:
          path: /etc/authselect/{{ authselect_custom_profile }}
        register: result_authselect_custom_profile_present
        changed_when: false
        when:
        - result_authselect_profile is not skipped
        - authselect_current_profile is not match("custom/")

      - name: 'Limit Password Reuse: password-auth - Create an authselect custom profile
          based on the current profile'
        ansible.builtin.command:
          cmd: authselect create-profile hardening -b {{ authselect_current_profile
            }}
        when:
        - result_authselect_profile is not skipped
        - result_authselect_check_cmd is success
        - authselect_current_profile is not match("^(custom/|local)")
        - not result_authselect_custom_profile_present.stat.exists

      - name: 'Limit Password Reuse: password-auth - Create an authselect custom profile
          based on sssd profile'
        ansible.builtin.command:
          cmd: authselect create-profile hardening -b sssd
        when:
        - result_authselect_profile is not skipped
        - result_authselect_check_cmd is success
        - authselect_current_profile is match("local")
        - not result_authselect_custom_profile_present.stat.exists

      - name: 'Limit Password Reuse: password-auth - Ensure authselect changes are
          applied'
        ansible.builtin.command:
          cmd: authselect apply-changes -b --backup=before-hardening-custom-profile
        when:
        - result_authselect_check_cmd is success
        - result_authselect_profile is not skipped
        - authselect_current_profile is not match("custom/")
        - authselect_custom_profile is not match(authselect_current_profile)

      - name: 'Limit Password Reuse: password-auth - Ensure the authselect custom
          profile is selected'
        ansible.builtin.command:
          cmd: authselect select {{ authselect_custom_profile }}
        register: result_pam_authselect_select_profile
        when:
        - result_authselect_check_cmd is success
        - result_authselect_profile is not skipped
        - authselect_current_profile is not match("custom/")
        - authselect_custom_profile is not match(authselect_current_profile)

      - name: 'Limit Password Reuse: password-auth - Restore the authselect features
          in the custom profile'
        ansible.builtin.command:
          cmd: authselect enable-feature {{ item }}
        loop: '{{ result_authselect_features.stdout_lines }}'
        register: result_pam_authselect_restore_features
        when:
        - result_authselect_profile is not skipped
        - result_authselect_features is not skipped
        - result_pam_authselect_select_profile is not skipped

      - name: 'Limit Password Reuse: password-auth - Ensure authselect changes are
          applied'
        ansible.builtin.command:
          cmd: authselect apply-changes -b --backup=after-hardening-custom-profile
        when:
        - result_authselect_check_cmd is success
        - result_authselect_profile is not skipped
        - result_pam_authselect_restore_features is not skipped

      - name: 'Limit Password Reuse: password-auth - Change the PAM file to be edited
          according to the custom authselect profile'
        ansible.builtin.set_fact:
          pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path
            | basename }}
        when:
        - authselect_custom_profile is defined
      when:
      - result_authselect_present.stat.exists

    - name: 'Limit Password Reuse: password-auth - Define a fact for control already
        filtered in case filters are used'
      ansible.builtin.set_fact:
        pam_module_control: '{{ var_password_pam_remember_control_flag.split(",")[0]
          }}'

    - name: 'Limit Password Reuse: password-auth - Check if expected PAM module line
        is present in {{ pam_file_path }}'
      ansible.builtin.lineinfile:
        path: '{{ pam_file_path }}'
        regexp: ^\s*password\s+{{ pam_module_control | regex_escape() }}\s+pam_pwhistory.so\s*.*
        state: absent
      check_mode: true
      changed_when: false
      register: result_pam_line_present

    - name: 'Limit Password Reuse: password-auth - Include or update the PAM module
        line in {{ pam_file_path }}'
      block:

      - name: 'Limit Password Reuse: password-auth - Check if required PAM module
          line is present in {{ pam_file_path }} with different control'
        ansible.builtin.lineinfile:
          path: '{{ pam_file_path }}'
          regexp: ^\s*password\s+.*\s+pam_pwhistory.so\s*
          state: absent
        check_mode: true
        changed_when: false
        register: result_pam_line_other_control_present

      - name: 'Limit Password Reuse: password-auth - Ensure the correct control for
          the required PAM module line in {{ pam_file_path }}'
        ansible.builtin.replace:
          dest: '{{ pam_file_path }}'
          regexp: ^(\s*password\s+).*(\bpam_pwhistory.so.*)
          replace: \1{{ pam_module_control }} \2
        register: result_pam_module_edit
        when:
        - result_pam_line_other_control_present.found == 1

      - name: 'Limit Password Reuse: password-auth - Ensure the required PAM module
          line is included in {{ pam_file_path }}'
        ansible.builtin.lineinfile:
          dest: '{{ pam_file_path }}'
          insertafter: ^password.*requisite.*pam_pwquality\.so
          line: password    {{ pam_module_control }}    pam_pwhistory.so
        register: result_pam_module_add
        when:
        - result_pam_line_other_control_present.found == 0 or result_pam_line_other_control_present.found
          > 1

      - name: 'Limit Password Reuse: password-auth - Ensure authselect changes are
          applied'
        ansible.builtin.command:
          cmd: authselect apply-changes -b
        when:
        - result_authselect_present is defined
        - result_authselect_present.stat.exists
        - |-
          (result_pam_module_add is defined and result_pam_module_add.changed)
           or (result_pam_module_edit is defined and result_pam_module_edit.changed)
      when:
      - result_pam_line_present.found is defined
      - result_pam_line_present.found == 0
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    - |
      (result_authselect_available_features.stdout is defined and result_authselect_available_features.stdout is not search("with-pwhistory")) or result_authselect_available_features is not defined
    tags:
    - CJIS-5.6.2.1.1
    - NIST-800-171-3.5.8
    - NIST-800-53-IA-5(1)(e)
    - NIST-800-53-IA-5(f)
    - PCI-DSS-Req-8.2.5
    - PCI-DSSv4-8.3
    - PCI-DSSv4-8.3.7
    - accounts_password_pam_pwhistory_remember_password_auth
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed

  - name: 'Limit Password Reuse: password-auth - Check the presence of /etc/security/pwhistory.conf
      file'
    ansible.builtin.stat:
      path: /etc/security/pwhistory.conf
    register: result_pwhistory_conf_check
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    tags:
    - CJIS-5.6.2.1.1
    - NIST-800-171-3.5.8
    - NIST-800-53-IA-5(1)(e)
    - NIST-800-53-IA-5(f)
    - PCI-DSS-Req-8.2.5
    - PCI-DSSv4-8.3
    - PCI-DSSv4-8.3.7
    - accounts_password_pam_pwhistory_remember_password_auth
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed

  - name: 'Limit Password Reuse: password-auth - pam_pwhistory.so parameters are configured
      in /etc/security/pwhistory.conf file'
    block:

    - name: 'Limit Password Reuse: password-auth - Ensure the pam_pwhistory.so remember
        parameter in /etc/security/pwhistory.conf'
      ansible.builtin.lineinfile:
        path: /etc/security/pwhistory.conf
        regexp: ^\s*remember\s*=
        line: remember = {{ var_password_pam_remember }}
        state: present

    - name: 'Limit Password Reuse: password-auth - Ensure the pam_pwhistory.so remember
        parameter is removed from PAM files'
      block:

      - name: 'Limit Password Reuse: password-auth - Check if /etc/pam.d/password-auth
          file is present'
        ansible.builtin.stat:
          path: /etc/pam.d/password-auth
        register: result_pam_password_auth_file_present

      - name: 'Limit Password Reuse: password-auth - Check the proper remediation
          for the system'
        block:

        - name: 'Limit Password Reuse: password-auth - Define the PAM file to be edited
            as a local fact'
          ansible.builtin.set_fact:
            pam_file_path: /etc/pam.d/password-auth

        - name: 'Limit Password Reuse: password-auth - Check if system relies on authselect
            tool'
          ansible.builtin.stat:
            path: /usr/bin/authselect
          register: result_authselect_present

        - name: 'Limit Password Reuse: password-auth - Ensure authselect custom profile
            is used if authselect is present'
          block:

          - name: 'Limit Password Reuse: password-auth - Check integrity of authselect
              current profile'
            ansible.builtin.command:
              cmd: authselect check
            register: result_authselect_check_cmd
            changed_when: false
            check_mode: false
            failed_when: false

          - name: 'Limit Password Reuse: password-auth - Informative message based
              on the authselect integrity check result'
            ansible.builtin.assert:
              that:
              - ansible_check_mode or result_authselect_check_cmd.rc == 0
              fail_msg:
              - authselect integrity check failed. Remediation aborted!
              - This remediation could not be applied because an authselect profile
                was not selected or the selected profile is not intact.
              - It is not recommended to manually edit the PAM files when authselect
                tool is available.
              - In cases where the default authselect profile does not cover a specific
                demand, a custom authselect profile is recommended.
              success_msg:
              - authselect integrity check passed

          - name: 'Limit Password Reuse: password-auth - Get authselect current profile'
            ansible.builtin.shell:
              cmd: authselect current -r | awk '{ print $1 }'
            register: result_authselect_profile
            changed_when: false
            when:
            - result_authselect_check_cmd is success

          - name: 'Limit Password Reuse: password-auth - Define the current authselect
              profile as a local fact'
            ansible.builtin.set_fact:
              authselect_current_profile: '{{ result_authselect_profile.stdout }}'
              authselect_custom_profile: '{{ result_authselect_profile.stdout }}'
            when:
            - result_authselect_profile is not skipped
            - result_authselect_profile.stdout is match("custom/")

          - name: 'Limit Password Reuse: password-auth - Define the new authselect
              custom profile as a local fact'
            ansible.builtin.set_fact:
              authselect_current_profile: '{{ result_authselect_profile.stdout }}'
              authselect_custom_profile: custom/hardening
            when:
            - result_authselect_profile is not skipped
            - result_authselect_profile.stdout is not match("custom/")

          - name: 'Limit Password Reuse: password-auth - Get authselect current features
              to also enable them in the custom profile'
            ansible.builtin.shell:
              cmd: authselect current | tail -n+3 | awk '{ print $2 }'
            register: result_authselect_features
            changed_when: false
            check_mode: false
            when:
            - result_authselect_profile is not skipped
            - authselect_current_profile is not match("custom/")

          - name: 'Limit Password Reuse: password-auth - Check if any custom profile
              with the same name was already created'
            ansible.builtin.stat:
              path: /etc/authselect/{{ authselect_custom_profile }}
            register: result_authselect_custom_profile_present
            changed_when: false
            when:
            - result_authselect_profile is not skipped
            - authselect_current_profile is not match("custom/")

          - name: 'Limit Password Reuse: password-auth - Create an authselect custom
              profile based on the current profile'
            ansible.builtin.command:
              cmd: authselect create-profile hardening -b {{ authselect_current_profile
                }}
            when:
            - result_authselect_profile is not skipped
            - result_authselect_check_cmd is success
            - authselect_current_profile is not match("^(custom/|local)")
            - not result_authselect_custom_profile_present.stat.exists

          - name: 'Limit Password Reuse: password-auth - Create an authselect custom
              profile based on sssd profile'
            ansible.builtin.command:
              cmd: authselect create-profile hardening -b sssd
            when:
            - result_authselect_profile is not skipped
            - result_authselect_check_cmd is success
            - authselect_current_profile is match("local")
            - not result_authselect_custom_profile_present.stat.exists

          - name: 'Limit Password Reuse: password-auth - Ensure authselect changes
              are applied'
            ansible.builtin.command:
              cmd: authselect apply-changes -b --backup=before-hardening-custom-profile
            when:
            - result_authselect_check_cmd is success
            - result_authselect_profile is not skipped
            - authselect_current_profile is not match("custom/")
            - authselect_custom_profile is not match(authselect_current_profile)

          - name: 'Limit Password Reuse: password-auth - Ensure the authselect custom
              profile is selected'
            ansible.builtin.command:
              cmd: authselect select {{ authselect_custom_profile }}
            register: result_pam_authselect_select_profile
            when:
            - result_authselect_check_cmd is success
            - result_authselect_profile is not skipped
            - authselect_current_profile is not match("custom/")
            - authselect_custom_profile is not match(authselect_current_profile)

          - name: 'Limit Password Reuse: password-auth - Restore the authselect features
              in the custom profile'
            ansible.builtin.command:
              cmd: authselect enable-feature {{ item }}
            loop: '{{ result_authselect_features.stdout_lines }}'
            register: result_pam_authselect_restore_features
            when:
            - result_authselect_profile is not skipped
            - result_authselect_features is not skipped
            - result_pam_authselect_select_profile is not skipped

          - name: 'Limit Password Reuse: password-auth - Ensure authselect changes
              are applied'
            ansible.builtin.command:
              cmd: authselect apply-changes -b --backup=after-hardening-custom-profile
            when:
            - result_authselect_check_cmd is success
            - result_authselect_profile is not skipped
            - result_pam_authselect_restore_features is not skipped

          - name: 'Limit Password Reuse: password-auth - Change the PAM file to be
              edited according to the custom authselect profile'
            ansible.builtin.set_fact:
              pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path
                | basename }}
            when:
            - authselect_custom_profile is defined
          when:
          - result_authselect_present.stat.exists

        - name: 'Limit Password Reuse: password-auth - Define a fact for control already
            filtered in case filters are used'
          ansible.builtin.set_fact:
            pam_module_control: ''

        - name: 'Limit Password Reuse: password-auth - Check if {{ pam_file_path }}
            file is present'
          ansible.builtin.stat:
            path: '{{ pam_file_path }}'
          register: result_pam_file_present

        - name: 'Limit Password Reuse: password-auth - Ensure the "remember" option
            from "pam_pwhistory.so" is not present in {{ pam_file_path }}'
          ansible.builtin.replace:
            dest: '{{ pam_file_path }}'
            regexp: (.*password.*pam_pwhistory.so.*)\bremember\b=?[0-9a-zA-Z]*(.*)
            replace: \1\2
          register: result_pam_option_removal
          when:
          - result_pam_file_present.stat.exists

        - name: 'Limit Password Reuse: password-auth - Ensure authselect changes are
            applied'
          ansible.builtin.command:
            cmd: authselect apply-changes -b
          when:
          - result_authselect_present.stat.exists
          - result_pam_option_removal is changed
        when:
        - result_pam_password_auth_file_present.stat.exists
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    - result_pwhistory_conf_check.stat.exists
    tags:
    - CJIS-5.6.2.1.1
    - NIST-800-171-3.5.8
    - NIST-800-53-IA-5(1)(e)
    - NIST-800-53-IA-5(f)
    - PCI-DSS-Req-8.2.5
    - PCI-DSSv4-8.3
    - PCI-DSSv4-8.3.7
    - accounts_password_pam_pwhistory_remember_password_auth
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed

  - name: 'Limit Password Reuse: password-auth - pam_pwhistory.so parameters are configured
      in PAM files'
    block:

    - name: 'Limit Password Reuse: password-auth - Define the PAM file to be edited
        as a local fact'
      ansible.builtin.set_fact:
        pam_file_path: /etc/pam.d/password-auth

    - name: 'Limit Password Reuse: password-auth - Check if system relies on authselect
        tool'
      ansible.builtin.stat:
        path: /usr/bin/authselect
      register: result_authselect_present

    - name: 'Limit Password Reuse: password-auth - Ensure authselect custom profile
        is used if authselect is present'
      block:

      - name: 'Limit Password Reuse: password-auth - Check integrity of authselect
          current profile'
        ansible.builtin.command:
          cmd: authselect check
        register: result_authselect_check_cmd
        changed_when: false
        check_mode: false
        failed_when: false

      - name: 'Limit Password Reuse: password-auth - Informative message based on
          the authselect integrity check result'
        ansible.builtin.assert:
          that:
          - ansible_check_mode or result_authselect_check_cmd.rc == 0
          fail_msg:
          - authselect integrity check failed. Remediation aborted!
          - This remediation could not be applied because an authselect profile was
            not selected or the selected profile is not intact.
          - It is not recommended to manually edit the PAM files when authselect tool
            is available.
          - In cases where the default authselect profile does not cover a specific
            demand, a custom authselect profile is recommended.
          success_msg:
          - authselect integrity check passed

      - name: 'Limit Password Reuse: password-auth - Get authselect current profile'
        ansible.builtin.shell:
          cmd: authselect current -r | awk '{ print $1 }'
        register: result_authselect_profile
        changed_when: false
        when:
        - result_authselect_check_cmd is success

      - name: 'Limit Password Reuse: password-auth - Define the current authselect
          profile as a local fact'
        ansible.builtin.set_fact:
          authselect_current_profile: '{{ result_authselect_profile.stdout }}'
          authselect_custom_profile: '{{ result_authselect_profile.stdout }}'
        when:
        - result_authselect_profile is not skipped
        - result_authselect_profile.stdout is match("custom/")

      - name: 'Limit Password Reuse: password-auth - Define the new authselect custom
          profile as a local fact'
        ansible.builtin.set_fact:
          authselect_current_profile: '{{ result_authselect_profile.stdout }}'
          authselect_custom_profile: custom/hardening
        when:
        - result_authselect_profile is not skipped
        - result_authselect_profile.stdout is not match("custom/")

      - name: 'Limit Password Reuse: password-auth - Get authselect current features
          to also enable them in the custom profile'
        ansible.builtin.shell:
          cmd: authselect current | tail -n+3 | awk '{ print $2 }'
        register: result_authselect_features
        changed_when: false
        check_mode: false
        when:
        - result_authselect_profile is not skipped
        - authselect_current_profile is not match("custom/")

      - name: 'Limit Password Reuse: password-auth - Check if any custom profile with
          the same name was already created'
        ansible.builtin.stat:
          path: /etc/authselect/{{ authselect_custom_profile }}
        register: result_authselect_custom_profile_present
        changed_when: false
        when:
        - result_authselect_profile is not skipped
        - authselect_current_profile is not match("custom/")

      - name: 'Limit Password Reuse: password-auth - Create an authselect custom profile
          based on the current profile'
        ansible.builtin.command:
          cmd: authselect create-profile hardening -b {{ authselect_current_profile
            }}
        when:
        - result_authselect_profile is not skipped
        - result_authselect_check_cmd is success
        - authselect_current_profile is not match("^(custom/|local)")
        - not result_authselect_custom_profile_present.stat.exists

      - name: 'Limit Password Reuse: password-auth - Create an authselect custom profile
          based on sssd profile'
        ansible.builtin.command:
          cmd: authselect create-profile hardening -b sssd
        when:
        - result_authselect_profile is not skipped
        - result_authselect_check_cmd is success
        - authselect_current_profile is match("local")
        - not result_authselect_custom_profile_present.stat.exists

      - name: 'Limit Password Reuse: password-auth - Ensure authselect changes are
          applied'
        ansible.builtin.command:
          cmd: authselect apply-changes -b --backup=before-hardening-custom-profile
        when:
        - result_authselect_check_cmd is success
        - result_authselect_profile is not skipped
        - authselect_current_profile is not match("custom/")
        - authselect_custom_profile is not match(authselect_current_profile)

      - name: 'Limit Password Reuse: password-auth - Ensure the authselect custom
          profile is selected'
        ansible.builtin.command:
          cmd: authselect select {{ authselect_custom_profile }}
        register: result_pam_authselect_select_profile
        when:
        - result_authselect_check_cmd is success
        - result_authselect_profile is not skipped
        - authselect_current_profile is not match("custom/")
        - authselect_custom_profile is not match(authselect_current_profile)

      - name: 'Limit Password Reuse: password-auth - Restore the authselect features
          in the custom profile'
        ansible.builtin.command:
          cmd: authselect enable-feature {{ item }}
        loop: '{{ result_authselect_features.stdout_lines }}'
        register: result_pam_authselect_restore_features
        when:
        - result_authselect_profile is not skipped
        - result_authselect_features is not skipped
        - result_pam_authselect_select_profile is not skipped

      - name: 'Limit Password Reuse: password-auth - Ensure authselect changes are
          applied'
        ansible.builtin.command:
          cmd: authselect apply-changes -b --backup=after-hardening-custom-profile
        when:
        - result_authselect_check_cmd is success
        - result_authselect_profile is not skipped
        - result_pam_authselect_restore_features is not skipped

      - name: 'Limit Password Reuse: password-auth - Change the PAM file to be edited
          according to the custom authselect profile'
        ansible.builtin.set_fact:
          pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path
            | basename }}
        when:
        - authselect_custom_profile is defined
      when:
      - result_authselect_present.stat.exists

    - name: 'Limit Password Reuse: password-auth - Define a fact for control already
        filtered in case filters are used'
      ansible.builtin.set_fact:
        pam_module_control: requisite

    - name: 'Limit Password Reuse: password-auth - Check if expected PAM module line
        is present in {{ pam_file_path }}'
      ansible.builtin.lineinfile:
        path: '{{ pam_file_path }}'
        regexp: ^\s*password\s+{{ pam_module_control | regex_escape() }}\s+pam_pwhistory.so\s*.*
        state: absent
      check_mode: true
      changed_when: false
      register: result_pam_line_present

    - name: 'Limit Password Reuse: password-auth - Include or update the PAM module
        line in {{ pam_file_path }}'
      block:

      - name: 'Limit Password Reuse: password-auth - Check if required PAM module
          line is present in {{ pam_file_path }} with different control'
        ansible.builtin.lineinfile:
          path: '{{ pam_file_path }}'
          regexp: ^\s*password\s+.*\s+pam_pwhistory.so\s*
          state: absent
        check_mode: true
        changed_when: false
        register: result_pam_line_other_control_present

      - name: 'Limit Password Reuse: password-auth - Ensure the correct control for
          the required PAM module line in {{ pam_file_path }}'
        ansible.builtin.replace:
          dest: '{{ pam_file_path }}'
          regexp: ^(\s*password\s+).*(\bpam_pwhistory.so.*)
          replace: \1{{ pam_module_control }} \2
        register: result_pam_module_edit
        when:
        - result_pam_line_other_control_present.found == 1

      - name: 'Limit Password Reuse: password-auth - Ensure the required PAM module
          line is included in {{ pam_file_path }}'
        ansible.builtin.lineinfile:
          dest: '{{ pam_file_path }}'
          line: password    {{ pam_module_control }}    pam_pwhistory.so
        register: result_pam_module_add
        when:
        - result_pam_line_other_control_present.found == 0 or result_pam_line_other_control_present.found
          > 1

      - name: 'Limit Password Reuse: password-auth - Ensure authselect changes are
          applied'
        ansible.builtin.command:
          cmd: authselect apply-changes -b
        when:
        - result_authselect_present is defined
        - result_authselect_present.stat.exists
        - |-
          (result_pam_module_add is defined and result_pam_module_add.changed)
           or (result_pam_module_edit is defined and result_pam_module_edit.changed)
      when:
      - result_pam_line_present.found is defined
      - result_pam_line_present.found == 0

    - name: 'Limit Password Reuse: password-auth - Define a fact for control already
        filtered in case filters are used'
      ansible.builtin.set_fact:
        pam_module_control: requisite

    - name: 'Limit Password Reuse: password-auth - Check if the required PAM module
        option is present in {{ pam_file_path }}'
      ansible.builtin.lineinfile:
        path: '{{ pam_file_path }}'
        regexp: ^\s*password\s+{{ pam_module_control | regex_escape() }}\s+pam_pwhistory.so\s*.*\sremember\b
        state: absent
      check_mode: true
      changed_when: false
      register: result_pam_module_accounts_password_pam_pwhistory_remember_password_auth_option_present

    - name: 'Limit Password Reuse: password-auth - Ensure the "remember" PAM option
        for "pam_pwhistory.so" is included in {{ pam_file_path }}'
      ansible.builtin.lineinfile:
        path: '{{ pam_file_path }}'
        backrefs: true
        regexp: ^(\s*password\s+{{ pam_module_control | regex_escape() }}\s+pam_pwhistory.so.*)
        line: \1 remember={{ var_password_pam_remember }}
        state: present
      register: result_pam_accounts_password_pam_pwhistory_remember_password_auth_add
      when:
      - result_pam_module_accounts_password_pam_pwhistory_remember_password_auth_option_present.found
        is defined
      - result_pam_module_accounts_password_pam_pwhistory_remember_password_auth_option_present.found
        == 0

    - name: 'Limit Password Reuse: password-auth - Ensure the required value for "remember"
        PAM option from "pam_pwhistory.so" in {{ pam_file_path }}'
      ansible.builtin.lineinfile:
        path: '{{ pam_file_path }}'
        backrefs: true
        regexp: ^(\s*password\s+{{ pam_module_control | regex_escape() }}\s+pam_pwhistory.so\s+.*)(remember)=[0-9a-zA-Z]*\s*(.*)
        line: \1\2={{ var_password_pam_remember }} \3
      register: result_pam_accounts_password_pam_pwhistory_remember_password_auth_edit
      when:
      - result_pam_module_accounts_password_pam_pwhistory_remember_password_auth_option_present.found
        > 0

    - name: 'Limit Password Reuse: password-auth - Ensure authselect changes are applied'
      ansible.builtin.command:
        cmd: authselect apply-changes -b
      when:
      - result_authselect_present.stat.exists
      - (result_pam_remember_add is defined and result_pam_remember_add.changed) or
        (result_pam_remember_edit is defined and result_pam_remember_edit.changed)
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    - not result_pwhistory_conf_check.stat.exists
    tags:
    - CJIS-5.6.2.1.1
    - NIST-800-171-3.5.8
    - NIST-800-53-IA-5(1)(e)
    - NIST-800-53-IA-5(f)
    - PCI-DSS-Req-8.2.5
    - PCI-DSSv4-8.3
    - PCI-DSSv4-8.3.7
    - accounts_password_pam_pwhistory_remember_password_auth
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed

  - name: 'Limit Password Reuse: system-auth - Check if system relies on authselect
      tool'
    ansible.builtin.stat:
      path: /usr/bin/authselect
    register: result_authselect_present
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    tags:
    - CJIS-5.6.2.1.1
    - NIST-800-171-3.5.8
    - NIST-800-53-IA-5(1)(e)
    - NIST-800-53-IA-5(f)
    - PCI-DSS-Req-8.2.5
    - PCI-DSSv4-8.3
    - PCI-DSSv4-8.3.7
    - accounts_password_pam_pwhistory_remember_system_auth
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed

  - name: 'Limit Password Reuse: system-auth - Collect the available authselect features'
    ansible.builtin.command:
      cmd: authselect list-features sssd
    register: result_authselect_available_features
    changed_when: false
    check_mode: false
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    - result_authselect_present.stat.exists
    tags:
    - CJIS-5.6.2.1.1
    - NIST-800-171-3.5.8
    - NIST-800-53-IA-5(1)(e)
    - NIST-800-53-IA-5(f)
    - PCI-DSS-Req-8.2.5
    - PCI-DSSv4-8.3
    - PCI-DSSv4-8.3.7
    - accounts_password_pam_pwhistory_remember_system_auth
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed

  - name: 'Limit Password Reuse: system-auth - Enable pam_pwhistory.so using authselect
      feature'
    block:

    - name: 'Limit Password Reuse: system-auth - Check integrity of authselect current
        profile'
      ansible.builtin.command:
        cmd: authselect check
      register: result_authselect_check_cmd
      changed_when: false
      check_mode: false
      failed_when: false

    - name: 'Limit Password Reuse: system-auth - Informative message based on the
        authselect integrity check result'
      ansible.builtin.assert:
        that:
        - ansible_check_mode or result_authselect_check_cmd.rc == 0
        fail_msg:
        - authselect integrity check failed. Remediation aborted!
        - This remediation could not be applied because an authselect profile was
          not selected or the selected profile is not intact.
        - It is not recommended to manually edit the PAM files when authselect tool
          is available.
        - In cases where the default authselect profile does not cover a specific
          demand, a custom authselect profile is recommended.
        success_msg:
        - authselect integrity check passed

    - name: 'Limit Password Reuse: system-auth - Get authselect current features'
      ansible.builtin.shell:
        cmd: authselect current | tail -n+3 | awk '{ print $2 }'
      register: result_authselect_features
      changed_when: false
      check_mode: false
      when:
      - result_authselect_check_cmd is success

    - name: 'Limit Password Reuse: system-auth - Ensure "with-pwhistory" feature is
        enabled using authselect tool'
      ansible.builtin.command:
        cmd: authselect enable-feature with-pwhistory
      register: result_authselect_enable_feature_cmd
      when:
      - result_authselect_check_cmd is success
      - result_authselect_features.stdout is not search("with-pwhistory")

    - name: 'Limit Password Reuse: system-auth - Ensure authselect changes are applied'
      ansible.builtin.command:
        cmd: authselect apply-changes -b
      when:
      - result_authselect_enable_feature_cmd is not skipped
      - result_authselect_enable_feature_cmd is success
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    - result_authselect_present.stat.exists
    - result_authselect_available_features.stdout is search("with-pwhistory")
    tags:
    - CJIS-5.6.2.1.1
    - NIST-800-171-3.5.8
    - NIST-800-53-IA-5(1)(e)
    - NIST-800-53-IA-5(f)
    - PCI-DSS-Req-8.2.5
    - PCI-DSSv4-8.3
    - PCI-DSSv4-8.3.7
    - accounts_password_pam_pwhistory_remember_system_auth
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed

  - name: 'Limit Password Reuse: system-auth - Enable pam_pwhistory.so in appropriate
      PAM files'
    block:

    - name: 'Limit Password Reuse: system-auth - Define the PAM file to be edited
        as a local fact'
      ansible.builtin.set_fact:
        pam_file_path: /etc/pam.d/system-auth

    - name: 'Limit Password Reuse: system-auth - Check if system relies on authselect
        tool'
      ansible.builtin.stat:
        path: /usr/bin/authselect
      register: result_authselect_present

    - name: 'Limit Password Reuse: system-auth - Ensure authselect custom profile
        is used if authselect is present'
      block:

      - name: 'Limit Password Reuse: system-auth - Check integrity of authselect current
          profile'
        ansible.builtin.command:
          cmd: authselect check
        register: result_authselect_check_cmd
        changed_when: false
        check_mode: false
        failed_when: false

      - name: 'Limit Password Reuse: system-auth - Informative message based on the
          authselect integrity check result'
        ansible.builtin.assert:
          that:
          - ansible_check_mode or result_authselect_check_cmd.rc == 0
          fail_msg:
          - authselect integrity check failed. Remediation aborted!
          - This remediation could not be applied because an authselect profile was
            not selected or the selected profile is not intact.
          - It is not recommended to manually edit the PAM files when authselect tool
            is available.
          - In cases where the default authselect profile does not cover a specific
            demand, a custom authselect profile is recommended.
          success_msg:
          - authselect integrity check passed

      - name: 'Limit Password Reuse: system-auth - Get authselect current profile'
        ansible.builtin.shell:
          cmd: authselect current -r | awk '{ print $1 }'
        register: result_authselect_profile
        changed_when: false
        when:
        - result_authselect_check_cmd is success

      - name: 'Limit Password Reuse: system-auth - Define the current authselect profile
          as a local fact'
        ansible.builtin.set_fact:
          authselect_current_profile: '{{ result_authselect_profile.stdout }}'
          authselect_custom_profile: '{{ result_authselect_profile.stdout }}'
        when:
        - result_authselect_profile is not skipped
        - result_authselect_profile.stdout is match("custom/")

      - name: 'Limit Password Reuse: system-auth - Define the new authselect custom
          profile as a local fact'
        ansible.builtin.set_fact:
          authselect_current_profile: '{{ result_authselect_profile.stdout }}'
          authselect_custom_profile: custom/hardening
        when:
        - result_authselect_profile is not skipped
        - result_authselect_profile.stdout is not match("custom/")

      - name: 'Limit Password Reuse: system-auth - Get authselect current features
          to also enable them in the custom profile'
        ansible.builtin.shell:
          cmd: authselect current | tail -n+3 | awk '{ print $2 }'
        register: result_authselect_features
        changed_when: false
        check_mode: false
        when:
        - result_authselect_profile is not skipped
        - authselect_current_profile is not match("custom/")

      - name: 'Limit Password Reuse: system-auth - Check if any custom profile with
          the same name was already created'
        ansible.builtin.stat:
          path: /etc/authselect/{{ authselect_custom_profile }}
        register: result_authselect_custom_profile_present
        changed_when: false
        when:
        - result_authselect_profile is not skipped
        - authselect_current_profile is not match("custom/")

      - name: 'Limit Password Reuse: system-auth - Create an authselect custom profile
          based on the current profile'
        ansible.builtin.command:
          cmd: authselect create-profile hardening -b {{ authselect_current_profile
            }}
        when:
        - result_authselect_profile is not skipped
        - result_authselect_check_cmd is success
        - authselect_current_profile is not match("^(custom/|local)")
        - not result_authselect_custom_profile_present.stat.exists

      - name: 'Limit Password Reuse: system-auth - Create an authselect custom profile
          based on sssd profile'
        ansible.builtin.command:
          cmd: authselect create-profile hardening -b sssd
        when:
        - result_authselect_profile is not skipped
        - result_authselect_check_cmd is success
        - authselect_current_profile is match("local")
        - not result_authselect_custom_profile_present.stat.exists

      - name: 'Limit Password Reuse: system-auth - Ensure authselect changes are applied'
        ansible.builtin.command:
          cmd: authselect apply-changes -b --backup=before-hardening-custom-profile
        when:
        - result_authselect_check_cmd is success
        - result_authselect_profile is not skipped
        - authselect_current_profile is not match("custom/")
        - authselect_custom_profile is not match(authselect_current_profile)

      - name: 'Limit Password Reuse: system-auth - Ensure the authselect custom profile
          is selected'
        ansible.builtin.command:
          cmd: authselect select {{ authselect_custom_profile }}
        register: result_pam_authselect_select_profile
        when:
        - result_authselect_check_cmd is success
        - result_authselect_profile is not skipped
        - authselect_current_profile is not match("custom/")
        - authselect_custom_profile is not match(authselect_current_profile)

      - name: 'Limit Password Reuse: system-auth - Restore the authselect features
          in the custom profile'
        ansible.builtin.command:
          cmd: authselect enable-feature {{ item }}
        loop: '{{ result_authselect_features.stdout_lines }}'
        register: result_pam_authselect_restore_features
        when:
        - result_authselect_profile is not skipped
        - result_authselect_features is not skipped
        - result_pam_authselect_select_profile is not skipped

      - name: 'Limit Password Reuse: system-auth - Ensure authselect changes are applied'
        ansible.builtin.command:
          cmd: authselect apply-changes -b --backup=after-hardening-custom-profile
        when:
        - result_authselect_check_cmd is success
        - result_authselect_profile is not skipped
        - result_pam_authselect_restore_features is not skipped

      - name: 'Limit Password Reuse: system-auth - Change the PAM file to be edited
          according to the custom authselect profile'
        ansible.builtin.set_fact:
          pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path
            | basename }}
        when:
        - authselect_custom_profile is defined
      when:
      - result_authselect_present.stat.exists

    - name: 'Limit Password Reuse: system-auth - Define a fact for control already
        filtered in case filters are used'
      ansible.builtin.set_fact:
        pam_module_control: '{{ var_password_pam_remember_control_flag.split(",")[0]
          }}'

    - name: 'Limit Password Reuse: system-auth - Check if expected PAM module line
        is present in {{ pam_file_path }}'
      ansible.builtin.lineinfile:
        path: '{{ pam_file_path }}'
        regexp: ^\s*password\s+{{ pam_module_control | regex_escape() }}\s+pam_pwhistory.so\s*.*
        state: absent
      check_mode: true
      changed_when: false
      register: result_pam_line_present

    - name: 'Limit Password Reuse: system-auth - Include or update the PAM module
        line in {{ pam_file_path }}'
      block:

      - name: 'Limit Password Reuse: system-auth - Check if required PAM module line
          is present in {{ pam_file_path }} with different control'
        ansible.builtin.lineinfile:
          path: '{{ pam_file_path }}'
          regexp: ^\s*password\s+.*\s+pam_pwhistory.so\s*
          state: absent
        check_mode: true
        changed_when: false
        register: result_pam_line_other_control_present

      - name: 'Limit Password Reuse: system-auth - Ensure the correct control for
          the required PAM module line in {{ pam_file_path }}'
        ansible.builtin.replace:
          dest: '{{ pam_file_path }}'
          regexp: ^(\s*password\s+).*(\bpam_pwhistory.so.*)
          replace: \1{{ pam_module_control }} \2
        register: result_pam_module_edit
        when:
        - result_pam_line_other_control_present.found == 1

      - name: 'Limit Password Reuse: system-auth - Ensure the required PAM module
          line is included in {{ pam_file_path }}'
        ansible.builtin.lineinfile:
          dest: '{{ pam_file_path }}'
          insertafter: ^password.*requisite.*pam_pwquality\.so
          line: password    {{ pam_module_control }}    pam_pwhistory.so
        register: result_pam_module_add
        when:
        - result_pam_line_other_control_present.found == 0 or result_pam_line_other_control_present.found
          > 1

      - name: 'Limit Password Reuse: system-auth - Ensure authselect changes are applied'
        ansible.builtin.command:
          cmd: authselect apply-changes -b
        when:
        - result_authselect_present is defined
        - result_authselect_present.stat.exists
        - |-
          (result_pam_module_add is defined and result_pam_module_add.changed)
           or (result_pam_module_edit is defined and result_pam_module_edit.changed)
      when:
      - result_pam_line_present.found is defined
      - result_pam_line_present.found == 0
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    - |
      (result_authselect_available_features.stdout is defined and result_authselect_available_features.stdout is not search("with-pwhistory")) or result_authselect_available_features is not defined
    tags:
    - CJIS-5.6.2.1.1
    - NIST-800-171-3.5.8
    - NIST-800-53-IA-5(1)(e)
    - NIST-800-53-IA-5(f)
    - PCI-DSS-Req-8.2.5
    - PCI-DSSv4-8.3
    - PCI-DSSv4-8.3.7
    - accounts_password_pam_pwhistory_remember_system_auth
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed

  - name: 'Limit Password Reuse: system-auth - Check the presence of /etc/security/pwhistory.conf
      file'
    ansible.builtin.stat:
      path: /etc/security/pwhistory.conf
    register: result_pwhistory_conf_check
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    tags:
    - CJIS-5.6.2.1.1
    - NIST-800-171-3.5.8
    - NIST-800-53-IA-5(1)(e)
    - NIST-800-53-IA-5(f)
    - PCI-DSS-Req-8.2.5
    - PCI-DSSv4-8.3
    - PCI-DSSv4-8.3.7
    - accounts_password_pam_pwhistory_remember_system_auth
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed

  - name: 'Limit Password Reuse: system-auth - pam_pwhistory.so parameters are configured
      in /etc/security/pwhistory.conf file'
    block:

    - name: 'Limit Password Reuse: system-auth - Ensure the pam_pwhistory.so remember
        parameter in /etc/security/pwhistory.conf'
      ansible.builtin.lineinfile:
        path: /etc/security/pwhistory.conf
        regexp: ^\s*remember\s*=
        line: remember = {{ var_password_pam_remember }}
        state: present

    - name: 'Limit Password Reuse: system-auth - Ensure the pam_pwhistory.so remember
        parameter is removed from PAM files'
      block:

      - name: 'Limit Password Reuse: system-auth - Check if /etc/pam.d/system-auth
          file is present'
        ansible.builtin.stat:
          path: /etc/pam.d/system-auth
        register: result_pam_auth_file_present

      - name: 'Limit Password Reuse: system-auth - Check the proper remediation for
          the system'
        block:

        - name: 'Limit Password Reuse: system-auth - Define the PAM file to be edited
            as a local fact'
          ansible.builtin.set_fact:
            pam_file_path: /etc/pam.d/system-auth

        - name: 'Limit Password Reuse: system-auth - Check if system relies on authselect
            tool'
          ansible.builtin.stat:
            path: /usr/bin/authselect
          register: result_authselect_present

        - name: 'Limit Password Reuse: system-auth - Ensure authselect custom profile
            is used if authselect is present'
          block:

          - name: 'Limit Password Reuse: system-auth - Check integrity of authselect
              current profile'
            ansible.builtin.command:
              cmd: authselect check
            register: result_authselect_check_cmd
            changed_when: false
            check_mode: false
            failed_when: false

          - name: 'Limit Password Reuse: system-auth - Informative message based on
              the authselect integrity check result'
            ansible.builtin.assert:
              that:
              - ansible_check_mode or result_authselect_check_cmd.rc == 0
              fail_msg:
              - authselect integrity check failed. Remediation aborted!
              - This remediation could not be applied because an authselect profile
                was not selected or the selected profile is not intact.
              - It is not recommended to manually edit the PAM files when authselect
                tool is available.
              - In cases where the default authselect profile does not cover a specific
                demand, a custom authselect profile is recommended.
              success_msg:
              - authselect integrity check passed

          - name: 'Limit Password Reuse: system-auth - Get authselect current profile'
            ansible.builtin.shell:
              cmd: authselect current -r | awk '{ print $1 }'
            register: result_authselect_profile
            changed_when: false
            when:
            - result_authselect_check_cmd is success

          - name: 'Limit Password Reuse: system-auth - Define the current authselect
              profile as a local fact'
            ansible.builtin.set_fact:
              authselect_current_profile: '{{ result_authselect_profile.stdout }}'
              authselect_custom_profile: '{{ result_authselect_profile.stdout }}'
            when:
            - result_authselect_profile is not skipped
            - result_authselect_profile.stdout is match("custom/")

          - name: 'Limit Password Reuse: system-auth - Define the new authselect custom
              profile as a local fact'
            ansible.builtin.set_fact:
              authselect_current_profile: '{{ result_authselect_profile.stdout }}'
              authselect_custom_profile: custom/hardening
            when:
            - result_authselect_profile is not skipped
            - result_authselect_profile.stdout is not match("custom/")

          - name: 'Limit Password Reuse: system-auth - Get authselect current features
              to also enable them in the custom profile'
            ansible.builtin.shell:
              cmd: authselect current | tail -n+3 | awk '{ print $2 }'
            register: result_authselect_features
            changed_when: false
            check_mode: false
            when:
            - result_authselect_profile is not skipped
            - authselect_current_profile is not match("custom/")

          - name: 'Limit Password Reuse: system-auth - Check if any custom profile
              with the same name was already created'
            ansible.builtin.stat:
              path: /etc/authselect/{{ authselect_custom_profile }}
            register: result_authselect_custom_profile_present
            changed_when: false
            when:
            - result_authselect_profile is not skipped
            - authselect_current_profile is not match("custom/")

          - name: 'Limit Password Reuse: system-auth - Create an authselect custom
              profile based on the current profile'
            ansible.builtin.command:
              cmd: authselect create-profile hardening -b {{ authselect_current_profile
                }}
            when:
            - result_authselect_profile is not skipped
            - result_authselect_check_cmd is success
            - authselect_current_profile is not match("^(custom/|local)")
            - not result_authselect_custom_profile_present.stat.exists

          - name: 'Limit Password Reuse: system-auth - Create an authselect custom
              profile based on sssd profile'
            ansible.builtin.command:
              cmd: authselect create-profile hardening -b sssd
            when:
            - result_authselect_profile is not skipped
            - result_authselect_check_cmd is success
            - authselect_current_profile is match("local")
            - not result_authselect_custom_profile_present.stat.exists

          - name: 'Limit Password Reuse: system-auth - Ensure authselect changes are
              applied'
            ansible.builtin.command:
              cmd: authselect apply-changes -b --backup=before-hardening-custom-profile
            when:
            - result_authselect_check_cmd is success
            - result_authselect_profile is not skipped
            - authselect_current_profile is not match("custom/")
            - authselect_custom_profile is not match(authselect_current_profile)

          - name: 'Limit Password Reuse: system-auth - Ensure the authselect custom
              profile is selected'
            ansible.builtin.command:
              cmd: authselect select {{ authselect_custom_profile }}
            register: result_pam_authselect_select_profile
            when:
            - result_authselect_check_cmd is success
            - result_authselect_profile is not skipped
            - authselect_current_profile is not match("custom/")
            - authselect_custom_profile is not match(authselect_current_profile)

          - name: 'Limit Password Reuse: system-auth - Restore the authselect features
              in the custom profile'
            ansible.builtin.command:
              cmd: authselect enable-feature {{ item }}
            loop: '{{ result_authselect_features.stdout_lines }}'
            register: result_pam_authselect_restore_features
            when:
            - result_authselect_profile is not skipped
            - result_authselect_features is not skipped
            - result_pam_authselect_select_profile is not skipped

          - name: 'Limit Password Reuse: system-auth - Ensure authselect changes are
              applied'
            ansible.builtin.command:
              cmd: authselect apply-changes -b --backup=after-hardening-custom-profile
            when:
            - result_authselect_check_cmd is success
            - result_authselect_profile is not skipped
            - result_pam_authselect_restore_features is not skipped

          - name: 'Limit Password Reuse: system-auth - Change the PAM file to be edited
              according to the custom authselect profile'
            ansible.builtin.set_fact:
              pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path
                | basename }}
            when:
            - authselect_custom_profile is defined
          when:
          - result_authselect_present.stat.exists

        - name: 'Limit Password Reuse: system-auth - Define a fact for control already
            filtered in case filters are used'
          ansible.builtin.set_fact:
            pam_module_control: ''

        - name: 'Limit Password Reuse: system-auth - Check if {{ pam_file_path }}
            file is present'
          ansible.builtin.stat:
            path: '{{ pam_file_path }}'
          register: result_pam_file_present

        - name: 'Limit Password Reuse: system-auth - Ensure the "remember" option
            from "pam_pwhistory.so" is not present in {{ pam_file_path }}'
          ansible.builtin.replace:
            dest: '{{ pam_file_path }}'
            regexp: (.*password.*pam_pwhistory.so.*)\bremember\b=?[0-9a-zA-Z]*(.*)
            replace: \1\2
          register: result_pam_option_removal
          when:
          - result_pam_file_present.stat.exists

        - name: 'Limit Password Reuse: system-auth - Ensure authselect changes are
            applied'
          ansible.builtin.command:
            cmd: authselect apply-changes -b
          when:
          - result_authselect_present.stat.exists
          - result_pam_option_removal is changed
        when:
        - result_pam_auth_file_present.stat.exists
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    - result_pwhistory_conf_check.stat.exists
    tags:
    - CJIS-5.6.2.1.1
    - NIST-800-171-3.5.8
    - NIST-800-53-IA-5(1)(e)
    - NIST-800-53-IA-5(f)
    - PCI-DSS-Req-8.2.5
    - PCI-DSSv4-8.3
    - PCI-DSSv4-8.3.7
    - accounts_password_pam_pwhistory_remember_system_auth
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed

  - name: 'Limit Password Reuse: system-auth - pam_pwhistory.so parameters are configured
      in PAM files'
    block:

    - name: 'Limit Password Reuse: system-auth - Define the PAM file to be edited
        as a local fact'
      ansible.builtin.set_fact:
        pam_file_path: /etc/pam.d/system-auth

    - name: 'Limit Password Reuse: system-auth - Check if system relies on authselect
        tool'
      ansible.builtin.stat:
        path: /usr/bin/authselect
      register: result_authselect_present

    - name: 'Limit Password Reuse: system-auth - Ensure authselect custom profile
        is used if authselect is present'
      block:

      - name: 'Limit Password Reuse: system-auth - Check integrity of authselect current
          profile'
        ansible.builtin.command:
          cmd: authselect check
        register: result_authselect_check_cmd
        changed_when: false
        check_mode: false
        failed_when: false

      - name: 'Limit Password Reuse: system-auth - Informative message based on the
          authselect integrity check result'
        ansible.builtin.assert:
          that:
          - ansible_check_mode or result_authselect_check_cmd.rc == 0
          fail_msg:
          - authselect integrity check failed. Remediation aborted!
          - This remediation could not be applied because an authselect profile was
            not selected or the selected profile is not intact.
          - It is not recommended to manually edit the PAM files when authselect tool
            is available.
          - In cases where the default authselect profile does not cover a specific
            demand, a custom authselect profile is recommended.
          success_msg:
          - authselect integrity check passed

      - name: 'Limit Password Reuse: system-auth - Get authselect current profile'
        ansible.builtin.shell:
          cmd: authselect current -r | awk '{ print $1 }'
        register: result_authselect_profile
        changed_when: false
        when:
        - result_authselect_check_cmd is success

      - name: 'Limit Password Reuse: system-auth - Define the current authselect profile
          as a local fact'
        ansible.builtin.set_fact:
          authselect_current_profile: '{{ result_authselect_profile.stdout }}'
          authselect_custom_profile: '{{ result_authselect_profile.stdout }}'
        when:
        - result_authselect_profile is not skipped
        - result_authselect_profile.stdout is match("custom/")

      - name: 'Limit Password Reuse: system-auth - Define the new authselect custom
          profile as a local fact'
        ansible.builtin.set_fact:
          authselect_current_profile: '{{ result_authselect_profile.stdout }}'
          authselect_custom_profile: custom/hardening
        when:
        - result_authselect_profile is not skipped
        - result_authselect_profile.stdout is not match("custom/")

      - name: 'Limit Password Reuse: system-auth - Get authselect current features
          to also enable them in the custom profile'
        ansible.builtin.shell:
          cmd: authselect current | tail -n+3 | awk '{ print $2 }'
        register: result_authselect_features
        changed_when: false
        check_mode: false
        when:
        - result_authselect_profile is not skipped
        - authselect_current_profile is not match("custom/")

      - name: 'Limit Password Reuse: system-auth - Check if any custom profile with
          the same name was already created'
        ansible.builtin.stat:
          path: /etc/authselect/{{ authselect_custom_profile }}
        register: result_authselect_custom_profile_present
        changed_when: false
        when:
        - result_authselect_profile is not skipped
        - authselect_current_profile is not match("custom/")

      - name: 'Limit Password Reuse: system-auth - Create an authselect custom profile
          based on the current profile'
        ansible.builtin.command:
          cmd: authselect create-profile hardening -b {{ authselect_current_profile
            }}
        when:
        - result_authselect_profile is not skipped
        - result_authselect_check_cmd is success
        - authselect_current_profile is not match("^(custom/|local)")
        - not result_authselect_custom_profile_present.stat.exists

      - name: 'Limit Password Reuse: system-auth - Create an authselect custom profile
          based on sssd profile'
        ansible.builtin.command:
          cmd: authselect create-profile hardening -b sssd
        when:
        - result_authselect_profile is not skipped
        - result_authselect_check_cmd is success
        - authselect_current_profile is match("local")
        - not result_authselect_custom_profile_present.stat.exists

      - name: 'Limit Password Reuse: system-auth - Ensure authselect changes are applied'
        ansible.builtin.command:
          cmd: authselect apply-changes -b --backup=before-hardening-custom-profile
        when:
        - result_authselect_check_cmd is success
        - result_authselect_profile is not skipped
        - authselect_current_profile is not match("custom/")
        - authselect_custom_profile is not match(authselect_current_profile)

      - name: 'Limit Password Reuse: system-auth - Ensure the authselect custom profile
          is selected'
        ansible.builtin.command:
          cmd: authselect select {{ authselect_custom_profile }}
        register: result_pam_authselect_select_profile
        when:
        - result_authselect_check_cmd is success
        - result_authselect_profile is not skipped
        - authselect_current_profile is not match("custom/")
        - authselect_custom_profile is not match(authselect_current_profile)

      - name: 'Limit Password Reuse: system-auth - Restore the authselect features
          in the custom profile'
        ansible.builtin.command:
          cmd: authselect enable-feature {{ item }}
        loop: '{{ result_authselect_features.stdout_lines }}'
        register: result_pam_authselect_restore_features
        when:
        - result_authselect_profile is not skipped
        - result_authselect_features is not skipped
        - result_pam_authselect_select_profile is not skipped

      - name: 'Limit Password Reuse: system-auth - Ensure authselect changes are applied'
        ansible.builtin.command:
          cmd: authselect apply-changes -b --backup=after-hardening-custom-profile
        when:
        - result_authselect_check_cmd is success
        - result_authselect_profile is not skipped
        - result_pam_authselect_restore_features is not skipped

      - name: 'Limit Password Reuse: system-auth - Change the PAM file to be edited
          according to the custom authselect profile'
        ansible.builtin.set_fact:
          pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path
            | basename }}
        when:
        - authselect_custom_profile is defined
      when:
      - result_authselect_present.stat.exists

    - name: 'Limit Password Reuse: system-auth - Define a fact for control already
        filtered in case filters are used'
      ansible.builtin.set_fact:
        pam_module_control: requisite

    - name: 'Limit Password Reuse: system-auth - Check if expected PAM module line
        is present in {{ pam_file_path }}'
      ansible.builtin.lineinfile:
        path: '{{ pam_file_path }}'
        regexp: ^\s*password\s+{{ pam_module_control | regex_escape() }}\s+pam_pwhistory.so\s*.*
        state: absent
      check_mode: true
      changed_when: false
      register: result_pam_line_present

    - name: 'Limit Password Reuse: system-auth - Include or update the PAM module
        line in {{ pam_file_path }}'
      block:

      - name: 'Limit Password Reuse: system-auth - Check if required PAM module line
          is present in {{ pam_file_path }} with different control'
        ansible.builtin.lineinfile:
          path: '{{ pam_file_path }}'
          regexp: ^\s*password\s+.*\s+pam_pwhistory.so\s*
          state: absent
        check_mode: true
        changed_when: false
        register: result_pam_line_other_control_present

      - name: 'Limit Password Reuse: system-auth - Ensure the correct control for
          the required PAM module line in {{ pam_file_path }}'
        ansible.builtin.replace:
          dest: '{{ pam_file_path }}'
          regexp: ^(\s*password\s+).*(\bpam_pwhistory.so.*)
          replace: \1{{ pam_module_control }} \2
        register: result_pam_module_edit
        when:
        - result_pam_line_other_control_present.found == 1

      - name: 'Limit Password Reuse: system-auth - Ensure the required PAM module
          line is included in {{ pam_file_path }}'
        ansible.builtin.lineinfile:
          dest: '{{ pam_file_path }}'
          line: password    {{ pam_module_control }}    pam_pwhistory.so
        register: result_pam_module_add
        when:
        - result_pam_line_other_control_present.found == 0 or result_pam_line_other_control_present.found
          > 1

      - name: 'Limit Password Reuse: system-auth - Ensure authselect changes are applied'
        ansible.builtin.command:
          cmd: authselect apply-changes -b
        when:
        - result_authselect_present is defined
        - result_authselect_present.stat.exists
        - |-
          (result_pam_module_add is defined and result_pam_module_add.changed)
           or (result_pam_module_edit is defined and result_pam_module_edit.changed)
      when:
      - result_pam_line_present.found is defined
      - result_pam_line_present.found == 0

    - name: 'Limit Password Reuse: system-auth - Define a fact for control already
        filtered in case filters are used'
      ansible.builtin.set_fact:
        pam_module_control: requisite

    - name: 'Limit Password Reuse: system-auth - Check if the required PAM module
        option is present in {{ pam_file_path }}'
      ansible.builtin.lineinfile:
        path: '{{ pam_file_path }}'
        regexp: ^\s*password\s+{{ pam_module_control | regex_escape() }}\s+pam_pwhistory.so\s*.*\sremember\b
        state: absent
      check_mode: true
      changed_when: false
      register: result_pam_module_accounts_password_pam_pwhistory_remember_system_auth_option_present

    - name: 'Limit Password Reuse: system-auth - Ensure the "remember" PAM option
        for "pam_pwhistory.so" is included in {{ pam_file_path }}'
      ansible.builtin.lineinfile:
        path: '{{ pam_file_path }}'
        backrefs: true
        regexp: ^(\s*password\s+{{ pam_module_control | regex_escape() }}\s+pam_pwhistory.so.*)
        line: \1 remember={{ var_password_pam_remember }}
        state: present
      register: result_pam_accounts_password_pam_pwhistory_remember_system_auth_add
      when:
      - result_pam_module_accounts_password_pam_pwhistory_remember_system_auth_option_present.found
        is defined
      - result_pam_module_accounts_password_pam_pwhistory_remember_system_auth_option_present.found
        == 0

    - name: 'Limit Password Reuse: system-auth - Ensure the required value for "remember"
        PAM option from "pam_pwhistory.so" in {{ pam_file_path }}'
      ansible.builtin.lineinfile:
        path: '{{ pam_file_path }}'
        backrefs: true
        regexp: ^(\s*password\s+{{ pam_module_control | regex_escape() }}\s+pam_pwhistory.so\s+.*)(remember)=[0-9a-zA-Z]*\s*(.*)
        line: \1\2={{ var_password_pam_remember }} \3
      register: result_pam_accounts_password_pam_pwhistory_remember_system_auth_edit
      when:
      - result_pam_module_accounts_password_pam_pwhistory_remember_system_auth_option_present.found
        > 0

    - name: 'Limit Password Reuse: system-auth - Ensure authselect changes are applied'
      ansible.builtin.command:
        cmd: authselect apply-changes -b
      when:
      - result_authselect_present.stat.exists
      - (result_pam_remember_add is defined and result_pam_remember_add.changed) or
        (result_pam_remember_edit is defined and result_pam_remember_edit.changed)
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    - not result_pwhistory_conf_check.stat.exists
    tags:
    - CJIS-5.6.2.1.1
    - NIST-800-171-3.5.8
    - NIST-800-53-IA-5(1)(e)
    - NIST-800-53-IA-5(f)
    - PCI-DSS-Req-8.2.5
    - PCI-DSSv4-8.3
    - PCI-DSSv4-8.3.7
    - accounts_password_pam_pwhistory_remember_system_auth
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed

  - name: Enforce Password History with use_authtok - Check if system relies on authselect
      tool
    ansible.builtin.stat:
      path: /usr/bin/authselect
    register: result_authselect_present
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    tags:
    - accounts_password_pam_pwhistory_use_authtok
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed

  - name: Enforce Password History with use_authtok - Ensure authselect custom profile
      is used if authselect is present
    block:

    - name: Enforce Password History with use_authtok - Check integrity of authselect
        current profile
      ansible.builtin.command:
        cmd: authselect check
      register: result_authselect_check_cmd
      changed_when: false
      check_mode: false
      failed_when: false

    - name: Enforce Password History with use_authtok - Informative message based
        on the authselect integrity check result
      ansible.builtin.assert:
        that:
        - ansible_check_mode or result_authselect_check_cmd.rc == 0
        fail_msg:
        - authselect integrity check failed. Remediation aborted!
        - This remediation could not be applied because an authselect profile was
          not selected or the selected profile is not intact.
        - It is not recommended to manually edit the PAM files when authselect tool
          is available.
        - In cases where the default authselect profile does not cover a specific
          demand, a custom authselect profile is recommended.
        success_msg:
        - authselect integrity check passed

    - name: Enforce Password History with use_authtok - Get authselect current profile
      ansible.builtin.shell:
        cmd: authselect current -r | awk '{ print $1 }'
      register: result_authselect_profile
      changed_when: false
      when:
      - result_authselect_check_cmd is success

    - name: Enforce Password History with use_authtok - Define the current authselect
        profile as a local fact
      ansible.builtin.set_fact:
        authselect_current_profile: '{{ result_authselect_profile.stdout }}'
        authselect_custom_profile: '{{ result_authselect_profile.stdout }}'
      when:
      - result_authselect_profile is not skipped
      - result_authselect_profile.stdout is match("custom/")

    - name: Enforce Password History with use_authtok - Define the new authselect
        custom profile as a local fact
      ansible.builtin.set_fact:
        authselect_current_profile: '{{ result_authselect_profile.stdout }}'
        authselect_custom_profile: custom/hardening
      when:
      - result_authselect_profile is not skipped
      - result_authselect_profile.stdout is not match("custom/")

    - name: Enforce Password History with use_authtok - Get authselect current features
        to also enable them in the custom profile
      ansible.builtin.shell:
        cmd: authselect current | tail -n+3 | awk '{ print $2 }'
      register: result_authselect_features
      changed_when: false
      check_mode: false
      when:
      - result_authselect_profile is not skipped
      - authselect_current_profile is not match("custom/")

    - name: Enforce Password History with use_authtok - Check if any custom profile
        with the same name was already created
      ansible.builtin.stat:
        path: /etc/authselect/{{ authselect_custom_profile }}
      register: result_authselect_custom_profile_present
      changed_when: false
      when:
      - result_authselect_profile is not skipped
      - authselect_current_profile is not match("custom/")

    - name: Enforce Password History with use_authtok - Create an authselect custom
        profile based on the current profile
      ansible.builtin.command:
        cmd: authselect create-profile hardening -b {{ authselect_current_profile
          }}
      when:
      - result_authselect_profile is not skipped
      - result_authselect_check_cmd is success
      - authselect_current_profile is not match("^(custom/|local)")
      - not result_authselect_custom_profile_present.stat.exists

    - name: Enforce Password History with use_authtok - Create an authselect custom
        profile based on sssd profile
      ansible.builtin.command:
        cmd: authselect create-profile hardening -b sssd
      when:
      - result_authselect_profile is not skipped
      - result_authselect_check_cmd is success
      - authselect_current_profile is match("local")
      - not result_authselect_custom_profile_present.stat.exists

    - name: Enforce Password History with use_authtok - Ensure authselect changes
        are applied
      ansible.builtin.command:
        cmd: authselect apply-changes -b --backup=before-hardening-custom-profile
      when:
      - result_authselect_check_cmd is success
      - result_authselect_profile is not skipped
      - authselect_current_profile is not match("custom/")
      - authselect_custom_profile is not match(authselect_current_profile)

    - name: Enforce Password History with use_authtok - Ensure the authselect custom
        profile is selected
      ansible.builtin.command:
        cmd: authselect select {{ authselect_custom_profile }}
      register: result_pam_authselect_select_profile
      when:
      - result_authselect_check_cmd is success
      - result_authselect_profile is not skipped
      - authselect_current_profile is not match("custom/")
      - authselect_custom_profile is not match(authselect_current_profile)

    - name: Enforce Password History with use_authtok - Restore the authselect features
        in the custom profile
      ansible.builtin.command:
        cmd: authselect enable-feature {{ item }}
      loop: '{{ result_authselect_features.stdout_lines }}'
      register: result_pam_authselect_restore_features
      when:
      - result_authselect_profile is not skipped
      - result_authselect_features is not skipped
      - result_pam_authselect_select_profile is not skipped

    - name: Enforce Password History with use_authtok - Ensure authselect changes
        are applied
      ansible.builtin.command:
        cmd: authselect apply-changes -b --backup=after-hardening-custom-profile
      when:
      - result_authselect_check_cmd is success
      - result_authselect_profile is not skipped
      - result_pam_authselect_restore_features is not skipped
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    - result_authselect_present.stat.exists
    tags:
    - accounts_password_pam_pwhistory_use_authtok
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed

  - name: Enforce Password History with use_authtok - Get authselect current profile
    ansible.builtin.shell:
      cmd: authselect current -r | awk '{ print $1 }'
    register: result_authselect_profile
    changed_when: false
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    - result_authselect_check_cmd is success
    tags:
    - accounts_password_pam_pwhistory_use_authtok
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed

  - name: Enforce Password History with use_authtok - Define the PAM profile path
      based on the authselect profile
    ansible.builtin.set_fact:
      pam_profile_path: '{%- if result_authselect_profile.stdout is match("^custom/")
        -%} /etc/authselect/{{ result_authselect_profile.stdout }} {%- else -%} /usr/share/authselect/default/{{
        result_authselect_profile.stdout }} {%- endif -%}'
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    - result_authselect_check_cmd is success
    - result_authselect_profile is not skipped
    tags:
    - accounts_password_pam_pwhistory_use_authtok
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed

  - name: Enforce Password History with use_authtok - Check if "use_authtok" option
      is present in pam_pwhistory.so in /password-auth
    ansible.builtin.lineinfile:
      path: '{{ pam_profile_path }}/password-auth'
      regexp: ^\s*password\s+([^#\n\r]+)\s+pam_pwhistory\.so\s+([^#\n\r]+\s+)?use_authtok\b
      state: absent
    check_mode: true
    changed_when: false
    register: result_pam_pwhistory_password_auth_option_present
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    - result_authselect_check_cmd is success
    - result_authselect_profile is not skipped
    - pam_profile_path is defined
    tags:
    - accounts_password_pam_pwhistory_use_authtok
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed

  - name: Enforce Password History with use_authtok - Ensure "use_authtok" option
      is added to pam_pwhistory.so in /password-auth
    ansible.builtin.replace:
      path: '{{ pam_profile_path }}/password-auth'
      regexp: (^\s*password\s+(requisite|required|sufficient)\s+pam_pwhistory\.so\s+.*)$
      replace: \1 use_authtok
    register: result_pam_pwhistory_password_auth_add
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    - result_authselect_check_cmd is success
    - result_authselect_profile is not skipped
    - pam_profile_path is defined
    - result_pam_pwhistory_password_auth_option_present.found is defined
    - result_pam_pwhistory_password_auth_option_present.found == 0
    tags:
    - accounts_password_pam_pwhistory_use_authtok
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed

  - name: Enforce Password History with use_authtok - Check if "use_authtok" option
      is present in pam_pwhistory.so in /system-auth
    ansible.builtin.lineinfile:
      path: '{{ pam_profile_path }}/system-auth'
      regexp: ^\s*password\s+([^#\n\r]+)\s+pam_pwhistory\.so\s+([^#\n\r]+\s+)?use_authtok\b
      state: absent
    check_mode: true
    changed_when: false
    register: result_pam_pwhistory_system_auth_option_present
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    - result_authselect_check_cmd is success
    - result_authselect_profile is not skipped
    - pam_profile_path is defined
    tags:
    - accounts_password_pam_pwhistory_use_authtok
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed

  - name: Enforce Password History with use_authtok - Ensure "use_authtok" option
      is added to pam_pwhistory.so in /system-auth
    ansible.builtin.replace:
      path: '{{ pam_profile_path }}/system-auth'
      regexp: (^\s*password\s+(requisite|required|sufficient)\s+pam_pwhistory\.so\s+.*)$
      replace: \1 use_authtok
    register: result_pam_pwhistory_system_auth_add
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    - result_authselect_check_cmd is success
    - result_authselect_profile is not skipped
    - pam_profile_path is defined
    - result_pam_pwhistory_system_auth_option_present.found is defined
    - result_pam_pwhistory_system_auth_option_present.found == 0
    tags:
    - accounts_password_pam_pwhistory_use_authtok
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed

  - name: Enforce Password History with use_authtok - Ensure authselect changes are
      applied
    ansible.builtin.command:
      cmd: authselect apply-changes -b
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    - result_authselect_check_cmd is success
    - result_authselect_profile is not skipped
    - |-
      (result_pam_pwhistory_password_auth_add is defined and result_pam_pwhistory_password_auth_add.changed)
       or (result_pam_pwhistory_system_auth_add is defined and result_pam_pwhistory_system_auth_add.changed)
    tags:
    - accounts_password_pam_pwhistory_use_authtok
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed

  - name: Require use_authtok for pam_unix.so - Check if system relies on authselect
      tool
    ansible.builtin.stat:
      path: /usr/bin/authselect
    register: result_authselect_present
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    tags:
    - accounts_password_pam_unix_authtok
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed

  - name: Require use_authtok for pam_unix.so - Define a fact for control already
      filtered in case filters are used
    ansible.builtin.set_fact:
      pam_module_control: sufficient
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    tags:
    - accounts_password_pam_unix_authtok
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed

  - name: Require use_authtok for pam_unix.so - Check if expected PAM module line
      is present in /etc/pam.d/system-auth
    ansible.builtin.lineinfile:
      path: /etc/pam.d/system-auth
      regexp: ^\s*password\s+{{ pam_module_control | regex_escape() }}\s+pam_unix.so\s*.*
      state: absent
    check_mode: true
    changed_when: false
    register: result_pam_line_present
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    tags:
    - accounts_password_pam_unix_authtok
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed

  - name: Require use_authtok for pam_unix.so - Include or update the PAM module line
      in /etc/pam.d/system-auth
    block:

    - name: Require use_authtok for pam_unix.so - Check if required PAM module line
        is present in /etc/pam.d/system-auth with different control
      ansible.builtin.lineinfile:
        path: /etc/pam.d/system-auth
        regexp: ^\s*password\s+.*\s+pam_unix.so\s*
        state: absent
      check_mode: true
      changed_when: false
      register: result_pam_line_other_control_present

    - name: Require use_authtok for pam_unix.so - Ensure the correct control for the
        required PAM module line in /etc/pam.d/system-auth
      ansible.builtin.replace:
        dest: /etc/pam.d/system-auth
        regexp: ^(\s*password\s+).*(\bpam_unix.so.*)
        replace: \1{{ pam_module_control }} \2
      register: result_pam_module_edit
      when:
      - result_pam_line_other_control_present.found == 1

    - name: Require use_authtok for pam_unix.so - Ensure the required PAM module line
        is included in /etc/pam.d/system-auth
      ansible.builtin.lineinfile:
        dest: /etc/pam.d/system-auth
        line: password    {{ pam_module_control }}    pam_unix.so
      register: result_pam_module_add
      when:
      - result_pam_line_other_control_present.found == 0 or result_pam_line_other_control_present.found
        > 1

    - name: Require use_authtok for pam_unix.so - Ensure authselect changes are applied
      ansible.builtin.command:
        cmd: authselect apply-changes -b
      when:
      - result_authselect_present is defined
      - result_authselect_present.stat.exists
      - |-
        (result_pam_module_add is defined and result_pam_module_add.changed)
         or (result_pam_module_edit is defined and result_pam_module_edit.changed)
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    - result_pam_line_present.found is defined
    - result_pam_line_present.found == 0
    tags:
    - accounts_password_pam_unix_authtok
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed

  - name: Require use_authtok for pam_unix.so - Define a fact for control already
      filtered in case filters are used
    ansible.builtin.set_fact:
      pam_module_control: sufficient
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    tags:
    - accounts_password_pam_unix_authtok
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed

  - name: Require use_authtok for pam_unix.so - Check if the required PAM module option
      is present in /etc/pam.d/system-auth
    ansible.builtin.lineinfile:
      path: /etc/pam.d/system-auth
      regexp: ^\s*password\s+{{ pam_module_control | regex_escape() }}\s+pam_unix.so\s*.*\suse_authtok\b
      state: absent
    check_mode: true
    changed_when: false
    register: result_pam_module_accounts_password_pam_unix_authtok_option_present
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    tags:
    - accounts_password_pam_unix_authtok
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed

  - name: Require use_authtok for pam_unix.so - Ensure the "use_authtok" PAM option
      for "pam_unix.so" is included in /etc/pam.d/system-auth
    ansible.builtin.lineinfile:
      path: /etc/pam.d/system-auth
      backrefs: true
      regexp: ^(\s*password\s+{{ pam_module_control | regex_escape() }}\s+pam_unix.so.*)
      line: \1 use_authtok
      state: present
    register: result_pam_accounts_password_pam_unix_authtok_add
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    - result_pam_module_accounts_password_pam_unix_authtok_option_present.found is
      defined
    - result_pam_module_accounts_password_pam_unix_authtok_option_present.found ==
      0
    tags:
    - accounts_password_pam_unix_authtok
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed

  - name: Require use_authtok for pam_unix.so - Define a fact for control already
      filtered in case filters are used
    ansible.builtin.set_fact:
      pam_module_control: sufficient
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    tags:
    - accounts_password_pam_unix_authtok
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed

  - name: Require use_authtok for pam_unix.so - Check if expected PAM module line
      is present in /etc/pam.d/password-auth
    ansible.builtin.lineinfile:
      path: /etc/pam.d/password-auth
      regexp: ^\s*password\s+{{ pam_module_control | regex_escape() }}\s+pam_unix.so\s*.*
      state: absent
    check_mode: true
    changed_when: false
    register: result_pam_line_present
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    tags:
    - accounts_password_pam_unix_authtok
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed

  - name: Require use_authtok for pam_unix.so - Include or update the PAM module line
      in /etc/pam.d/password-auth
    block:

    - name: Require use_authtok for pam_unix.so - Check if required PAM module line
        is present in /etc/pam.d/password-auth with different control
      ansible.builtin.lineinfile:
        path: /etc/pam.d/password-auth
        regexp: ^\s*password\s+.*\s+pam_unix.so\s*
        state: absent
      check_mode: true
      changed_when: false
      register: result_pam_line_other_control_present

    - name: Require use_authtok for pam_unix.so - Ensure the correct control for the
        required PAM module line in /etc/pam.d/password-auth
      ansible.builtin.replace:
        dest: /etc/pam.d/password-auth
        regexp: ^(\s*password\s+).*(\bpam_unix.so.*)
        replace: \1{{ pam_module_control }} \2
      register: result_pam_module_edit
      when:
      - result_pam_line_other_control_present.found == 1

    - name: Require use_authtok for pam_unix.so - Ensure the required PAM module line
        is included in /etc/pam.d/password-auth
      ansible.builtin.lineinfile:
        dest: /etc/pam.d/password-auth
        line: password    {{ pam_module_control }}    pam_unix.so
      register: result_pam_module_add
      when:
      - result_pam_line_other_control_present.found == 0 or result_pam_line_other_control_present.found
        > 1

    - name: Require use_authtok for pam_unix.so - Ensure authselect changes are applied
      ansible.builtin.command:
        cmd: authselect apply-changes -b
      when:
      - result_authselect_present is defined
      - result_authselect_present.stat.exists
      - |-
        (result_pam_module_add is defined and result_pam_module_add.changed)
         or (result_pam_module_edit is defined and result_pam_module_edit.changed)
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    - result_pam_line_present.found is defined
    - result_pam_line_present.found == 0
    tags:
    - accounts_password_pam_unix_authtok
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed

  - name: Require use_authtok for pam_unix.so - Define a fact for control already
      filtered in case filters are used
    ansible.builtin.set_fact:
      pam_module_control: sufficient
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    tags:
    - accounts_password_pam_unix_authtok
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed

  - name: Require use_authtok for pam_unix.so - Check if the required PAM module option
      is present in /etc/pam.d/password-auth
    ansible.builtin.lineinfile:
      path: /etc/pam.d/password-auth
      regexp: ^\s*password\s+{{ pam_module_control | regex_escape() }}\s+pam_unix.so\s*.*\suse_authtok\b
      state: absent
    check_mode: true
    changed_when: false
    register: result_pam_module_accounts_password_pam_unix_authtok_option_present
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    tags:
    - accounts_password_pam_unix_authtok
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed

  - name: Require use_authtok for pam_unix.so - Ensure the "use_authtok" PAM option
      for "pam_unix.so" is included in /etc/pam.d/password-auth
    ansible.builtin.lineinfile:
      path: /etc/pam.d/password-auth
      backrefs: true
      regexp: ^(\s*password\s+{{ pam_module_control | regex_escape() }}\s+pam_unix.so.*)
      line: \1 use_authtok
      state: present
    register: result_pam_accounts_password_pam_unix_authtok_add
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    - result_pam_module_accounts_password_pam_unix_authtok_option_present.found is
      defined
    - result_pam_module_accounts_password_pam_unix_authtok_option_present.found ==
      0
    tags:
    - accounts_password_pam_unix_authtok
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed

  - name: Lock Accounts After Failed Password Attempts - Check if system relies on
      authselect tool
    ansible.builtin.stat:
      path: /usr/bin/authselect
    register: result_authselect_present
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    tags:
    - CJIS-5.5.3
    - DISA-STIG-RHEL-08-020011
    - NIST-800-171-3.1.8
    - NIST-800-53-AC-7(a)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-8.1.6
    - PCI-DSSv4-8.3
    - PCI-DSSv4-8.3.4
    - accounts_passwords_pam_faillock_deny
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Lock Accounts After Failed Password Attempts - Remediation where authselect
      tool is present
    block:

    - name: Lock Accounts After Failed Password Attempts - Check integrity of authselect
        current profile
      ansible.builtin.command:
        cmd: authselect check
      register: result_authselect_check_cmd
      changed_when: false
      check_mode: false
      failed_when: false

    - name: Lock Accounts After Failed Password Attempts - Informative message based
        on the authselect integrity check result
      ansible.builtin.assert:
        that:
        - ansible_check_mode or result_authselect_check_cmd.rc == 0
        fail_msg:
        - authselect integrity check failed. Remediation aborted!
        - This remediation could not be applied because an authselect profile was
          not selected or the selected profile is not intact.
        - It is not recommended to manually edit the PAM files when authselect tool
          is available.
        - In cases where the default authselect profile does not cover a specific
          demand, a custom authselect profile is recommended.
        success_msg:
        - authselect integrity check passed

    - name: Lock Accounts After Failed Password Attempts - Get authselect current
        features
      ansible.builtin.shell:
        cmd: authselect current | tail -n+3 | awk '{ print $2 }'
      register: result_authselect_features
      changed_when: false
      check_mode: false
      when:
      - result_authselect_check_cmd is success

    - name: Lock Accounts After Failed Password Attempts - Ensure "with-faillock"
        feature is enabled using authselect tool
      ansible.builtin.command:
        cmd: authselect enable-feature with-faillock
      register: result_authselect_enable_feature_cmd
      when:
      - result_authselect_check_cmd is success
      - result_authselect_features.stdout is not search("with-faillock")

    - name: Lock Accounts After Failed Password Attempts - Ensure authselect changes
        are applied
      ansible.builtin.command:
        cmd: authselect apply-changes -b
      when:
      - result_authselect_enable_feature_cmd is not skipped
      - result_authselect_enable_feature_cmd is success
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    - result_authselect_present.stat.exists
    tags:
    - CJIS-5.5.3
    - DISA-STIG-RHEL-08-020011
    - NIST-800-171-3.1.8
    - NIST-800-53-AC-7(a)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-8.1.6
    - PCI-DSSv4-8.3
    - PCI-DSSv4-8.3.4
    - accounts_passwords_pam_faillock_deny
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Lock Accounts After Failed Password Attempts - Remediation where authselect
      tool is not present
    block:

    - name: Lock Accounts After Failed Password Attempts - Check if pam_faillock.so
        is already enabled
      ansible.builtin.lineinfile:
        path: /etc/pam.d/system-auth
        regexp: .*auth.*pam_faillock\.so (preauth|authfail)
        state: absent
      check_mode: true
      changed_when: false
      register: result_pam_faillock_is_enabled

    - name: Lock Accounts After Failed Password Attempts - Enable pam_faillock.so
        preauth editing PAM files
      ansible.builtin.lineinfile:
        path: '{{ item }}'
        line: auth        required      pam_faillock.so preauth
        insertbefore: ^auth.*sufficient.*pam_unix\.so.*
        state: present
      loop:
      - /etc/pam.d/system-auth
      - /etc/pam.d/password-auth
      when:
      - result_pam_faillock_is_enabled.found == 0

    - name: Lock Accounts After Failed Password Attempts - Enable pam_faillock.so
        authfail editing PAM files
      ansible.builtin.lineinfile:
        path: '{{ item }}'
        line: auth        required      pam_faillock.so authfail
        insertbefore: ^auth.*required.*pam_deny\.so.*
        state: present
      loop:
      - /etc/pam.d/system-auth
      - /etc/pam.d/password-auth
      when:
      - result_pam_faillock_is_enabled.found == 0

    - name: Lock Accounts After Failed Password Attempts - Enable pam_faillock.so
        account section editing PAM files
      ansible.builtin.lineinfile:
        path: '{{ item }}'
        line: account     required      pam_faillock.so
        insertbefore: ^account.*required.*pam_unix\.so.*
        state: present
      loop:
      - /etc/pam.d/system-auth
      - /etc/pam.d/password-auth
      when:
      - result_pam_faillock_is_enabled.found == 0
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    - not result_authselect_present.stat.exists
    tags:
    - CJIS-5.5.3
    - DISA-STIG-RHEL-08-020011
    - NIST-800-171-3.1.8
    - NIST-800-53-AC-7(a)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-8.1.6
    - PCI-DSSv4-8.3
    - PCI-DSSv4-8.3.4
    - accounts_passwords_pam_faillock_deny
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Lock Accounts After Failed Password Attempts - Check the presence of /etc/security/faillock.conf
      file
    ansible.builtin.stat:
      path: /etc/security/faillock.conf
    register: result_faillock_conf_check
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    tags:
    - CJIS-5.5.3
    - DISA-STIG-RHEL-08-020011
    - NIST-800-171-3.1.8
    - NIST-800-53-AC-7(a)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-8.1.6
    - PCI-DSSv4-8.3
    - PCI-DSSv4-8.3.4
    - accounts_passwords_pam_faillock_deny
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Lock Accounts After Failed Password Attempts - Ensure the pam_faillock.so
      deny parameter in /etc/security/faillock.conf
    ansible.builtin.lineinfile:
      path: /etc/security/faillock.conf
      regexp: ^\s*deny\s*=
      line: deny = {{ var_accounts_passwords_pam_faillock_deny }}
      state: present
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    - result_faillock_conf_check.stat.exists
    tags:
    - CJIS-5.5.3
    - DISA-STIG-RHEL-08-020011
    - NIST-800-171-3.1.8
    - NIST-800-53-AC-7(a)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-8.1.6
    - PCI-DSSv4-8.3
    - PCI-DSSv4-8.3.4
    - accounts_passwords_pam_faillock_deny
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Lock Accounts After Failed Password Attempts - Ensure the pam_faillock.so
      deny parameter not in PAM files
    block:

    - name: Lock Accounts After Failed Password Attempts - Check if /etc/pam.d/system-auth
        file is present
      ansible.builtin.stat:
        path: /etc/pam.d/system-auth
      register: result_pam_auth_file_present

    - name: Lock Accounts After Failed Password Attempts - Check the proper remediation
        for the system
      block:

      - name: Lock Accounts After Failed Password Attempts - Define the PAM file to
          be edited as a local fact
        ansible.builtin.set_fact:
          pam_file_path: /etc/pam.d/system-auth

      - name: Lock Accounts After Failed Password Attempts - Check if system relies
          on authselect tool
        ansible.builtin.stat:
          path: /usr/bin/authselect
        register: result_authselect_present

      - name: Lock Accounts After Failed Password Attempts - Ensure authselect custom
          profile is used if authselect is present
        block:

        - name: Lock Accounts After Failed Password Attempts - Check integrity of
            authselect current profile
          ansible.builtin.command:
            cmd: authselect check
          register: result_authselect_check_cmd
          changed_when: false
          check_mode: false
          failed_when: false

        - name: Lock Accounts After Failed Password Attempts - Informative message
            based on the authselect integrity check result
          ansible.builtin.assert:
            that:
            - ansible_check_mode or result_authselect_check_cmd.rc == 0
            fail_msg:
            - authselect integrity check failed. Remediation aborted!
            - This remediation could not be applied because an authselect profile
              was not selected or the selected profile is not intact.
            - It is not recommended to manually edit the PAM files when authselect
              tool is available.
            - In cases where the default authselect profile does not cover a specific
              demand, a custom authselect profile is recommended.
            success_msg:
            - authselect integrity check passed

        - name: Lock Accounts After Failed Password Attempts - Get authselect current
            profile
          ansible.builtin.shell:
            cmd: authselect current -r | awk '{ print $1 }'
          register: result_authselect_profile
          changed_when: false
          when:
          - result_authselect_check_cmd is success

        - name: Lock Accounts After Failed Password Attempts - Define the current
            authselect profile as a local fact
          ansible.builtin.set_fact:
            authselect_current_profile: '{{ result_authselect_profile.stdout }}'
            authselect_custom_profile: '{{ result_authselect_profile.stdout }}'
          when:
          - result_authselect_profile is not skipped
          - result_authselect_profile.stdout is match("custom/")

        - name: Lock Accounts After Failed Password Attempts - Define the new authselect
            custom profile as a local fact
          ansible.builtin.set_fact:
            authselect_current_profile: '{{ result_authselect_profile.stdout }}'
            authselect_custom_profile: custom/hardening
          when:
          - result_authselect_profile is not skipped
          - result_authselect_profile.stdout is not match("custom/")

        - name: Lock Accounts After Failed Password Attempts - Get authselect current
            features to also enable them in the custom profile
          ansible.builtin.shell:
            cmd: authselect current | tail -n+3 | awk '{ print $2 }'
          register: result_authselect_features
          changed_when: false
          check_mode: false
          when:
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")

        - name: Lock Accounts After Failed Password Attempts - Check if any custom
            profile with the same name was already created
          ansible.builtin.stat:
            path: /etc/authselect/{{ authselect_custom_profile }}
          register: result_authselect_custom_profile_present
          changed_when: false
          when:
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")

        - name: Lock Accounts After Failed Password Attempts - Create an authselect
            custom profile based on the current profile
          ansible.builtin.command:
            cmd: authselect create-profile hardening -b {{ authselect_current_profile
              }}
          when:
          - result_authselect_profile is not skipped
          - result_authselect_check_cmd is success
          - authselect_current_profile is not match("^(custom/|local)")
          - not result_authselect_custom_profile_present.stat.exists

        - name: Lock Accounts After Failed Password Attempts - Create an authselect
            custom profile based on sssd profile
          ansible.builtin.command:
            cmd: authselect create-profile hardening -b sssd
          when:
          - result_authselect_profile is not skipped
          - result_authselect_check_cmd is success
          - authselect_current_profile is match("local")
          - not result_authselect_custom_profile_present.stat.exists

        - name: Lock Accounts After Failed Password Attempts - Ensure authselect changes
            are applied
          ansible.builtin.command:
            cmd: authselect apply-changes -b --backup=before-hardening-custom-profile
          when:
          - result_authselect_check_cmd is success
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")
          - authselect_custom_profile is not match(authselect_current_profile)

        - name: Lock Accounts After Failed Password Attempts - Ensure the authselect
            custom profile is selected
          ansible.builtin.command:
            cmd: authselect select {{ authselect_custom_profile }}
          register: result_pam_authselect_select_profile
          when:
          - result_authselect_check_cmd is success
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")
          - authselect_custom_profile is not match(authselect_current_profile)

        - name: Lock Accounts After Failed Password Attempts - Restore the authselect
            features in the custom profile
          ansible.builtin.command:
            cmd: authselect enable-feature {{ item }}
          loop: '{{ result_authselect_features.stdout_lines }}'
          register: result_pam_authselect_restore_features
          when:
          - result_authselect_profile is not skipped
          - result_authselect_features is not skipped
          - result_pam_authselect_select_profile is not skipped

        - name: Lock Accounts After Failed Password Attempts - Ensure authselect changes
            are applied
          ansible.builtin.command:
            cmd: authselect apply-changes -b --backup=after-hardening-custom-profile
          when:
          - result_authselect_check_cmd is success
          - result_authselect_profile is not skipped
          - result_pam_authselect_restore_features is not skipped

        - name: Lock Accounts After Failed Password Attempts - Change the PAM file
            to be edited according to the custom authselect profile
          ansible.builtin.set_fact:
            pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path
              | basename }}
          when:
          - authselect_custom_profile is defined
        when:
        - result_authselect_present.stat.exists

      - name: Lock Accounts After Failed Password Attempts - Define a fact for control
          already filtered in case filters are used
        ansible.builtin.set_fact:
          pam_module_control: ''

      - name: Lock Accounts After Failed Password Attempts - Check if {{ pam_file_path
          }} file is present
        ansible.builtin.stat:
          path: '{{ pam_file_path }}'
        register: result_pam_file_present

      - name: Lock Accounts After Failed Password Attempts - Ensure the "deny" option
          from "pam_faillock.so" is not present in {{ pam_file_path }}
        ansible.builtin.replace:
          dest: '{{ pam_file_path }}'
          regexp: (.*auth.*pam_faillock.so.*)\bdeny\b=?[0-9a-zA-Z]*(.*)
          replace: \1\2
        register: result_pam_option_removal
        when:
        - result_pam_file_present.stat.exists

      - name: Lock Accounts After Failed Password Attempts - Ensure authselect changes
          are applied
        ansible.builtin.command:
          cmd: authselect apply-changes -b
        when:
        - result_authselect_present.stat.exists
        - result_pam_option_removal is changed
      when:
      - result_pam_auth_file_present.stat.exists

    - name: Lock Accounts After Failed Password Attempts - Check if /etc/pam.d/password-auth
        file is present
      ansible.builtin.stat:
        path: /etc/pam.d/password-auth
      register: result_pam_password_auth_file_present

    - name: Lock Accounts After Failed Password Attempts - Check the proper remediation
        for the system
      block:

      - name: Lock Accounts After Failed Password Attempts - Define the PAM file to
          be edited as a local fact
        ansible.builtin.set_fact:
          pam_file_path: /etc/pam.d/password-auth

      - name: Lock Accounts After Failed Password Attempts - Check if system relies
          on authselect tool
        ansible.builtin.stat:
          path: /usr/bin/authselect
        register: result_authselect_present

      - name: Lock Accounts After Failed Password Attempts - Ensure authselect custom
          profile is used if authselect is present
        block:

        - name: Lock Accounts After Failed Password Attempts - Check integrity of
            authselect current profile
          ansible.builtin.command:
            cmd: authselect check
          register: result_authselect_check_cmd
          changed_when: false
          check_mode: false
          failed_when: false

        - name: Lock Accounts After Failed Password Attempts - Informative message
            based on the authselect integrity check result
          ansible.builtin.assert:
            that:
            - ansible_check_mode or result_authselect_check_cmd.rc == 0
            fail_msg:
            - authselect integrity check failed. Remediation aborted!
            - This remediation could not be applied because an authselect profile
              was not selected or the selected profile is not intact.
            - It is not recommended to manually edit the PAM files when authselect
              tool is available.
            - In cases where the default authselect profile does not cover a specific
              demand, a custom authselect profile is recommended.
            success_msg:
            - authselect integrity check passed

        - name: Lock Accounts After Failed Password Attempts - Get authselect current
            profile
          ansible.builtin.shell:
            cmd: authselect current -r | awk '{ print $1 }'
          register: result_authselect_profile
          changed_when: false
          when:
          - result_authselect_check_cmd is success

        - name: Lock Accounts After Failed Password Attempts - Define the current
            authselect profile as a local fact
          ansible.builtin.set_fact:
            authselect_current_profile: '{{ result_authselect_profile.stdout }}'
            authselect_custom_profile: '{{ result_authselect_profile.stdout }}'
          when:
          - result_authselect_profile is not skipped
          - result_authselect_profile.stdout is match("custom/")

        - name: Lock Accounts After Failed Password Attempts - Define the new authselect
            custom profile as a local fact
          ansible.builtin.set_fact:
            authselect_current_profile: '{{ result_authselect_profile.stdout }}'
            authselect_custom_profile: custom/hardening
          when:
          - result_authselect_profile is not skipped
          - result_authselect_profile.stdout is not match("custom/")

        - name: Lock Accounts After Failed Password Attempts - Get authselect current
            features to also enable them in the custom profile
          ansible.builtin.shell:
            cmd: authselect current | tail -n+3 | awk '{ print $2 }'
          register: result_authselect_features
          changed_when: false
          check_mode: false
          when:
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")

        - name: Lock Accounts After Failed Password Attempts - Check if any custom
            profile with the same name was already created
          ansible.builtin.stat:
            path: /etc/authselect/{{ authselect_custom_profile }}
          register: result_authselect_custom_profile_present
          changed_when: false
          when:
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")

        - name: Lock Accounts After Failed Password Attempts - Create an authselect
            custom profile based on the current profile
          ansible.builtin.command:
            cmd: authselect create-profile hardening -b {{ authselect_current_profile
              }}
          when:
          - result_authselect_profile is not skipped
          - result_authselect_check_cmd is success
          - authselect_current_profile is not match("^(custom/|local)")
          - not result_authselect_custom_profile_present.stat.exists

        - name: Lock Accounts After Failed Password Attempts - Create an authselect
            custom profile based on sssd profile
          ansible.builtin.command:
            cmd: authselect create-profile hardening -b sssd
          when:
          - result_authselect_profile is not skipped
          - result_authselect_check_cmd is success
          - authselect_current_profile is match("local")
          - not result_authselect_custom_profile_present.stat.exists

        - name: Lock Accounts After Failed Password Attempts - Ensure authselect changes
            are applied
          ansible.builtin.command:
            cmd: authselect apply-changes -b --backup=before-hardening-custom-profile
          when:
          - result_authselect_check_cmd is success
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")
          - authselect_custom_profile is not match(authselect_current_profile)

        - name: Lock Accounts After Failed Password Attempts - Ensure the authselect
            custom profile is selected
          ansible.builtin.command:
            cmd: authselect select {{ authselect_custom_profile }}
          register: result_pam_authselect_select_profile
          when:
          - result_authselect_check_cmd is success
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")
          - authselect_custom_profile is not match(authselect_current_profile)

        - name: Lock Accounts After Failed Password Attempts - Restore the authselect
            features in the custom profile
          ansible.builtin.command:
            cmd: authselect enable-feature {{ item }}
          loop: '{{ result_authselect_features.stdout_lines }}'
          register: result_pam_authselect_restore_features
          when:
          - result_authselect_profile is not skipped
          - result_authselect_features is not skipped
          - result_pam_authselect_select_profile is not skipped

        - name: Lock Accounts After Failed Password Attempts - Ensure authselect changes
            are applied
          ansible.builtin.command:
            cmd: authselect apply-changes -b --backup=after-hardening-custom-profile
          when:
          - result_authselect_check_cmd is success
          - result_authselect_profile is not skipped
          - result_pam_authselect_restore_features is not skipped

        - name: Lock Accounts After Failed Password Attempts - Change the PAM file
            to be edited according to the custom authselect profile
          ansible.builtin.set_fact:
            pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path
              | basename }}
          when:
          - authselect_custom_profile is defined
        when:
        - result_authselect_present.stat.exists

      - name: Lock Accounts After Failed Password Attempts - Define a fact for control
          already filtered in case filters are used
        ansible.builtin.set_fact:
          pam_module_control: ''

      - name: Lock Accounts After Failed Password Attempts - Check if {{ pam_file_path
          }} file is present
        ansible.builtin.stat:
          path: '{{ pam_file_path }}'
        register: result_pam_file_present

      - name: Lock Accounts After Failed Password Attempts - Ensure the "deny" option
          from "pam_faillock.so" is not present in {{ pam_file_path }}
        ansible.builtin.replace:
          dest: '{{ pam_file_path }}'
          regexp: (.*auth.*pam_faillock.so.*)\bdeny\b=?[0-9a-zA-Z]*(.*)
          replace: \1\2
        register: result_pam_option_removal
        when:
        - result_pam_file_present.stat.exists

      - name: Lock Accounts After Failed Password Attempts - Ensure authselect changes
          are applied
        ansible.builtin.command:
          cmd: authselect apply-changes -b
        when:
        - result_authselect_present.stat.exists
        - result_pam_option_removal is changed
      when:
      - result_pam_password_auth_file_present.stat.exists
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    - result_faillock_conf_check.stat.exists
    tags:
    - CJIS-5.5.3
    - DISA-STIG-RHEL-08-020011
    - NIST-800-171-3.1.8
    - NIST-800-53-AC-7(a)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-8.1.6
    - PCI-DSSv4-8.3
    - PCI-DSSv4-8.3.4
    - accounts_passwords_pam_faillock_deny
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Lock Accounts After Failed Password Attempts - Ensure the pam_faillock.so
      deny parameter in PAM files
    block:

    - name: Lock Accounts After Failed Password Attempts - Check if pam_faillock.so
        deny parameter is already enabled in pam files
      ansible.builtin.lineinfile:
        path: /etc/pam.d/system-auth
        regexp: .*auth.*pam_faillock\.so (preauth|authfail).*deny
        state: absent
      check_mode: true
      changed_when: false
      register: result_pam_faillock_deny_parameter_is_present

    - name: Lock Accounts After Failed Password Attempts - Ensure the inclusion of
        pam_faillock.so preauth deny parameter in auth section
      ansible.builtin.lineinfile:
        path: '{{ item }}'
        backrefs: true
        regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so preauth.*)
        line: \1required\3 deny={{ var_accounts_passwords_pam_faillock_deny }}
        state: present
      loop:
      - /etc/pam.d/system-auth
      - /etc/pam.d/password-auth
      when:
      - result_pam_faillock_deny_parameter_is_present.found == 0

    - name: Lock Accounts After Failed Password Attempts - Ensure the inclusion of
        pam_faillock.so authfail deny parameter in auth section
      ansible.builtin.lineinfile:
        path: '{{ item }}'
        backrefs: true
        regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so authfail.*)
        line: \1required\3 deny={{ var_accounts_passwords_pam_faillock_deny }}
        state: present
      loop:
      - /etc/pam.d/system-auth
      - /etc/pam.d/password-auth
      when:
      - result_pam_faillock_deny_parameter_is_present.found == 0

    - name: Lock Accounts After Failed Password Attempts - Ensure the desired value
        for pam_faillock.so preauth deny parameter in auth section
      ansible.builtin.lineinfile:
        path: '{{ item }}'
        backrefs: true
        regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so preauth.*)(deny)=[0-9]+(.*)
        line: \1required\3\4={{ var_accounts_passwords_pam_faillock_deny }}\5
        state: present
      loop:
      - /etc/pam.d/system-auth
      - /etc/pam.d/password-auth
      when:
      - result_pam_faillock_deny_parameter_is_present.found > 0

    - name: Lock Accounts After Failed Password Attempts - Ensure the desired value
        for pam_faillock.so authfail deny parameter in auth section
      ansible.builtin.lineinfile:
        path: '{{ item }}'
        backrefs: true
        regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so authfail.*)(deny)=[0-9]+(.*)
        line: \1required\3\4={{ var_accounts_passwords_pam_faillock_deny }}\5
        state: present
      loop:
      - /etc/pam.d/system-auth
      - /etc/pam.d/password-auth
      when:
      - result_pam_faillock_deny_parameter_is_present.found > 0
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    - not result_faillock_conf_check.stat.exists
    tags:
    - CJIS-5.5.3
    - DISA-STIG-RHEL-08-020011
    - NIST-800-171-3.1.8
    - NIST-800-53-AC-7(a)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-8.1.6
    - PCI-DSSv4-8.3
    - PCI-DSSv4-8.3.4
    - accounts_passwords_pam_faillock_deny
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure Root Account Lockout on Failed Password Attempts - Check if system
      relies on authselect tool
    ansible.builtin.stat:
      path: /usr/bin/authselect
    register: result_authselect_present
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    tags:
    - accounts_passwords_pam_faillock_even_deny_root_or_root_unlock_time
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure Root Account Lockout on Failed Password Attempts - Remediation where
      authselect tool is present
    block:

    - name: Ensure Root Account Lockout on Failed Password Attempts - Check integrity
        of authselect current profile
      ansible.builtin.command:
        cmd: authselect check
      register: result_authselect_check_cmd
      changed_when: false
      check_mode: false
      failed_when: false

    - name: Ensure Root Account Lockout on Failed Password Attempts - Informative
        message based on the authselect integrity check result
      ansible.builtin.assert:
        that:
        - ansible_check_mode or result_authselect_check_cmd.rc == 0
        fail_msg:
        - authselect integrity check failed. Remediation aborted!
        - This remediation could not be applied because an authselect profile was
          not selected or the selected profile is not intact.
        - It is not recommended to manually edit the PAM files when authselect tool
          is available.
        - In cases where the default authselect profile does not cover a specific
          demand, a custom authselect profile is recommended.
        success_msg:
        - authselect integrity check passed

    - name: Ensure Root Account Lockout on Failed Password Attempts - Get authselect
        current features
      ansible.builtin.shell:
        cmd: authselect current | tail -n+3 | awk '{ print $2 }'
      register: result_authselect_features
      changed_when: false
      check_mode: false
      when:
      - result_authselect_check_cmd is success

    - name: Ensure Root Account Lockout on Failed Password Attempts - Ensure "with-faillock"
        feature is enabled using authselect tool
      ansible.builtin.command:
        cmd: authselect enable-feature with-faillock
      register: result_authselect_enable_feature_cmd
      when:
      - result_authselect_check_cmd is success
      - result_authselect_features.stdout is not search("with-faillock")

    - name: Ensure Root Account Lockout on Failed Password Attempts - Ensure authselect
        changes are applied
      ansible.builtin.command:
        cmd: authselect apply-changes -b
      when:
      - result_authselect_enable_feature_cmd is not skipped
      - result_authselect_enable_feature_cmd is success
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    - result_authselect_present.stat.exists
    tags:
    - accounts_passwords_pam_faillock_even_deny_root_or_root_unlock_time
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure Root Account Lockout on Failed Password Attempts - Remediation where
      authselect tool is not present
    block:

    - name: Ensure Root Account Lockout on Failed Password Attempts - Check if pam_faillock.so
        is already enabled
      ansible.builtin.lineinfile:
        path: /etc/pam.d/system-auth
        regexp: .*auth.*pam_faillock\.so (preauth|authfail)
        state: absent
      check_mode: true
      changed_when: false
      register: result_pam_faillock_is_enabled

    - name: Ensure Root Account Lockout on Failed Password Attempts - Enable pam_faillock.so
        preauth editing PAM files
      ansible.builtin.lineinfile:
        path: '{{ item }}'
        line: auth        required      pam_faillock.so preauth
        insertbefore: ^auth.*sufficient.*pam_unix\.so.*
        state: present
      loop:
      - /etc/pam.d/system-auth
      - /etc/pam.d/password-auth
      when:
      - result_pam_faillock_is_enabled.found == 0

    - name: Ensure Root Account Lockout on Failed Password Attempts - Enable pam_faillock.so
        authfail editing PAM files
      ansible.builtin.lineinfile:
        path: '{{ item }}'
        line: auth        required      pam_faillock.so authfail
        insertbefore: ^auth.*required.*pam_deny\.so.*
        state: present
      loop:
      - /etc/pam.d/system-auth
      - /etc/pam.d/password-auth
      when:
      - result_pam_faillock_is_enabled.found == 0

    - name: Ensure Root Account Lockout on Failed Password Attempts - Enable pam_faillock.so
        account section editing PAM files
      ansible.builtin.lineinfile:
        path: '{{ item }}'
        line: account     required      pam_faillock.so
        insertbefore: ^account.*required.*pam_unix\.so.*
        state: present
      loop:
      - /etc/pam.d/system-auth
      - /etc/pam.d/password-auth
      when:
      - result_pam_faillock_is_enabled.found == 0
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    - not result_authselect_present.stat.exists
    tags:
    - accounts_passwords_pam_faillock_even_deny_root_or_root_unlock_time
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure Root Account Lockout on Failed Password Attempts - Check the presence
      of /etc/security/faillock.conf file
    ansible.builtin.stat:
      path: /etc/security/faillock.conf
    register: result_faillock_conf_check
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    tags:
    - accounts_passwords_pam_faillock_even_deny_root_or_root_unlock_time
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure Root Account Lockout on Failed Password Attempts - Ensure the pam_faillock.so
      even_deny_root parameter in /etc/security/faillock.conf
    ansible.builtin.lineinfile:
      path: /etc/security/faillock.conf
      regexp: ^\s*even_deny_root
      line: even_deny_root
      state: present
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    - result_faillock_conf_check.stat.exists
    tags:
    - accounts_passwords_pam_faillock_even_deny_root_or_root_unlock_time
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure Root Account Lockout on Failed Password Attempts - Ensure the pam_faillock.so
      even_deny_root parameter not in PAM files
    block:

    - name: Ensure Root Account Lockout on Failed Password Attempts - Check if /etc/pam.d/system-auth
        file is present
      ansible.builtin.stat:
        path: /etc/pam.d/system-auth
      register: result_pam_auth_file_present

    - name: Ensure Root Account Lockout on Failed Password Attempts - Check the proper
        remediation for the system
      block:

      - name: Ensure Root Account Lockout on Failed Password Attempts - Define the
          PAM file to be edited as a local fact
        ansible.builtin.set_fact:
          pam_file_path: /etc/pam.d/system-auth

      - name: Ensure Root Account Lockout on Failed Password Attempts - Check if system
          relies on authselect tool
        ansible.builtin.stat:
          path: /usr/bin/authselect
        register: result_authselect_present

      - name: Ensure Root Account Lockout on Failed Password Attempts - Ensure authselect
          custom profile is used if authselect is present
        block:

        - name: Ensure Root Account Lockout on Failed Password Attempts - Check integrity
            of authselect current profile
          ansible.builtin.command:
            cmd: authselect check
          register: result_authselect_check_cmd
          changed_when: false
          check_mode: false
          failed_when: false

        - name: Ensure Root Account Lockout on Failed Password Attempts - Informative
            message based on the authselect integrity check result
          ansible.builtin.assert:
            that:
            - ansible_check_mode or result_authselect_check_cmd.rc == 0
            fail_msg:
            - authselect integrity check failed. Remediation aborted!
            - This remediation could not be applied because an authselect profile
              was not selected or the selected profile is not intact.
            - It is not recommended to manually edit the PAM files when authselect
              tool is available.
            - In cases where the default authselect profile does not cover a specific
              demand, a custom authselect profile is recommended.
            success_msg:
            - authselect integrity check passed

        - name: Ensure Root Account Lockout on Failed Password Attempts - Get authselect
            current profile
          ansible.builtin.shell:
            cmd: authselect current -r | awk '{ print $1 }'
          register: result_authselect_profile
          changed_when: false
          when:
          - result_authselect_check_cmd is success

        - name: Ensure Root Account Lockout on Failed Password Attempts - Define the
            current authselect profile as a local fact
          ansible.builtin.set_fact:
            authselect_current_profile: '{{ result_authselect_profile.stdout }}'
            authselect_custom_profile: '{{ result_authselect_profile.stdout }}'
          when:
          - result_authselect_profile is not skipped
          - result_authselect_profile.stdout is match("custom/")

        - name: Ensure Root Account Lockout on Failed Password Attempts - Define the
            new authselect custom profile as a local fact
          ansible.builtin.set_fact:
            authselect_current_profile: '{{ result_authselect_profile.stdout }}'
            authselect_custom_profile: custom/hardening
          when:
          - result_authselect_profile is not skipped
          - result_authselect_profile.stdout is not match("custom/")

        - name: Ensure Root Account Lockout on Failed Password Attempts - Get authselect
            current features to also enable them in the custom profile
          ansible.builtin.shell:
            cmd: authselect current | tail -n+3 | awk '{ print $2 }'
          register: result_authselect_features
          changed_when: false
          check_mode: false
          when:
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")

        - name: Ensure Root Account Lockout on Failed Password Attempts - Check if
            any custom profile with the same name was already created
          ansible.builtin.stat:
            path: /etc/authselect/{{ authselect_custom_profile }}
          register: result_authselect_custom_profile_present
          changed_when: false
          when:
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")

        - name: Ensure Root Account Lockout on Failed Password Attempts - Create an
            authselect custom profile based on the current profile
          ansible.builtin.command:
            cmd: authselect create-profile hardening -b {{ authselect_current_profile
              }}
          when:
          - result_authselect_profile is not skipped
          - result_authselect_check_cmd is success
          - authselect_current_profile is not match("^(custom/|local)")
          - not result_authselect_custom_profile_present.stat.exists

        - name: Ensure Root Account Lockout on Failed Password Attempts - Create an
            authselect custom profile based on sssd profile
          ansible.builtin.command:
            cmd: authselect create-profile hardening -b sssd
          when:
          - result_authselect_profile is not skipped
          - result_authselect_check_cmd is success
          - authselect_current_profile is match("local")
          - not result_authselect_custom_profile_present.stat.exists

        - name: Ensure Root Account Lockout on Failed Password Attempts - Ensure authselect
            changes are applied
          ansible.builtin.command:
            cmd: authselect apply-changes -b --backup=before-hardening-custom-profile
          when:
          - result_authselect_check_cmd is success
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")
          - authselect_custom_profile is not match(authselect_current_profile)

        - name: Ensure Root Account Lockout on Failed Password Attempts - Ensure the
            authselect custom profile is selected
          ansible.builtin.command:
            cmd: authselect select {{ authselect_custom_profile }}
          register: result_pam_authselect_select_profile
          when:
          - result_authselect_check_cmd is success
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")
          - authselect_custom_profile is not match(authselect_current_profile)

        - name: Ensure Root Account Lockout on Failed Password Attempts - Restore
            the authselect features in the custom profile
          ansible.builtin.command:
            cmd: authselect enable-feature {{ item }}
          loop: '{{ result_authselect_features.stdout_lines }}'
          register: result_pam_authselect_restore_features
          when:
          - result_authselect_profile is not skipped
          - result_authselect_features is not skipped
          - result_pam_authselect_select_profile is not skipped

        - name: Ensure Root Account Lockout on Failed Password Attempts - Ensure authselect
            changes are applied
          ansible.builtin.command:
            cmd: authselect apply-changes -b --backup=after-hardening-custom-profile
          when:
          - result_authselect_check_cmd is success
          - result_authselect_profile is not skipped
          - result_pam_authselect_restore_features is not skipped

        - name: Ensure Root Account Lockout on Failed Password Attempts - Change the
            PAM file to be edited according to the custom authselect profile
          ansible.builtin.set_fact:
            pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path
              | basename }}
          when:
          - authselect_custom_profile is defined
        when:
        - result_authselect_present.stat.exists

      - name: Ensure Root Account Lockout on Failed Password Attempts - Define a fact
          for control already filtered in case filters are used
        ansible.builtin.set_fact:
          pam_module_control: ''

      - name: Ensure Root Account Lockout on Failed Password Attempts - Check if {{
          pam_file_path }} file is present
        ansible.builtin.stat:
          path: '{{ pam_file_path }}'
        register: result_pam_file_present

      - name: Ensure Root Account Lockout on Failed Password Attempts - Ensure the
          "even_deny_root" option from "pam_faillock.so" is not present in {{ pam_file_path
          }}
        ansible.builtin.replace:
          dest: '{{ pam_file_path }}'
          regexp: (.*auth.*pam_faillock.so.*)\beven_deny_root\b=?[0-9a-zA-Z]*(.*)
          replace: \1\2
        register: result_pam_option_removal
        when:
        - result_pam_file_present.stat.exists

      - name: Ensure Root Account Lockout on Failed Password Attempts - Ensure authselect
          changes are applied
        ansible.builtin.command:
          cmd: authselect apply-changes -b
        when:
        - result_authselect_present.stat.exists
        - result_pam_option_removal is changed
      when:
      - result_pam_auth_file_present.stat.exists

    - name: Ensure Root Account Lockout on Failed Password Attempts - Check if /etc/pam.d/password-auth
        file is present
      ansible.builtin.stat:
        path: /etc/pam.d/password-auth
      register: result_pam_password_auth_file_present

    - name: Ensure Root Account Lockout on Failed Password Attempts - Check the proper
        remediation for the system
      block:

      - name: Ensure Root Account Lockout on Failed Password Attempts - Define the
          PAM file to be edited as a local fact
        ansible.builtin.set_fact:
          pam_file_path: /etc/pam.d/password-auth

      - name: Ensure Root Account Lockout on Failed Password Attempts - Check if system
          relies on authselect tool
        ansible.builtin.stat:
          path: /usr/bin/authselect
        register: result_authselect_present

      - name: Ensure Root Account Lockout on Failed Password Attempts - Ensure authselect
          custom profile is used if authselect is present
        block:

        - name: Ensure Root Account Lockout on Failed Password Attempts - Check integrity
            of authselect current profile
          ansible.builtin.command:
            cmd: authselect check
          register: result_authselect_check_cmd
          changed_when: false
          check_mode: false
          failed_when: false

        - name: Ensure Root Account Lockout on Failed Password Attempts - Informative
            message based on the authselect integrity check result
          ansible.builtin.assert:
            that:
            - ansible_check_mode or result_authselect_check_cmd.rc == 0
            fail_msg:
            - authselect integrity check failed. Remediation aborted!
            - This remediation could not be applied because an authselect profile
              was not selected or the selected profile is not intact.
            - It is not recommended to manually edit the PAM files when authselect
              tool is available.
            - In cases where the default authselect profile does not cover a specific
              demand, a custom authselect profile is recommended.
            success_msg:
            - authselect integrity check passed

        - name: Ensure Root Account Lockout on Failed Password Attempts - Get authselect
            current profile
          ansible.builtin.shell:
            cmd: authselect current -r | awk '{ print $1 }'
          register: result_authselect_profile
          changed_when: false
          when:
          - result_authselect_check_cmd is success

        - name: Ensure Root Account Lockout on Failed Password Attempts - Define the
            current authselect profile as a local fact
          ansible.builtin.set_fact:
            authselect_current_profile: '{{ result_authselect_profile.stdout }}'
            authselect_custom_profile: '{{ result_authselect_profile.stdout }}'
          when:
          - result_authselect_profile is not skipped
          - result_authselect_profile.stdout is match("custom/")

        - name: Ensure Root Account Lockout on Failed Password Attempts - Define the
            new authselect custom profile as a local fact
          ansible.builtin.set_fact:
            authselect_current_profile: '{{ result_authselect_profile.stdout }}'
            authselect_custom_profile: custom/hardening
          when:
          - result_authselect_profile is not skipped
          - result_authselect_profile.stdout is not match("custom/")

        - name: Ensure Root Account Lockout on Failed Password Attempts - Get authselect
            current features to also enable them in the custom profile
          ansible.builtin.shell:
            cmd: authselect current | tail -n+3 | awk '{ print $2 }'
          register: result_authselect_features
          changed_when: false
          check_mode: false
          when:
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")

        - name: Ensure Root Account Lockout on Failed Password Attempts - Check if
            any custom profile with the same name was already created
          ansible.builtin.stat:
            path: /etc/authselect/{{ authselect_custom_profile }}
          register: result_authselect_custom_profile_present
          changed_when: false
          when:
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")

        - name: Ensure Root Account Lockout on Failed Password Attempts - Create an
            authselect custom profile based on the current profile
          ansible.builtin.command:
            cmd: authselect create-profile hardening -b {{ authselect_current_profile
              }}
          when:
          - result_authselect_profile is not skipped
          - result_authselect_check_cmd is success
          - authselect_current_profile is not match("^(custom/|local)")
          - not result_authselect_custom_profile_present.stat.exists

        - name: Ensure Root Account Lockout on Failed Password Attempts - Create an
            authselect custom profile based on sssd profile
          ansible.builtin.command:
            cmd: authselect create-profile hardening -b sssd
          when:
          - result_authselect_profile is not skipped
          - result_authselect_check_cmd is success
          - authselect_current_profile is match("local")
          - not result_authselect_custom_profile_present.stat.exists

        - name: Ensure Root Account Lockout on Failed Password Attempts - Ensure authselect
            changes are applied
          ansible.builtin.command:
            cmd: authselect apply-changes -b --backup=before-hardening-custom-profile
          when:
          - result_authselect_check_cmd is success
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")
          - authselect_custom_profile is not match(authselect_current_profile)

        - name: Ensure Root Account Lockout on Failed Password Attempts - Ensure the
            authselect custom profile is selected
          ansible.builtin.command:
            cmd: authselect select {{ authselect_custom_profile }}
          register: result_pam_authselect_select_profile
          when:
          - result_authselect_check_cmd is success
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")
          - authselect_custom_profile is not match(authselect_current_profile)

        - name: Ensure Root Account Lockout on Failed Password Attempts - Restore
            the authselect features in the custom profile
          ansible.builtin.command:
            cmd: authselect enable-feature {{ item }}
          loop: '{{ result_authselect_features.stdout_lines }}'
          register: result_pam_authselect_restore_features
          when:
          - result_authselect_profile is not skipped
          - result_authselect_features is not skipped
          - result_pam_authselect_select_profile is not skipped

        - name: Ensure Root Account Lockout on Failed Password Attempts - Ensure authselect
            changes are applied
          ansible.builtin.command:
            cmd: authselect apply-changes -b --backup=after-hardening-custom-profile
          when:
          - result_authselect_check_cmd is success
          - result_authselect_profile is not skipped
          - result_pam_authselect_restore_features is not skipped

        - name: Ensure Root Account Lockout on Failed Password Attempts - Change the
            PAM file to be edited according to the custom authselect profile
          ansible.builtin.set_fact:
            pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path
              | basename }}
          when:
          - authselect_custom_profile is defined
        when:
        - result_authselect_present.stat.exists

      - name: Ensure Root Account Lockout on Failed Password Attempts - Define a fact
          for control already filtered in case filters are used
        ansible.builtin.set_fact:
          pam_module_control: ''

      - name: Ensure Root Account Lockout on Failed Password Attempts - Check if {{
          pam_file_path }} file is present
        ansible.builtin.stat:
          path: '{{ pam_file_path }}'
        register: result_pam_file_present

      - name: Ensure Root Account Lockout on Failed Password Attempts - Ensure the
          "even_deny_root" option from "pam_faillock.so" is not present in {{ pam_file_path
          }}
        ansible.builtin.replace:
          dest: '{{ pam_file_path }}'
          regexp: (.*auth.*pam_faillock.so.*)\beven_deny_root\b=?[0-9a-zA-Z]*(.*)
          replace: \1\2
        register: result_pam_option_removal
        when:
        - result_pam_file_present.stat.exists

      - name: Ensure Root Account Lockout on Failed Password Attempts - Ensure authselect
          changes are applied
        ansible.builtin.command:
          cmd: authselect apply-changes -b
        when:
        - result_authselect_present.stat.exists
        - result_pam_option_removal is changed
      when:
      - result_pam_password_auth_file_present.stat.exists
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    - result_faillock_conf_check.stat.exists
    tags:
    - accounts_passwords_pam_faillock_even_deny_root_or_root_unlock_time
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure Root Account Lockout on Failed Password Attempts - Ensure the pam_faillock.so
      even_deny_root parameter in PAM files
    block:

    - name: Ensure Root Account Lockout on Failed Password Attempts - Check if pam_faillock.so
        even_deny_root parameter is already enabled in pam files
      ansible.builtin.lineinfile:
        path: /etc/pam.d/system-auth
        regexp: .*auth.*pam_faillock\.so (preauth|authfail).*even_deny_root
        state: absent
      check_mode: true
      changed_when: false
      register: result_pam_faillock_even_deny_root_parameter_is_present

    - name: Ensure Root Account Lockout on Failed Password Attempts - Ensure the inclusion
        of pam_faillock.so preauth even_deny_root parameter in auth section
      ansible.builtin.lineinfile:
        path: '{{ item }}'
        backrefs: true
        regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so preauth.*)
        line: \1required\3 even_deny_root
        state: present
      loop:
      - /etc/pam.d/system-auth
      - /etc/pam.d/password-auth
      when:
      - result_pam_faillock_even_deny_root_parameter_is_present.found == 0

    - name: Ensure Root Account Lockout on Failed Password Attempts - Ensure the inclusion
        of pam_faillock.so authfail even_deny_root parameter in auth section
      ansible.builtin.lineinfile:
        path: '{{ item }}'
        backrefs: true
        regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so authfail.*)
        line: \1required\3 even_deny_root
        state: present
      loop:
      - /etc/pam.d/system-auth
      - /etc/pam.d/password-auth
      when:
      - result_pam_faillock_even_deny_root_parameter_is_present.found == 0
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    - not result_faillock_conf_check.stat.exists
    tags:
    - accounts_passwords_pam_faillock_even_deny_root_or_root_unlock_time
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Set Lockout Time for Failed Password Attempts - Check if system relies on
      authselect tool
    ansible.builtin.stat:
      path: /usr/bin/authselect
    register: result_authselect_present
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    tags:
    - accounts_passwords_pam_faillock_unlock_time_with_zero
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Set Lockout Time for Failed Password Attempts - Remediation where authselect
      tool is present
    block:

    - name: Set Lockout Time for Failed Password Attempts - Check integrity of authselect
        current profile
      ansible.builtin.command:
        cmd: authselect check
      register: result_authselect_check_cmd
      changed_when: false
      check_mode: false
      failed_when: false

    - name: Set Lockout Time for Failed Password Attempts - Informative message based
        on the authselect integrity check result
      ansible.builtin.assert:
        that:
        - ansible_check_mode or result_authselect_check_cmd.rc == 0
        fail_msg:
        - authselect integrity check failed. Remediation aborted!
        - This remediation could not be applied because an authselect profile was
          not selected or the selected profile is not intact.
        - It is not recommended to manually edit the PAM files when authselect tool
          is available.
        - In cases where the default authselect profile does not cover a specific
          demand, a custom authselect profile is recommended.
        success_msg:
        - authselect integrity check passed

    - name: Set Lockout Time for Failed Password Attempts - Get authselect current
        features
      ansible.builtin.shell:
        cmd: authselect current | tail -n+3 | awk '{ print $2 }'
      register: result_authselect_features
      changed_when: false
      check_mode: false
      when:
      - result_authselect_check_cmd is success

    - name: Set Lockout Time for Failed Password Attempts - Ensure "with-faillock"
        feature is enabled using authselect tool
      ansible.builtin.command:
        cmd: authselect enable-feature with-faillock
      register: result_authselect_enable_feature_cmd
      when:
      - result_authselect_check_cmd is success
      - result_authselect_features.stdout is not search("with-faillock")

    - name: Set Lockout Time for Failed Password Attempts - Ensure authselect changes
        are applied
      ansible.builtin.command:
        cmd: authselect apply-changes -b
      when:
      - result_authselect_enable_feature_cmd is not skipped
      - result_authselect_enable_feature_cmd is success
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    - result_authselect_present.stat.exists
    tags:
    - accounts_passwords_pam_faillock_unlock_time_with_zero
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Set Lockout Time for Failed Password Attempts - Remediation where authselect
      tool is not present
    block:

    - name: Set Lockout Time for Failed Password Attempts - Check if pam_faillock.so
        is already enabled
      ansible.builtin.lineinfile:
        path: /etc/pam.d/system-auth
        regexp: .*auth.*pam_faillock\.so (preauth|authfail)
        state: absent
      check_mode: true
      changed_when: false
      register: result_pam_faillock_is_enabled

    - name: Set Lockout Time for Failed Password Attempts - Enable pam_faillock.so
        preauth editing PAM files
      ansible.builtin.lineinfile:
        path: '{{ item }}'
        line: auth        required      pam_faillock.so preauth
        insertbefore: ^auth.*sufficient.*pam_unix\.so.*
        state: present
      loop:
      - /etc/pam.d/system-auth
      - /etc/pam.d/password-auth
      when:
      - result_pam_faillock_is_enabled.found == 0

    - name: Set Lockout Time for Failed Password Attempts - Enable pam_faillock.so
        authfail editing PAM files
      ansible.builtin.lineinfile:
        path: '{{ item }}'
        line: auth        required      pam_faillock.so authfail
        insertbefore: ^auth.*required.*pam_deny\.so.*
        state: present
      loop:
      - /etc/pam.d/system-auth
      - /etc/pam.d/password-auth
      when:
      - result_pam_faillock_is_enabled.found == 0

    - name: Set Lockout Time for Failed Password Attempts - Enable pam_faillock.so
        account section editing PAM files
      ansible.builtin.lineinfile:
        path: '{{ item }}'
        line: account     required      pam_faillock.so
        insertbefore: ^account.*required.*pam_unix\.so.*
        state: present
      loop:
      - /etc/pam.d/system-auth
      - /etc/pam.d/password-auth
      when:
      - result_pam_faillock_is_enabled.found == 0
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    - not result_authselect_present.stat.exists
    tags:
    - accounts_passwords_pam_faillock_unlock_time_with_zero
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Set Lockout Time for Failed Password Attempts - Check the presence of /etc/security/faillock.conf
      file
    ansible.builtin.stat:
      path: /etc/security/faillock.conf
    register: result_faillock_conf_check
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    tags:
    - accounts_passwords_pam_faillock_unlock_time_with_zero
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Set Lockout Time for Failed Password Attempts - Ensure the pam_faillock.so
      unlock_time parameter in /etc/security/faillock.conf
    ansible.builtin.lineinfile:
      path: /etc/security/faillock.conf
      regexp: ^\s*unlock_time\s*=
      line: unlock_time = {{ var_accounts_passwords_pam_faillock_unlock_time }}
      state: present
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    - result_faillock_conf_check.stat.exists
    tags:
    - accounts_passwords_pam_faillock_unlock_time_with_zero
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Set Lockout Time for Failed Password Attempts - Ensure the pam_faillock.so
      unlock_time parameter not in PAM files
    block:

    - name: Set Lockout Time for Failed Password Attempts - Check if /etc/pam.d/system-auth
        file is present
      ansible.builtin.stat:
        path: /etc/pam.d/system-auth
      register: result_pam_auth_file_present

    - name: Set Lockout Time for Failed Password Attempts - Check the proper remediation
        for the system
      block:

      - name: Set Lockout Time for Failed Password Attempts - Define the PAM file
          to be edited as a local fact
        ansible.builtin.set_fact:
          pam_file_path: /etc/pam.d/system-auth

      - name: Set Lockout Time for Failed Password Attempts - Check if system relies
          on authselect tool
        ansible.builtin.stat:
          path: /usr/bin/authselect
        register: result_authselect_present

      - name: Set Lockout Time for Failed Password Attempts - Ensure authselect custom
          profile is used if authselect is present
        block:

        - name: Set Lockout Time for Failed Password Attempts - Check integrity of
            authselect current profile
          ansible.builtin.command:
            cmd: authselect check
          register: result_authselect_check_cmd
          changed_when: false
          check_mode: false
          failed_when: false

        - name: Set Lockout Time for Failed Password Attempts - Informative message
            based on the authselect integrity check result
          ansible.builtin.assert:
            that:
            - ansible_check_mode or result_authselect_check_cmd.rc == 0
            fail_msg:
            - authselect integrity check failed. Remediation aborted!
            - This remediation could not be applied because an authselect profile
              was not selected or the selected profile is not intact.
            - It is not recommended to manually edit the PAM files when authselect
              tool is available.
            - In cases where the default authselect profile does not cover a specific
              demand, a custom authselect profile is recommended.
            success_msg:
            - authselect integrity check passed

        - name: Set Lockout Time for Failed Password Attempts - Get authselect current
            profile
          ansible.builtin.shell:
            cmd: authselect current -r | awk '{ print $1 }'
          register: result_authselect_profile
          changed_when: false
          when:
          - result_authselect_check_cmd is success

        - name: Set Lockout Time for Failed Password Attempts - Define the current
            authselect profile as a local fact
          ansible.builtin.set_fact:
            authselect_current_profile: '{{ result_authselect_profile.stdout }}'
            authselect_custom_profile: '{{ result_authselect_profile.stdout }}'
          when:
          - result_authselect_profile is not skipped
          - result_authselect_profile.stdout is match("custom/")

        - name: Set Lockout Time for Failed Password Attempts - Define the new authselect
            custom profile as a local fact
          ansible.builtin.set_fact:
            authselect_current_profile: '{{ result_authselect_profile.stdout }}'
            authselect_custom_profile: custom/hardening
          when:
          - result_authselect_profile is not skipped
          - result_authselect_profile.stdout is not match("custom/")

        - name: Set Lockout Time for Failed Password Attempts - Get authselect current
            features to also enable them in the custom profile
          ansible.builtin.shell:
            cmd: authselect current | tail -n+3 | awk '{ print $2 }'
          register: result_authselect_features
          changed_when: false
          check_mode: false
          when:
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")

        - name: Set Lockout Time for Failed Password Attempts - Check if any custom
            profile with the same name was already created
          ansible.builtin.stat:
            path: /etc/authselect/{{ authselect_custom_profile }}
          register: result_authselect_custom_profile_present
          changed_when: false
          when:
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")

        - name: Set Lockout Time for Failed Password Attempts - Create an authselect
            custom profile based on the current profile
          ansible.builtin.command:
            cmd: authselect create-profile hardening -b {{ authselect_current_profile
              }}
          when:
          - result_authselect_profile is not skipped
          - result_authselect_check_cmd is success
          - authselect_current_profile is not match("^(custom/|local)")
          - not result_authselect_custom_profile_present.stat.exists

        - name: Set Lockout Time for Failed Password Attempts - Create an authselect
            custom profile based on sssd profile
          ansible.builtin.command:
            cmd: authselect create-profile hardening -b sssd
          when:
          - result_authselect_profile is not skipped
          - result_authselect_check_cmd is success
          - authselect_current_profile is match("local")
          - not result_authselect_custom_profile_present.stat.exists

        - name: Set Lockout Time for Failed Password Attempts - Ensure authselect
            changes are applied
          ansible.builtin.command:
            cmd: authselect apply-changes -b --backup=before-hardening-custom-profile
          when:
          - result_authselect_check_cmd is success
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")
          - authselect_custom_profile is not match(authselect_current_profile)

        - name: Set Lockout Time for Failed Password Attempts - Ensure the authselect
            custom profile is selected
          ansible.builtin.command:
            cmd: authselect select {{ authselect_custom_profile }}
          register: result_pam_authselect_select_profile
          when:
          - result_authselect_check_cmd is success
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")
          - authselect_custom_profile is not match(authselect_current_profile)

        - name: Set Lockout Time for Failed Password Attempts - Restore the authselect
            features in the custom profile
          ansible.builtin.command:
            cmd: authselect enable-feature {{ item }}
          loop: '{{ result_authselect_features.stdout_lines }}'
          register: result_pam_authselect_restore_features
          when:
          - result_authselect_profile is not skipped
          - result_authselect_features is not skipped
          - result_pam_authselect_select_profile is not skipped

        - name: Set Lockout Time for Failed Password Attempts - Ensure authselect
            changes are applied
          ansible.builtin.command:
            cmd: authselect apply-changes -b --backup=after-hardening-custom-profile
          when:
          - result_authselect_check_cmd is success
          - result_authselect_profile is not skipped
          - result_pam_authselect_restore_features is not skipped

        - name: Set Lockout Time for Failed Password Attempts - Change the PAM file
            to be edited according to the custom authselect profile
          ansible.builtin.set_fact:
            pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path
              | basename }}
          when:
          - authselect_custom_profile is defined
        when:
        - result_authselect_present.stat.exists

      - name: Set Lockout Time for Failed Password Attempts - Define a fact for control
          already filtered in case filters are used
        ansible.builtin.set_fact:
          pam_module_control: ''

      - name: Set Lockout Time for Failed Password Attempts - Check if {{ pam_file_path
          }} file is present
        ansible.builtin.stat:
          path: '{{ pam_file_path }}'
        register: result_pam_file_present

      - name: Set Lockout Time for Failed Password Attempts - Ensure the "unlock_time"
          option from "pam_faillock.so" is not present in {{ pam_file_path }}
        ansible.builtin.replace:
          dest: '{{ pam_file_path }}'
          regexp: (.*auth.*pam_faillock.so.*)\bunlock_time\b=?[0-9a-zA-Z]*(.*)
          replace: \1\2
        register: result_pam_option_removal
        when:
        - result_pam_file_present.stat.exists

      - name: Set Lockout Time for Failed Password Attempts - Ensure authselect changes
          are applied
        ansible.builtin.command:
          cmd: authselect apply-changes -b
        when:
        - result_authselect_present.stat.exists
        - result_pam_option_removal is changed
      when:
      - result_pam_auth_file_present.stat.exists

    - name: Set Lockout Time for Failed Password Attempts - Check if /etc/pam.d/password-auth
        file is present
      ansible.builtin.stat:
        path: /etc/pam.d/password-auth
      register: result_pam_password_auth_file_present

    - name: Set Lockout Time for Failed Password Attempts - Check the proper remediation
        for the system
      block:

      - name: Set Lockout Time for Failed Password Attempts - Define the PAM file
          to be edited as a local fact
        ansible.builtin.set_fact:
          pam_file_path: /etc/pam.d/password-auth

      - name: Set Lockout Time for Failed Password Attempts - Check if system relies
          on authselect tool
        ansible.builtin.stat:
          path: /usr/bin/authselect
        register: result_authselect_present

      - name: Set Lockout Time for Failed Password Attempts - Ensure authselect custom
          profile is used if authselect is present
        block:

        - name: Set Lockout Time for Failed Password Attempts - Check integrity of
            authselect current profile
          ansible.builtin.command:
            cmd: authselect check
          register: result_authselect_check_cmd
          changed_when: false
          check_mode: false
          failed_when: false

        - name: Set Lockout Time for Failed Password Attempts - Informative message
            based on the authselect integrity check result
          ansible.builtin.assert:
            that:
            - ansible_check_mode or result_authselect_check_cmd.rc == 0
            fail_msg:
            - authselect integrity check failed. Remediation aborted!
            - This remediation could not be applied because an authselect profile
              was not selected or the selected profile is not intact.
            - It is not recommended to manually edit the PAM files when authselect
              tool is available.
            - In cases where the default authselect profile does not cover a specific
              demand, a custom authselect profile is recommended.
            success_msg:
            - authselect integrity check passed

        - name: Set Lockout Time for Failed Password Attempts - Get authselect current
            profile
          ansible.builtin.shell:
            cmd: authselect current -r | awk '{ print $1 }'
          register: result_authselect_profile
          changed_when: false
          when:
          - result_authselect_check_cmd is success

        - name: Set Lockout Time for Failed Password Attempts - Define the current
            authselect profile as a local fact
          ansible.builtin.set_fact:
            authselect_current_profile: '{{ result_authselect_profile.stdout }}'
            authselect_custom_profile: '{{ result_authselect_profile.stdout }}'
          when:
          - result_authselect_profile is not skipped
          - result_authselect_profile.stdout is match("custom/")

        - name: Set Lockout Time for Failed Password Attempts - Define the new authselect
            custom profile as a local fact
          ansible.builtin.set_fact:
            authselect_current_profile: '{{ result_authselect_profile.stdout }}'
            authselect_custom_profile: custom/hardening
          when:
          - result_authselect_profile is not skipped
          - result_authselect_profile.stdout is not match("custom/")

        - name: Set Lockout Time for Failed Password Attempts - Get authselect current
            features to also enable them in the custom profile
          ansible.builtin.shell:
            cmd: authselect current | tail -n+3 | awk '{ print $2 }'
          register: result_authselect_features
          changed_when: false
          check_mode: false
          when:
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")

        - name: Set Lockout Time for Failed Password Attempts - Check if any custom
            profile with the same name was already created
          ansible.builtin.stat:
            path: /etc/authselect/{{ authselect_custom_profile }}
          register: result_authselect_custom_profile_present
          changed_when: false
          when:
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")

        - name: Set Lockout Time for Failed Password Attempts - Create an authselect
            custom profile based on the current profile
          ansible.builtin.command:
            cmd: authselect create-profile hardening -b {{ authselect_current_profile
              }}
          when:
          - result_authselect_profile is not skipped
          - result_authselect_check_cmd is success
          - authselect_current_profile is not match("^(custom/|local)")
          - not result_authselect_custom_profile_present.stat.exists

        - name: Set Lockout Time for Failed Password Attempts - Create an authselect
            custom profile based on sssd profile
          ansible.builtin.command:
            cmd: authselect create-profile hardening -b sssd
          when:
          - result_authselect_profile is not skipped
          - result_authselect_check_cmd is success
          - authselect_current_profile is match("local")
          - not result_authselect_custom_profile_present.stat.exists

        - name: Set Lockout Time for Failed Password Attempts - Ensure authselect
            changes are applied
          ansible.builtin.command:
            cmd: authselect apply-changes -b --backup=before-hardening-custom-profile
          when:
          - result_authselect_check_cmd is success
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")
          - authselect_custom_profile is not match(authselect_current_profile)

        - name: Set Lockout Time for Failed Password Attempts - Ensure the authselect
            custom profile is selected
          ansible.builtin.command:
            cmd: authselect select {{ authselect_custom_profile }}
          register: result_pam_authselect_select_profile
          when:
          - result_authselect_check_cmd is success
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")
          - authselect_custom_profile is not match(authselect_current_profile)

        - name: Set Lockout Time for Failed Password Attempts - Restore the authselect
            features in the custom profile
          ansible.builtin.command:
            cmd: authselect enable-feature {{ item }}
          loop: '{{ result_authselect_features.stdout_lines }}'
          register: result_pam_authselect_restore_features
          when:
          - result_authselect_profile is not skipped
          - result_authselect_features is not skipped
          - result_pam_authselect_select_profile is not skipped

        - name: Set Lockout Time for Failed Password Attempts - Ensure authselect
            changes are applied
          ansible.builtin.command:
            cmd: authselect apply-changes -b --backup=after-hardening-custom-profile
          when:
          - result_authselect_check_cmd is success
          - result_authselect_profile is not skipped
          - result_pam_authselect_restore_features is not skipped

        - name: Set Lockout Time for Failed Password Attempts - Change the PAM file
            to be edited according to the custom authselect profile
          ansible.builtin.set_fact:
            pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path
              | basename }}
          when:
          - authselect_custom_profile is defined
        when:
        - result_authselect_present.stat.exists

      - name: Set Lockout Time for Failed Password Attempts - Define a fact for control
          already filtered in case filters are used
        ansible.builtin.set_fact:
          pam_module_control: ''

      - name: Set Lockout Time for Failed Password Attempts - Check if {{ pam_file_path
          }} file is present
        ansible.builtin.stat:
          path: '{{ pam_file_path }}'
        register: result_pam_file_present

      - name: Set Lockout Time for Failed Password Attempts - Ensure the "unlock_time"
          option from "pam_faillock.so" is not present in {{ pam_file_path }}
        ansible.builtin.replace:
          dest: '{{ pam_file_path }}'
          regexp: (.*auth.*pam_faillock.so.*)\bunlock_time\b=?[0-9a-zA-Z]*(.*)
          replace: \1\2
        register: result_pam_option_removal
        when:
        - result_pam_file_present.stat.exists

      - name: Set Lockout Time for Failed Password Attempts - Ensure authselect changes
          are applied
        ansible.builtin.command:
          cmd: authselect apply-changes -b
        when:
        - result_authselect_present.stat.exists
        - result_pam_option_removal is changed
      when:
      - result_pam_password_auth_file_present.stat.exists
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    - result_faillock_conf_check.stat.exists
    tags:
    - accounts_passwords_pam_faillock_unlock_time_with_zero
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Set Lockout Time for Failed Password Attempts - Ensure the pam_faillock.so
      unlock_time parameter in PAM files
    block:

    - name: Set Lockout Time for Failed Password Attempts - Check if pam_faillock.so
        unlock_time parameter is already enabled in pam files
      ansible.builtin.lineinfile:
        path: /etc/pam.d/system-auth
        regexp: .*auth.*pam_faillock\.so (preauth|authfail).*unlock_time
        state: absent
      check_mode: true
      changed_when: false
      register: result_pam_faillock_unlock_time_parameter_is_present

    - name: Set Lockout Time for Failed Password Attempts - Ensure the inclusion of
        pam_faillock.so preauth unlock_time parameter in auth section
      ansible.builtin.lineinfile:
        path: '{{ item }}'
        backrefs: true
        regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so preauth.*)
        line: \1required\3 unlock_time={{ var_accounts_passwords_pam_faillock_unlock_time
          }}
        state: present
      loop:
      - /etc/pam.d/system-auth
      - /etc/pam.d/password-auth
      when:
      - result_pam_faillock_unlock_time_parameter_is_present.found == 0

    - name: Set Lockout Time for Failed Password Attempts - Ensure the inclusion of
        pam_faillock.so authfail unlock_time parameter in auth section
      ansible.builtin.lineinfile:
        path: '{{ item }}'
        backrefs: true
        regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so authfail.*)
        line: \1required\3 unlock_time={{ var_accounts_passwords_pam_faillock_unlock_time
          }}
        state: present
      loop:
      - /etc/pam.d/system-auth
      - /etc/pam.d/password-auth
      when:
      - result_pam_faillock_unlock_time_parameter_is_present.found == 0

    - name: Set Lockout Time for Failed Password Attempts - Ensure the desired value
        for pam_faillock.so preauth unlock_time parameter in auth section
      ansible.builtin.lineinfile:
        path: '{{ item }}'
        backrefs: true
        regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so preauth.*)(unlock_time)=[0-9]+(.*)
        line: \1required\3\4={{ var_accounts_passwords_pam_faillock_unlock_time }}\5
        state: present
      loop:
      - /etc/pam.d/system-auth
      - /etc/pam.d/password-auth
      when:
      - result_pam_faillock_unlock_time_parameter_is_present.found > 0

    - name: Set Lockout Time for Failed Password Attempts - Ensure the desired value
        for pam_faillock.so authfail unlock_time parameter in auth section
      ansible.builtin.lineinfile:
        path: '{{ item }}'
        backrefs: true
        regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so authfail.*)(unlock_time)=[0-9]+(.*)
        line: \1required\3\4={{ var_accounts_passwords_pam_faillock_unlock_time }}\5
        state: present
      loop:
      - /etc/pam.d/system-auth
      - /etc/pam.d/password-auth
      when:
      - result_pam_faillock_unlock_time_parameter_is_present.found > 0
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    - not result_faillock_conf_check.stat.exists
    tags:
    - accounts_passwords_pam_faillock_unlock_time_with_zero
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure PAM Enforces Password Requirements - Prevent the Use of Dictionary
      Words - Ensure PAM variable dictcheck is set accordingly
    ansible.builtin.lineinfile:
      create: true
      dest: /etc/security/pwquality.conf
      regexp: ^#?\s*dictcheck
      line: dictcheck = {{ var_password_pam_dictcheck }}
    when:
    - '"kernel" in ansible_facts.packages'
    - '"libpwquality" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-020300
    - NIST-800-53-CM-6(a)
    - NIST-800-53-IA-5(1)(a)
    - NIST-800-53-IA-5(4)
    - NIST-800-53-IA-5(c)
    - accounts_password_pam_dictcheck
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure PAM Enforces Password Requirements - Minimum Different Characters
      - Ensure PAM variable difok is set accordingly
    ansible.builtin.lineinfile:
      create: true
      dest: /etc/security/pwquality.conf
      regexp: ^#?\s*difok
      line: difok = {{ var_password_pam_difok }}
    when:
    - '"kernel" in ansible_facts.packages'
    - '"libpwquality" in ansible_facts.packages'
    tags:
    - CJIS-5.6.2.1.1
    - DISA-STIG-RHEL-08-020170
    - NIST-800-53-CM-6(a)
    - NIST-800-53-IA-5(1)(b)
    - NIST-800-53-IA-5(4)
    - NIST-800-53-IA-5(c)
    - accounts_password_pam_difok
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure PAM Enforces Password Requirements - Enforce for root User
    ansible.builtin.lineinfile:
      path: /etc/security/pwquality.conf
      create: true
      regexp: ''
      line: enforce_for_root
      state: present
    when:
    - '"kernel" in ansible_facts.packages'
    - '"libpwquality" in ansible_facts.packages'
    tags:
    - NIST-800-53-CM-6(a)
    - NIST-800-53-IA-5(1)(a)
    - NIST-800-53-IA-5(4)
    - NIST-800-53-IA-5(c)
    - accounts_password_pam_enforce_root
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Set Password Maximum Consecutive Repeating Characters - Ensure PAM variable
      maxrepeat is set accordingly
    ansible.builtin.lineinfile:
      create: true
      dest: /etc/security/pwquality.conf
      regexp: ^#?\s*maxrepeat
      line: maxrepeat = {{ var_password_pam_maxrepeat }}
    when:
    - '"kernel" in ansible_facts.packages'
    - '"libpwquality" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-020150
    - NIST-800-53-CM-6(a)
    - NIST-800-53-IA-5(4)
    - NIST-800-53-IA-5(c)
    - accounts_password_pam_maxrepeat
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Limit the maximum number of sequential characters in passwords - Ensure
      PAM variable maxsequence is set accordingly
    ansible.builtin.lineinfile:
      create: true
      dest: /etc/security/pwquality.conf
      regexp: ^#?\s*maxsequence
      line: maxsequence = {{ var_password_pam_maxsequence }}
    when:
    - '"kernel" in ansible_facts.packages'
    - '"libpwquality" in ansible_facts.packages'
    tags:
    - accounts_password_pam_maxsequence
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure PAM Enforces Password Requirements - Minimum Length - Ensure PAM
      variable minlen is set accordingly
    ansible.builtin.lineinfile:
      create: true
      dest: /etc/security/pwquality.conf
      regexp: ^#?\s*minlen
      line: minlen = {{ var_password_pam_minlen }}
    when:
    - '"kernel" in ansible_facts.packages'
    - '"libpwquality" in ansible_facts.packages'
    tags:
    - CJIS-5.6.2.1.1
    - DISA-STIG-RHEL-08-020230
    - NIST-800-53-CM-6(a)
    - NIST-800-53-IA-5(1)(a)
    - NIST-800-53-IA-5(4)
    - NIST-800-53-IA-5(c)
    - PCI-DSS-Req-8.2.3
    - PCI-DSSv4-8.3
    - PCI-DSSv4-8.3.6
    - accounts_password_pam_minlen
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure PAM password complexity module is enabled in password-auth - Check
      if /etc/pam.d/password-auth file is present
    ansible.builtin.stat:
      path: /etc/pam.d/password-auth
    register: result_pam_password_auth_file_present
    when:
    - '"kernel" in ansible_facts.packages'
    - '"libpwquality" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-020100
    - accounts_password_pam_pwquality_password_auth
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure PAM password complexity module is enabled in password-auth - Check
      the proper remediation for the system
    block:

    - name: Ensure PAM password complexity module is enabled in password-auth - Define
        the PAM file to be edited as a local fact
      ansible.builtin.set_fact:
        pam_file_path: /etc/pam.d/password-auth

    - name: Ensure PAM password complexity module is enabled in password-auth - Check
        if system relies on authselect tool
      ansible.builtin.stat:
        path: /usr/bin/authselect
      register: result_authselect_present

    - name: Ensure PAM password complexity module is enabled in password-auth - Ensure
        authselect custom profile is used if authselect is present
      block:

      - name: Ensure PAM password complexity module is enabled in password-auth -
          Check integrity of authselect current profile
        ansible.builtin.command:
          cmd: authselect check
        register: result_authselect_check_cmd
        changed_when: false
        check_mode: false
        failed_when: false

      - name: Ensure PAM password complexity module is enabled in password-auth -
          Informative message based on the authselect integrity check result
        ansible.builtin.assert:
          that:
          - ansible_check_mode or result_authselect_check_cmd.rc == 0
          fail_msg:
          - authselect integrity check failed. Remediation aborted!
          - This remediation could not be applied because an authselect profile was
            not selected or the selected profile is not intact.
          - It is not recommended to manually edit the PAM files when authselect tool
            is available.
          - In cases where the default authselect profile does not cover a specific
            demand, a custom authselect profile is recommended.
          success_msg:
          - authselect integrity check passed

      - name: Ensure PAM password complexity module is enabled in password-auth -
          Get authselect current profile
        ansible.builtin.shell:
          cmd: authselect current -r | awk '{ print $1 }'
        register: result_authselect_profile
        changed_when: false
        when:
        - result_authselect_check_cmd is success

      - name: Ensure PAM password complexity module is enabled in password-auth -
          Define the current authselect profile as a local fact
        ansible.builtin.set_fact:
          authselect_current_profile: '{{ result_authselect_profile.stdout }}'
          authselect_custom_profile: '{{ result_authselect_profile.stdout }}'
        when:
        - result_authselect_profile is not skipped
        - result_authselect_profile.stdout is match("custom/")

      - name: Ensure PAM password complexity module is enabled in password-auth -
          Define the new authselect custom profile as a local fact
        ansible.builtin.set_fact:
          authselect_current_profile: '{{ result_authselect_profile.stdout }}'
          authselect_custom_profile: custom/hardening
        when:
        - result_authselect_profile is not skipped
        - result_authselect_profile.stdout is not match("custom/")

      - name: Ensure PAM password complexity module is enabled in password-auth -
          Get authselect current features to also enable them in the custom profile
        ansible.builtin.shell:
          cmd: authselect current | tail -n+3 | awk '{ print $2 }'
        register: result_authselect_features
        changed_when: false
        check_mode: false
        when:
        - result_authselect_profile is not skipped
        - authselect_current_profile is not match("custom/")

      - name: Ensure PAM password complexity module is enabled in password-auth -
          Check if any custom profile with the same name was already created
        ansible.builtin.stat:
          path: /etc/authselect/{{ authselect_custom_profile }}
        register: result_authselect_custom_profile_present
        changed_when: false
        when:
        - result_authselect_profile is not skipped
        - authselect_current_profile is not match("custom/")

      - name: Ensure PAM password complexity module is enabled in password-auth -
          Create an authselect custom profile based on the current profile
        ansible.builtin.command:
          cmd: authselect create-profile hardening -b {{ authselect_current_profile
            }}
        when:
        - result_authselect_profile is not skipped
        - result_authselect_check_cmd is success
        - authselect_current_profile is not match("^(custom/|local)")
        - not result_authselect_custom_profile_present.stat.exists

      - name: Ensure PAM password complexity module is enabled in password-auth -
          Create an authselect custom profile based on sssd profile
        ansible.builtin.command:
          cmd: authselect create-profile hardening -b sssd
        when:
        - result_authselect_profile is not skipped
        - result_authselect_check_cmd is success
        - authselect_current_profile is match("local")
        - not result_authselect_custom_profile_present.stat.exists

      - name: Ensure PAM password complexity module is enabled in password-auth -
          Ensure authselect changes are applied
        ansible.builtin.command:
          cmd: authselect apply-changes -b --backup=before-hardening-custom-profile
        when:
        - result_authselect_check_cmd is success
        - result_authselect_profile is not skipped
        - authselect_current_profile is not match("custom/")
        - authselect_custom_profile is not match(authselect_current_profile)

      - name: Ensure PAM password complexity module is enabled in password-auth -
          Ensure the authselect custom profile is selected
        ansible.builtin.command:
          cmd: authselect select {{ authselect_custom_profile }}
        register: result_pam_authselect_select_profile
        when:
        - result_authselect_check_cmd is success
        - result_authselect_profile is not skipped
        - authselect_current_profile is not match("custom/")
        - authselect_custom_profile is not match(authselect_current_profile)

      - name: Ensure PAM password complexity module is enabled in password-auth -
          Restore the authselect features in the custom profile
        ansible.builtin.command:
          cmd: authselect enable-feature {{ item }}
        loop: '{{ result_authselect_features.stdout_lines }}'
        register: result_pam_authselect_restore_features
        when:
        - result_authselect_profile is not skipped
        - result_authselect_features is not skipped
        - result_pam_authselect_select_profile is not skipped

      - name: Ensure PAM password complexity module is enabled in password-auth -
          Ensure authselect changes are applied
        ansible.builtin.command:
          cmd: authselect apply-changes -b --backup=after-hardening-custom-profile
        when:
        - result_authselect_check_cmd is success
        - result_authselect_profile is not skipped
        - result_pam_authselect_restore_features is not skipped

      - name: Ensure PAM password complexity module is enabled in password-auth -
          Change the PAM file to be edited according to the custom authselect profile
        ansible.builtin.set_fact:
          pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path
            | basename }}
        when:
        - authselect_custom_profile is defined
      when:
      - result_authselect_present.stat.exists

    - name: Ensure PAM password complexity module is enabled in password-auth - Define
        a fact for control already filtered in case filters are used
      ansible.builtin.set_fact:
        pam_module_control: requisite

    - name: Ensure PAM password complexity module is enabled in password-auth - Check
        if expected PAM module line is present in {{ pam_file_path }}
      ansible.builtin.lineinfile:
        path: '{{ pam_file_path }}'
        regexp: ^\s*password\s+{{ pam_module_control | regex_escape() }}\s+pam_pwquality.so\s*.*
        state: absent
      check_mode: true
      changed_when: false
      register: result_pam_line_present

    - name: Ensure PAM password complexity module is enabled in password-auth - Include
        or update the PAM module line in {{ pam_file_path }}
      block:

      - name: Ensure PAM password complexity module is enabled in password-auth -
          Check if required PAM module line is present in {{ pam_file_path }} with
          different control
        ansible.builtin.lineinfile:
          path: '{{ pam_file_path }}'
          regexp: ^\s*password\s+.*\s+pam_pwquality.so\s*
          state: absent
        check_mode: true
        changed_when: false
        register: result_pam_line_other_control_present

      - name: Ensure PAM password complexity module is enabled in password-auth -
          Ensure the correct control for the required PAM module line in {{ pam_file_path
          }}
        ansible.builtin.replace:
          dest: '{{ pam_file_path }}'
          regexp: ^(\s*password\s+).*(\bpam_pwquality.so.*)
          replace: \1{{ pam_module_control }} \2
        register: result_pam_module_edit
        when:
        - result_pam_line_other_control_present.found == 1

      - name: Ensure PAM password complexity module is enabled in password-auth -
          Ensure the required PAM module line is included in {{ pam_file_path }}
        ansible.builtin.lineinfile:
          dest: '{{ pam_file_path }}'
          insertafter: ^account.*required.*pam_permit\.so
          line: password    {{ pam_module_control }}    pam_pwquality.so
        register: result_pam_module_add
        when:
        - result_pam_line_other_control_present.found == 0 or result_pam_line_other_control_present.found
          > 1

      - name: Ensure PAM password complexity module is enabled in password-auth -
          Ensure authselect changes are applied
        ansible.builtin.command:
          cmd: authselect apply-changes -b
        when:
        - result_authselect_present is defined
        - result_authselect_present.stat.exists
        - |-
          (result_pam_module_add is defined and result_pam_module_add.changed)
           or (result_pam_module_edit is defined and result_pam_module_edit.changed)
      when:
      - result_pam_line_present.found is defined
      - result_pam_line_present.found == 0

    - name: Ensure PAM password complexity module is enabled in password-auth - Ensure
        authselect changes are applied
      ansible.builtin.command:
        cmd: authselect apply-changes -b
      when:
      - result_authselect_present.stat.exists
      - |-
        (result_pam_accounts_password_pam_pwquality_password_auth_add is defined and result_pam_accounts_password_pam_pwquality_password_auth_add.changed)
         or (result_pam_accounts_password_pam_pwquality_password_auth_edit is defined and result_pam_accounts_password_pam_pwquality_password_auth_edit.changed)
    when:
    - '"kernel" in ansible_facts.packages'
    - '"libpwquality" in ansible_facts.packages'
    - result_pam_password_auth_file_present.stat.exists
    tags:
    - DISA-STIG-RHEL-08-020100
    - accounts_password_pam_pwquality_password_auth
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure PAM password complexity module is enabled in system-auth - Check
      if /etc/pam.d/system-auth file is present
    ansible.builtin.stat:
      path: /etc/pam.d/system-auth
    register: result_pam_auth_file_present
    when:
    - '"kernel" in ansible_facts.packages'
    - '"libpwquality" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-020101
    - accounts_password_pam_pwquality_system_auth
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure PAM password complexity module is enabled in system-auth - Check
      the proper remediation for the system
    block:

    - name: Ensure PAM password complexity module is enabled in system-auth - Define
        the PAM file to be edited as a local fact
      ansible.builtin.set_fact:
        pam_file_path: /etc/pam.d/system-auth

    - name: Ensure PAM password complexity module is enabled in system-auth - Check
        if system relies on authselect tool
      ansible.builtin.stat:
        path: /usr/bin/authselect
      register: result_authselect_present

    - name: Ensure PAM password complexity module is enabled in system-auth - Ensure
        authselect custom profile is used if authselect is present
      block:

      - name: Ensure PAM password complexity module is enabled in system-auth - Check
          integrity of authselect current profile
        ansible.builtin.command:
          cmd: authselect check
        register: result_authselect_check_cmd
        changed_when: false
        check_mode: false
        failed_when: false

      - name: Ensure PAM password complexity module is enabled in system-auth - Informative
          message based on the authselect integrity check result
        ansible.builtin.assert:
          that:
          - ansible_check_mode or result_authselect_check_cmd.rc == 0
          fail_msg:
          - authselect integrity check failed. Remediation aborted!
          - This remediation could not be applied because an authselect profile was
            not selected or the selected profile is not intact.
          - It is not recommended to manually edit the PAM files when authselect tool
            is available.
          - In cases where the default authselect profile does not cover a specific
            demand, a custom authselect profile is recommended.
          success_msg:
          - authselect integrity check passed

      - name: Ensure PAM password complexity module is enabled in system-auth - Get
          authselect current profile
        ansible.builtin.shell:
          cmd: authselect current -r | awk '{ print $1 }'
        register: result_authselect_profile
        changed_when: false
        when:
        - result_authselect_check_cmd is success

      - name: Ensure PAM password complexity module is enabled in system-auth - Define
          the current authselect profile as a local fact
        ansible.builtin.set_fact:
          authselect_current_profile: '{{ result_authselect_profile.stdout }}'
          authselect_custom_profile: '{{ result_authselect_profile.stdout }}'
        when:
        - result_authselect_profile is not skipped
        - result_authselect_profile.stdout is match("custom/")

      - name: Ensure PAM password complexity module is enabled in system-auth - Define
          the new authselect custom profile as a local fact
        ansible.builtin.set_fact:
          authselect_current_profile: '{{ result_authselect_profile.stdout }}'
          authselect_custom_profile: custom/hardening
        when:
        - result_authselect_profile is not skipped
        - result_authselect_profile.stdout is not match("custom/")

      - name: Ensure PAM password complexity module is enabled in system-auth - Get
          authselect current features to also enable them in the custom profile
        ansible.builtin.shell:
          cmd: authselect current | tail -n+3 | awk '{ print $2 }'
        register: result_authselect_features
        changed_when: false
        check_mode: false
        when:
        - result_authselect_profile is not skipped
        - authselect_current_profile is not match("custom/")

      - name: Ensure PAM password complexity module is enabled in system-auth - Check
          if any custom profile with the same name was already created
        ansible.builtin.stat:
          path: /etc/authselect/{{ authselect_custom_profile }}
        register: result_authselect_custom_profile_present
        changed_when: false
        when:
        - result_authselect_profile is not skipped
        - authselect_current_profile is not match("custom/")

      - name: Ensure PAM password complexity module is enabled in system-auth - Create
          an authselect custom profile based on the current profile
        ansible.builtin.command:
          cmd: authselect create-profile hardening -b {{ authselect_current_profile
            }}
        when:
        - result_authselect_profile is not skipped
        - result_authselect_check_cmd is success
        - authselect_current_profile is not match("^(custom/|local)")
        - not result_authselect_custom_profile_present.stat.exists

      - name: Ensure PAM password complexity module is enabled in system-auth - Create
          an authselect custom profile based on sssd profile
        ansible.builtin.command:
          cmd: authselect create-profile hardening -b sssd
        when:
        - result_authselect_profile is not skipped
        - result_authselect_check_cmd is success
        - authselect_current_profile is match("local")
        - not result_authselect_custom_profile_present.stat.exists

      - name: Ensure PAM password complexity module is enabled in system-auth - Ensure
          authselect changes are applied
        ansible.builtin.command:
          cmd: authselect apply-changes -b --backup=before-hardening-custom-profile
        when:
        - result_authselect_check_cmd is success
        - result_authselect_profile is not skipped
        - authselect_current_profile is not match("custom/")
        - authselect_custom_profile is not match(authselect_current_profile)

      - name: Ensure PAM password complexity module is enabled in system-auth - Ensure
          the authselect custom profile is selected
        ansible.builtin.command:
          cmd: authselect select {{ authselect_custom_profile }}
        register: result_pam_authselect_select_profile
        when:
        - result_authselect_check_cmd is success
        - result_authselect_profile is not skipped
        - authselect_current_profile is not match("custom/")
        - authselect_custom_profile is not match(authselect_current_profile)

      - name: Ensure PAM password complexity module is enabled in system-auth - Restore
          the authselect features in the custom profile
        ansible.builtin.command:
          cmd: authselect enable-feature {{ item }}
        loop: '{{ result_authselect_features.stdout_lines }}'
        register: result_pam_authselect_restore_features
        when:
        - result_authselect_profile is not skipped
        - result_authselect_features is not skipped
        - result_pam_authselect_select_profile is not skipped

      - name: Ensure PAM password complexity module is enabled in system-auth - Ensure
          authselect changes are applied
        ansible.builtin.command:
          cmd: authselect apply-changes -b --backup=after-hardening-custom-profile
        when:
        - result_authselect_check_cmd is success
        - result_authselect_profile is not skipped
        - result_pam_authselect_restore_features is not skipped

      - name: Ensure PAM password complexity module is enabled in system-auth - Change
          the PAM file to be edited according to the custom authselect profile
        ansible.builtin.set_fact:
          pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path
            | basename }}
        when:
        - authselect_custom_profile is defined
      when:
      - result_authselect_present.stat.exists

    - name: Ensure PAM password complexity module is enabled in system-auth - Define
        a fact for control already filtered in case filters are used
      ansible.builtin.set_fact:
        pam_module_control: requisite

    - name: Ensure PAM password complexity module is enabled in system-auth - Check
        if expected PAM module line is present in {{ pam_file_path }}
      ansible.builtin.lineinfile:
        path: '{{ pam_file_path }}'
        regexp: ^\s*password\s+{{ pam_module_control | regex_escape() }}\s+pam_pwquality.so\s*.*
        state: absent
      check_mode: true
      changed_when: false
      register: result_pam_line_present

    - name: Ensure PAM password complexity module is enabled in system-auth - Include
        or update the PAM module line in {{ pam_file_path }}
      block:

      - name: Ensure PAM password complexity module is enabled in system-auth - Check
          if required PAM module line is present in {{ pam_file_path }} with different
          control
        ansible.builtin.lineinfile:
          path: '{{ pam_file_path }}'
          regexp: ^\s*password\s+.*\s+pam_pwquality.so\s*
          state: absent
        check_mode: true
        changed_when: false
        register: result_pam_line_other_control_present

      - name: Ensure PAM password complexity module is enabled in system-auth - Ensure
          the correct control for the required PAM module line in {{ pam_file_path
          }}
        ansible.builtin.replace:
          dest: '{{ pam_file_path }}'
          regexp: ^(\s*password\s+).*(\bpam_pwquality.so.*)
          replace: \1{{ pam_module_control }} \2
        register: result_pam_module_edit
        when:
        - result_pam_line_other_control_present.found == 1

      - name: Ensure PAM password complexity module is enabled in system-auth - Ensure
          the required PAM module line is included in {{ pam_file_path }}
        ansible.builtin.lineinfile:
          dest: '{{ pam_file_path }}'
          insertafter: ^account.*required.*pam_permit\.so
          line: password    {{ pam_module_control }}    pam_pwquality.so
        register: result_pam_module_add
        when:
        - result_pam_line_other_control_present.found == 0 or result_pam_line_other_control_present.found
          > 1

      - name: Ensure PAM password complexity module is enabled in system-auth - Ensure
          authselect changes are applied
        ansible.builtin.command:
          cmd: authselect apply-changes -b
        when:
        - result_authselect_present is defined
        - result_authselect_present.stat.exists
        - |-
          (result_pam_module_add is defined and result_pam_module_add.changed)
           or (result_pam_module_edit is defined and result_pam_module_edit.changed)
      when:
      - result_pam_line_present.found is defined
      - result_pam_line_present.found == 0

    - name: Ensure PAM password complexity module is enabled in system-auth - Ensure
        authselect changes are applied
      ansible.builtin.command:
        cmd: authselect apply-changes -b
      when:
      - result_authselect_present.stat.exists
      - |-
        (result_pam_accounts_password_pam_pwquality_system_auth_add is defined and result_pam_accounts_password_pam_pwquality_system_auth_add.changed)
         or (result_pam_accounts_password_pam_pwquality_system_auth_edit is defined and result_pam_accounts_password_pam_pwquality_system_auth_edit.changed)
    when:
    - '"kernel" in ansible_facts.packages'
    - '"libpwquality" in ansible_facts.packages'
    - result_pam_auth_file_present.stat.exists
    tags:
    - DISA-STIG-RHEL-08-020101
    - accounts_password_pam_pwquality_system_auth
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set Password Hashing Algorithm in /etc/login.defs
    ansible.builtin.lineinfile:
      dest: /etc/login.defs
      regexp: ^#?ENCRYPT_METHOD
      line: ENCRYPT_METHOD {{ var_password_hashing_algorithm.split('|')[0] }}
      state: present
      create: true
    when:
    - '"kernel" in ansible_facts.packages'
    - '"shadow-utils" in ansible_facts.packages'
    tags:
    - CJIS-5.6.2.2
    - DISA-STIG-RHEL-08-010110
    - NIST-800-171-3.13.11
    - NIST-800-53-CM-6(a)
    - NIST-800-53-IA-5(1)(c)
    - NIST-800-53-IA-5(c)
    - PCI-DSS-Req-8.2.1
    - PCI-DSSv4-8.3
    - PCI-DSSv4-8.3.2
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy
    - set_password_hashing_algorithm_logindefs

  - name: Set PAM Password Hashing Algorithm - password-auth - Check if /etc/pam.d/password-auth
      file is present
    ansible.builtin.stat:
      path: /etc/pam.d/password-auth
    register: result_pam_password_auth_file_present
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    tags:
    - CJIS-5.6.2.2
    - DISA-STIG-RHEL-08-010160
    - NIST-800-171-3.13.11
    - NIST-800-53-CM-6(a)
    - NIST-800-53-IA-5(1)(c)
    - NIST-800-53-IA-5(c)
    - PCI-DSS-Req-8.2.1
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - set_password_hashing_algorithm_passwordauth

  - name: Set PAM Password Hashing Algorithm - password-auth - Check the proper remediation
      for the system
    block:

    - name: Set PAM Password Hashing Algorithm - password-auth - Define the PAM file
        to be edited as a local fact
      ansible.builtin.set_fact:
        pam_file_path: /etc/pam.d/password-auth

    - name: Set PAM Password Hashing Algorithm - password-auth - Check if system relies
        on authselect tool
      ansible.builtin.stat:
        path: /usr/bin/authselect
      register: result_authselect_present

    - name: Set PAM Password Hashing Algorithm - password-auth - Ensure authselect
        custom profile is used if authselect is present
      block:

      - name: Set PAM Password Hashing Algorithm - password-auth - Check integrity
          of authselect current profile
        ansible.builtin.command:
          cmd: authselect check
        register: result_authselect_check_cmd
        changed_when: false
        check_mode: false
        failed_when: false

      - name: Set PAM Password Hashing Algorithm - password-auth - Informative message
          based on the authselect integrity check result
        ansible.builtin.assert:
          that:
          - ansible_check_mode or result_authselect_check_cmd.rc == 0
          fail_msg:
          - authselect integrity check failed. Remediation aborted!
          - This remediation could not be applied because an authselect profile was
            not selected or the selected profile is not intact.
          - It is not recommended to manually edit the PAM files when authselect tool
            is available.
          - In cases where the default authselect profile does not cover a specific
            demand, a custom authselect profile is recommended.
          success_msg:
          - authselect integrity check passed

      - name: Set PAM Password Hashing Algorithm - password-auth - Get authselect
          current profile
        ansible.builtin.shell:
          cmd: authselect current -r | awk '{ print $1 }'
        register: result_authselect_profile
        changed_when: false
        when:
        - result_authselect_check_cmd is success

      - name: Set PAM Password Hashing Algorithm - password-auth - Define the current
          authselect profile as a local fact
        ansible.builtin.set_fact:
          authselect_current_profile: '{{ result_authselect_profile.stdout }}'
          authselect_custom_profile: '{{ result_authselect_profile.stdout }}'
        when:
        - result_authselect_profile is not skipped
        - result_authselect_profile.stdout is match("custom/")

      - name: Set PAM Password Hashing Algorithm - password-auth - Define the new
          authselect custom profile as a local fact
        ansible.builtin.set_fact:
          authselect_current_profile: '{{ result_authselect_profile.stdout }}'
          authselect_custom_profile: custom/hardening
        when:
        - result_authselect_profile is not skipped
        - result_authselect_profile.stdout is not match("custom/")

      - name: Set PAM Password Hashing Algorithm - password-auth - Get authselect
          current features to also enable them in the custom profile
        ansible.builtin.shell:
          cmd: authselect current | tail -n+3 | awk '{ print $2 }'
        register: result_authselect_features
        changed_when: false
        check_mode: false
        when:
        - result_authselect_profile is not skipped
        - authselect_current_profile is not match("custom/")

      - name: Set PAM Password Hashing Algorithm - password-auth - Check if any custom
          profile with the same name was already created
        ansible.builtin.stat:
          path: /etc/authselect/{{ authselect_custom_profile }}
        register: result_authselect_custom_profile_present
        changed_when: false
        when:
        - result_authselect_profile is not skipped
        - authselect_current_profile is not match("custom/")

      - name: Set PAM Password Hashing Algorithm - password-auth - Create an authselect
          custom profile based on the current profile
        ansible.builtin.command:
          cmd: authselect create-profile hardening -b {{ authselect_current_profile
            }}
        when:
        - result_authselect_profile is not skipped
        - result_authselect_check_cmd is success
        - authselect_current_profile is not match("^(custom/|local)")
        - not result_authselect_custom_profile_present.stat.exists

      - name: Set PAM Password Hashing Algorithm - password-auth - Create an authselect
          custom profile based on sssd profile
        ansible.builtin.command:
          cmd: authselect create-profile hardening -b sssd
        when:
        - result_authselect_profile is not skipped
        - result_authselect_check_cmd is success
        - authselect_current_profile is match("local")
        - not result_authselect_custom_profile_present.stat.exists

      - name: Set PAM Password Hashing Algorithm - password-auth - Ensure authselect
          changes are applied
        ansible.builtin.command:
          cmd: authselect apply-changes -b --backup=before-hardening-custom-profile
        when:
        - result_authselect_check_cmd is success
        - result_authselect_profile is not skipped
        - authselect_current_profile is not match("custom/")
        - authselect_custom_profile is not match(authselect_current_profile)

      - name: Set PAM Password Hashing Algorithm - password-auth - Ensure the authselect
          custom profile is selected
        ansible.builtin.command:
          cmd: authselect select {{ authselect_custom_profile }}
        register: result_pam_authselect_select_profile
        when:
        - result_authselect_check_cmd is success
        - result_authselect_profile is not skipped
        - authselect_current_profile is not match("custom/")
        - authselect_custom_profile is not match(authselect_current_profile)

      - name: Set PAM Password Hashing Algorithm - password-auth - Restore the authselect
          features in the custom profile
        ansible.builtin.command:
          cmd: authselect enable-feature {{ item }}
        loop: '{{ result_authselect_features.stdout_lines }}'
        register: result_pam_authselect_restore_features
        when:
        - result_authselect_profile is not skipped
        - result_authselect_features is not skipped
        - result_pam_authselect_select_profile is not skipped

      - name: Set PAM Password Hashing Algorithm - password-auth - Ensure authselect
          changes are applied
        ansible.builtin.command:
          cmd: authselect apply-changes -b --backup=after-hardening-custom-profile
        when:
        - result_authselect_check_cmd is success
        - result_authselect_profile is not skipped
        - result_pam_authselect_restore_features is not skipped

      - name: Set PAM Password Hashing Algorithm - password-auth - Change the PAM
          file to be edited according to the custom authselect profile
        ansible.builtin.set_fact:
          pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path
            | basename }}
        when:
        - authselect_custom_profile is defined
      when:
      - result_authselect_present.stat.exists

    - name: Set PAM Password Hashing Algorithm - password-auth - Define a fact for
        control already filtered in case filters are used
      ansible.builtin.set_fact:
        pam_module_control: sufficient

    - name: Set PAM Password Hashing Algorithm - password-auth - Check if expected
        PAM module line is present in {{ pam_file_path }}
      ansible.builtin.lineinfile:
        path: '{{ pam_file_path }}'
        regexp: ^\s*password\s+{{ pam_module_control | regex_escape() }}\s+pam_unix.so\s*.*
        state: absent
      check_mode: true
      changed_when: false
      register: result_pam_line_present

    - name: Set PAM Password Hashing Algorithm - password-auth - Include or update
        the PAM module line in {{ pam_file_path }}
      block:

      - name: Set PAM Password Hashing Algorithm - password-auth - Check if required
          PAM module line is present in {{ pam_file_path }} with different control
        ansible.builtin.lineinfile:
          path: '{{ pam_file_path }}'
          regexp: ^\s*password\s+.*\s+pam_unix.so\s*
          state: absent
        check_mode: true
        changed_when: false
        register: result_pam_line_other_control_present

      - name: Set PAM Password Hashing Algorithm - password-auth - Ensure the correct
          control for the required PAM module line in {{ pam_file_path }}
        ansible.builtin.replace:
          dest: '{{ pam_file_path }}'
          regexp: ^(\s*password\s+).*(\bpam_unix.so.*)
          replace: \1{{ pam_module_control }} \2
        register: result_pam_module_edit
        when:
        - result_pam_line_other_control_present.found == 1

      - name: Set PAM Password Hashing Algorithm - password-auth - Ensure the required
          PAM module line is included in {{ pam_file_path }}
        ansible.builtin.lineinfile:
          dest: '{{ pam_file_path }}'
          line: password    {{ pam_module_control }}    pam_unix.so
        register: result_pam_module_add
        when:
        - result_pam_line_other_control_present.found == 0 or result_pam_line_other_control_present.found
          > 1

      - name: Set PAM Password Hashing Algorithm - password-auth - Ensure authselect
          changes are applied
        ansible.builtin.command:
          cmd: authselect apply-changes -b
        when:
        - result_authselect_present is defined
        - result_authselect_present.stat.exists
        - |-
          (result_pam_module_add is defined and result_pam_module_add.changed)
           or (result_pam_module_edit is defined and result_pam_module_edit.changed)
      when:
      - result_pam_line_present.found is defined
      - result_pam_line_present.found == 0

    - name: Set PAM Password Hashing Algorithm - password-auth - Define a fact for
        control already filtered in case filters are used
      ansible.builtin.set_fact:
        pam_module_control: sufficient

    - name: Set PAM Password Hashing Algorithm - password-auth - Check if the required
        PAM module option is present in {{ pam_file_path }}
      ansible.builtin.lineinfile:
        path: '{{ pam_file_path }}'
        regexp: ^\s*password\s+{{ pam_module_control | regex_escape() }}\s+pam_unix.so\s*.*\s{{
          var_password_hashing_algorithm_pam.split("|")[0] }}\b
        state: absent
      check_mode: true
      changed_when: false
      register: result_pam_module_set_password_hashing_algorithm_passwordauth_option_present

    - name: Set PAM Password Hashing Algorithm - password-auth - Ensure the "{{ var_password_hashing_algorithm_pam.split("|")[0]
        }}" PAM option for "pam_unix.so" is included in {{ pam_file_path }}
      ansible.builtin.lineinfile:
        path: '{{ pam_file_path }}'
        backrefs: true
        regexp: ^(\s*password\s+{{ pam_module_control | regex_escape() }}\s+pam_unix.so.*)
        line: \1 {{ var_password_hashing_algorithm_pam.split("|")[0] }}
        state: present
      register: result_pam_set_password_hashing_algorithm_passwordauth_add
      when:
      - result_pam_module_set_password_hashing_algorithm_passwordauth_option_present.found
        is defined
      - result_pam_module_set_password_hashing_algorithm_passwordauth_option_present.found
        == 0

    - name: Set PAM Password Hashing Algorithm - password-auth - Ensure authselect
        changes are applied
      ansible.builtin.command:
        cmd: authselect apply-changes -b
      when:
      - result_authselect_present.stat.exists
      - |-
        (result_pam_set_password_hashing_algorithm_passwordauth_add is defined and result_pam_set_password_hashing_algorithm_passwordauth_add.changed)
         or (result_pam_set_password_hashing_algorithm_passwordauth_edit is defined and result_pam_set_password_hashing_algorithm_passwordauth_edit.changed)
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    - result_pam_password_auth_file_present.stat.exists
    tags:
    - CJIS-5.6.2.2
    - DISA-STIG-RHEL-08-010160
    - NIST-800-171-3.13.11
    - NIST-800-53-CM-6(a)
    - NIST-800-53-IA-5(1)(c)
    - NIST-800-53-IA-5(c)
    - PCI-DSS-Req-8.2.1
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - set_password_hashing_algorithm_passwordauth

  - name: Set PAM Password Hashing Algorithm - password-auth - Check if /etc/pam.d/password-auth
      File is Present
    ansible.builtin.stat:
      path: /etc/pam.d/password-auth
    register: result_pam_password_auth_file_present
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    tags:
    - CJIS-5.6.2.2
    - DISA-STIG-RHEL-08-010160
    - NIST-800-171-3.13.11
    - NIST-800-53-CM-6(a)
    - NIST-800-53-IA-5(1)(c)
    - NIST-800-53-IA-5(c)
    - PCI-DSS-Req-8.2.1
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - set_password_hashing_algorithm_passwordauth

  - name: Set PAM Password Hashing Algorithm - password-auth - Check The Proper Remediation
      For The System
    block:

    - name: Set PAM Password Hashing Algorithm - password-auth - Define the PAM file
        to be edited as a local fact
      ansible.builtin.set_fact:
        pam_file_path: /etc/pam.d/password-auth

    - name: Set PAM Password Hashing Algorithm - password-auth - Check if system relies
        on authselect tool
      ansible.builtin.stat:
        path: /usr/bin/authselect
      register: result_authselect_present

    - name: Set PAM Password Hashing Algorithm - password-auth - Ensure authselect
        custom profile is used if authselect is present
      block:

      - name: Set PAM Password Hashing Algorithm - password-auth - Check integrity
          of authselect current profile
        ansible.builtin.command:
          cmd: authselect check
        register: result_authselect_check_cmd
        changed_when: false
        check_mode: false
        failed_when: false

      - name: Set PAM Password Hashing Algorithm - password-auth - Informative message
          based on the authselect integrity check result
        ansible.builtin.assert:
          that:
          - ansible_check_mode or result_authselect_check_cmd.rc == 0
          fail_msg:
          - authselect integrity check failed. Remediation aborted!
          - This remediation could not be applied because an authselect profile was
            not selected or the selected profile is not intact.
          - It is not recommended to manually edit the PAM files when authselect tool
            is available.
          - In cases where the default authselect profile does not cover a specific
            demand, a custom authselect profile is recommended.
          success_msg:
          - authselect integrity check passed

      - name: Set PAM Password Hashing Algorithm - password-auth - Get authselect
          current profile
        ansible.builtin.shell:
          cmd: authselect current -r | awk '{ print $1 }'
        register: result_authselect_profile
        changed_when: false
        when:
        - result_authselect_check_cmd is success

      - name: Set PAM Password Hashing Algorithm - password-auth - Define the current
          authselect profile as a local fact
        ansible.builtin.set_fact:
          authselect_current_profile: '{{ result_authselect_profile.stdout }}'
          authselect_custom_profile: '{{ result_authselect_profile.stdout }}'
        when:
        - result_authselect_profile is not skipped
        - result_authselect_profile.stdout is match("custom/")

      - name: Set PAM Password Hashing Algorithm - password-auth - Define the new
          authselect custom profile as a local fact
        ansible.builtin.set_fact:
          authselect_current_profile: '{{ result_authselect_profile.stdout }}'
          authselect_custom_profile: custom/hardening
        when:
        - result_authselect_profile is not skipped
        - result_authselect_profile.stdout is not match("custom/")

      - name: Set PAM Password Hashing Algorithm - password-auth - Get authselect
          current features to also enable them in the custom profile
        ansible.builtin.shell:
          cmd: authselect current | tail -n+3 | awk '{ print $2 }'
        register: result_authselect_features
        changed_when: false
        check_mode: false
        when:
        - result_authselect_profile is not skipped
        - authselect_current_profile is not match("custom/")

      - name: Set PAM Password Hashing Algorithm - password-auth - Check if any custom
          profile with the same name was already created
        ansible.builtin.stat:
          path: /etc/authselect/{{ authselect_custom_profile }}
        register: result_authselect_custom_profile_present
        changed_when: false
        when:
        - result_authselect_profile is not skipped
        - authselect_current_profile is not match("custom/")

      - name: Set PAM Password Hashing Algorithm - password-auth - Create an authselect
          custom profile based on the current profile
        ansible.builtin.command:
          cmd: authselect create-profile hardening -b {{ authselect_current_profile
            }}
        when:
        - result_authselect_profile is not skipped
        - result_authselect_check_cmd is success
        - authselect_current_profile is not match("^(custom/|local)")
        - not result_authselect_custom_profile_present.stat.exists

      - name: Set PAM Password Hashing Algorithm - password-auth - Create an authselect
          custom profile based on sssd profile
        ansible.builtin.command:
          cmd: authselect create-profile hardening -b sssd
        when:
        - result_authselect_profile is not skipped
        - result_authselect_check_cmd is success
        - authselect_current_profile is match("local")
        - not result_authselect_custom_profile_present.stat.exists

      - name: Set PAM Password Hashing Algorithm - password-auth - Ensure authselect
          changes are applied
        ansible.builtin.command:
          cmd: authselect apply-changes -b --backup=before-hardening-custom-profile
        when:
        - result_authselect_check_cmd is success
        - result_authselect_profile is not skipped
        - authselect_current_profile is not match("custom/")
        - authselect_custom_profile is not match(authselect_current_profile)

      - name: Set PAM Password Hashing Algorithm - password-auth - Ensure the authselect
          custom profile is selected
        ansible.builtin.command:
          cmd: authselect select {{ authselect_custom_profile }}
        register: result_pam_authselect_select_profile
        when:
        - result_authselect_check_cmd is success
        - result_authselect_profile is not skipped
        - authselect_current_profile is not match("custom/")
        - authselect_custom_profile is not match(authselect_current_profile)

      - name: Set PAM Password Hashing Algorithm - password-auth - Restore the authselect
          features in the custom profile
        ansible.builtin.command:
          cmd: authselect enable-feature {{ item }}
        loop: '{{ result_authselect_features.stdout_lines }}'
        register: result_pam_authselect_restore_features
        when:
        - result_authselect_profile is not skipped
        - result_authselect_features is not skipped
        - result_pam_authselect_select_profile is not skipped

      - name: Set PAM Password Hashing Algorithm - password-auth - Ensure authselect
          changes are applied
        ansible.builtin.command:
          cmd: authselect apply-changes -b --backup=after-hardening-custom-profile
        when:
        - result_authselect_check_cmd is success
        - result_authselect_profile is not skipped
        - result_pam_authselect_restore_features is not skipped

      - name: Set PAM Password Hashing Algorithm - password-auth - Change the PAM
          file to be edited according to the custom authselect profile
        ansible.builtin.set_fact:
          pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path
            | basename }}
        when:
        - authselect_custom_profile is defined
      when:
      - result_authselect_present.stat.exists

    - name: Set PAM Password Hashing Algorithm - password-auth - Check if "{{ pam_file_path
        }}" File is Present
      ansible.builtin.stat:
        path: '{{ pam_file_path }}'
      register: pam_file_path_present

    - name: Set PAM Password Hashing Algorithm - password-auth - Ensure That Only
        the Correct Hashing Algorithm Option For pam_unix.so Is Used in {{ pam_file_path
        }}
      ansible.builtin.replace:
        dest: '{{ pam_file_path }}'
        regexp: (^\s*password.*pam_unix\.so.*)\b{{ item }}\b\s*(.*)
        replace: \1\2
      when:
      - item != var_password_hashing_algorithm_pam.split('|')[0]
      - pam_file_path_present.stat.exists
      loop:
      - sha512
      - yescrypt
      - gost_yescrypt
      - blowfish
      - sha256
      - md5
      - bigcrypt
      register: result_pam_hashing_options_removal

    - name: Set PAM Password Hashing Algorithm - password-auth - Ensure authselect
        changes are applied
      ansible.builtin.command:
        cmd: authselect apply-changes -b
      when:
      - result_authselect_present.stat.exists
      - result_pam_hashing_options_removal is changed
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    - result_pam_password_auth_file_present.stat.exists
    tags:
    - CJIS-5.6.2.2
    - DISA-STIG-RHEL-08-010160
    - NIST-800-171-3.13.11
    - NIST-800-53-CM-6(a)
    - NIST-800-53-IA-5(1)(c)
    - NIST-800-53-IA-5(c)
    - PCI-DSS-Req-8.2.1
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - set_password_hashing_algorithm_passwordauth

  - name: Set PAM Password Hashing Algorithm - system-auth - Check if /etc/pam.d/system-auth
      file is present
    ansible.builtin.stat:
      path: /etc/pam.d/system-auth
    register: result_pam_auth_file_present
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    tags:
    - CJIS-5.6.2.2
    - DISA-STIG-RHEL-08-010159
    - NIST-800-171-3.13.11
    - NIST-800-53-CM-6(a)
    - NIST-800-53-IA-5(1)(c)
    - NIST-800-53-IA-5(c)
    - PCI-DSS-Req-8.2.1
    - PCI-DSSv4-8.3
    - PCI-DSSv4-8.3.2
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - set_password_hashing_algorithm_systemauth

  - name: Set PAM Password Hashing Algorithm - system-auth - Check the proper remediation
      for the system
    block:

    - name: Set PAM Password Hashing Algorithm - system-auth - Define the PAM file
        to be edited as a local fact
      ansible.builtin.set_fact:
        pam_file_path: /etc/pam.d/system-auth

    - name: Set PAM Password Hashing Algorithm - system-auth - Check if system relies
        on authselect tool
      ansible.builtin.stat:
        path: /usr/bin/authselect
      register: result_authselect_present

    - name: Set PAM Password Hashing Algorithm - system-auth - Ensure authselect custom
        profile is used if authselect is present
      block:

      - name: Set PAM Password Hashing Algorithm - system-auth - Check integrity of
          authselect current profile
        ansible.builtin.command:
          cmd: authselect check
        register: result_authselect_check_cmd
        changed_when: false
        check_mode: false
        failed_when: false

      - name: Set PAM Password Hashing Algorithm - system-auth - Informative message
          based on the authselect integrity check result
        ansible.builtin.assert:
          that:
          - ansible_check_mode or result_authselect_check_cmd.rc == 0
          fail_msg:
          - authselect integrity check failed. Remediation aborted!
          - This remediation could not be applied because an authselect profile was
            not selected or the selected profile is not intact.
          - It is not recommended to manually edit the PAM files when authselect tool
            is available.
          - In cases where the default authselect profile does not cover a specific
            demand, a custom authselect profile is recommended.
          success_msg:
          - authselect integrity check passed

      - name: Set PAM Password Hashing Algorithm - system-auth - Get authselect current
          profile
        ansible.builtin.shell:
          cmd: authselect current -r | awk '{ print $1 }'
        register: result_authselect_profile
        changed_when: false
        when:
        - result_authselect_check_cmd is success

      - name: Set PAM Password Hashing Algorithm - system-auth - Define the current
          authselect profile as a local fact
        ansible.builtin.set_fact:
          authselect_current_profile: '{{ result_authselect_profile.stdout }}'
          authselect_custom_profile: '{{ result_authselect_profile.stdout }}'
        when:
        - result_authselect_profile is not skipped
        - result_authselect_profile.stdout is match("custom/")

      - name: Set PAM Password Hashing Algorithm - system-auth - Define the new authselect
          custom profile as a local fact
        ansible.builtin.set_fact:
          authselect_current_profile: '{{ result_authselect_profile.stdout }}'
          authselect_custom_profile: custom/hardening
        when:
        - result_authselect_profile is not skipped
        - result_authselect_profile.stdout is not match("custom/")

      - name: Set PAM Password Hashing Algorithm - system-auth - Get authselect current
          features to also enable them in the custom profile
        ansible.builtin.shell:
          cmd: authselect current | tail -n+3 | awk '{ print $2 }'
        register: result_authselect_features
        changed_when: false
        check_mode: false
        when:
        - result_authselect_profile is not skipped
        - authselect_current_profile is not match("custom/")

      - name: Set PAM Password Hashing Algorithm - system-auth - Check if any custom
          profile with the same name was already created
        ansible.builtin.stat:
          path: /etc/authselect/{{ authselect_custom_profile }}
        register: result_authselect_custom_profile_present
        changed_when: false
        when:
        - result_authselect_profile is not skipped
        - authselect_current_profile is not match("custom/")

      - name: Set PAM Password Hashing Algorithm - system-auth - Create an authselect
          custom profile based on the current profile
        ansible.builtin.command:
          cmd: authselect create-profile hardening -b {{ authselect_current_profile
            }}
        when:
        - result_authselect_profile is not skipped
        - result_authselect_check_cmd is success
        - authselect_current_profile is not match("^(custom/|local)")
        - not result_authselect_custom_profile_present.stat.exists

      - name: Set PAM Password Hashing Algorithm - system-auth - Create an authselect
          custom profile based on sssd profile
        ansible.builtin.command:
          cmd: authselect create-profile hardening -b sssd
        when:
        - result_authselect_profile is not skipped
        - result_authselect_check_cmd is success
        - authselect_current_profile is match("local")
        - not result_authselect_custom_profile_present.stat.exists

      - name: Set PAM Password Hashing Algorithm - system-auth - Ensure authselect
          changes are applied
        ansible.builtin.command:
          cmd: authselect apply-changes -b --backup=before-hardening-custom-profile
        when:
        - result_authselect_check_cmd is success
        - result_authselect_profile is not skipped
        - authselect_current_profile is not match("custom/")
        - authselect_custom_profile is not match(authselect_current_profile)

      - name: Set PAM Password Hashing Algorithm - system-auth - Ensure the authselect
          custom profile is selected
        ansible.builtin.command:
          cmd: authselect select {{ authselect_custom_profile }}
        register: result_pam_authselect_select_profile
        when:
        - result_authselect_check_cmd is success
        - result_authselect_profile is not skipped
        - authselect_current_profile is not match("custom/")
        - authselect_custom_profile is not match(authselect_current_profile)

      - name: Set PAM Password Hashing Algorithm - system-auth - Restore the authselect
          features in the custom profile
        ansible.builtin.command:
          cmd: authselect enable-feature {{ item }}
        loop: '{{ result_authselect_features.stdout_lines }}'
        register: result_pam_authselect_restore_features
        when:
        - result_authselect_profile is not skipped
        - result_authselect_features is not skipped
        - result_pam_authselect_select_profile is not skipped

      - name: Set PAM Password Hashing Algorithm - system-auth - Ensure authselect
          changes are applied
        ansible.builtin.command:
          cmd: authselect apply-changes -b --backup=after-hardening-custom-profile
        when:
        - result_authselect_check_cmd is success
        - result_authselect_profile is not skipped
        - result_pam_authselect_restore_features is not skipped

      - name: Set PAM Password Hashing Algorithm - system-auth - Change the PAM file
          to be edited according to the custom authselect profile
        ansible.builtin.set_fact:
          pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path
            | basename }}
        when:
        - authselect_custom_profile is defined
      when:
      - result_authselect_present.stat.exists

    - name: Set PAM Password Hashing Algorithm - system-auth - Define a fact for control
        already filtered in case filters are used
      ansible.builtin.set_fact:
        pam_module_control: sufficient

    - name: Set PAM Password Hashing Algorithm - system-auth - Check if expected PAM
        module line is present in {{ pam_file_path }}
      ansible.builtin.lineinfile:
        path: '{{ pam_file_path }}'
        regexp: ^\s*password\s+{{ pam_module_control | regex_escape() }}\s+pam_unix.so\s*.*
        state: absent
      check_mode: true
      changed_when: false
      register: result_pam_line_present

    - name: Set PAM Password Hashing Algorithm - system-auth - Include or update the
        PAM module line in {{ pam_file_path }}
      block:

      - name: Set PAM Password Hashing Algorithm - system-auth - Check if required
          PAM module line is present in {{ pam_file_path }} with different control
        ansible.builtin.lineinfile:
          path: '{{ pam_file_path }}'
          regexp: ^\s*password\s+.*\s+pam_unix.so\s*
          state: absent
        check_mode: true
        changed_when: false
        register: result_pam_line_other_control_present

      - name: Set PAM Password Hashing Algorithm - system-auth - Ensure the correct
          control for the required PAM module line in {{ pam_file_path }}
        ansible.builtin.replace:
          dest: '{{ pam_file_path }}'
          regexp: ^(\s*password\s+).*(\bpam_unix.so.*)
          replace: \1{{ pam_module_control }} \2
        register: result_pam_module_edit
        when:
        - result_pam_line_other_control_present.found == 1

      - name: Set PAM Password Hashing Algorithm - system-auth - Ensure the required
          PAM module line is included in {{ pam_file_path }}
        ansible.builtin.lineinfile:
          dest: '{{ pam_file_path }}'
          line: password    {{ pam_module_control }}    pam_unix.so
        register: result_pam_module_add
        when:
        - result_pam_line_other_control_present.found == 0 or result_pam_line_other_control_present.found
          > 1

      - name: Set PAM Password Hashing Algorithm - system-auth - Ensure authselect
          changes are applied
        ansible.builtin.command:
          cmd: authselect apply-changes -b
        when:
        - result_authselect_present is defined
        - result_authselect_present.stat.exists
        - |-
          (result_pam_module_add is defined and result_pam_module_add.changed)
           or (result_pam_module_edit is defined and result_pam_module_edit.changed)
      when:
      - result_pam_line_present.found is defined
      - result_pam_line_present.found == 0

    - name: Set PAM Password Hashing Algorithm - system-auth - Define a fact for control
        already filtered in case filters are used
      ansible.builtin.set_fact:
        pam_module_control: sufficient

    - name: Set PAM Password Hashing Algorithm - system-auth - Check if the required
        PAM module option is present in {{ pam_file_path }}
      ansible.builtin.lineinfile:
        path: '{{ pam_file_path }}'
        regexp: ^\s*password\s+{{ pam_module_control | regex_escape() }}\s+pam_unix.so\s*.*\s{{
          var_password_hashing_algorithm_pam.split("|")[0] }}\b
        state: absent
      check_mode: true
      changed_when: false
      register: result_pam_module_set_password_hashing_algorithm_systemauth_option_present

    - name: Set PAM Password Hashing Algorithm - system-auth - Ensure the "{{ var_password_hashing_algorithm_pam.split("|")[0]
        }}" PAM option for "pam_unix.so" is included in {{ pam_file_path }}
      ansible.builtin.lineinfile:
        path: '{{ pam_file_path }}'
        backrefs: true
        regexp: ^(\s*password\s+{{ pam_module_control | regex_escape() }}\s+pam_unix.so.*)
        line: \1 {{ var_password_hashing_algorithm_pam.split("|")[0] }}
        state: present
      register: result_pam_set_password_hashing_algorithm_systemauth_add
      when:
      - result_pam_module_set_password_hashing_algorithm_systemauth_option_present.found
        is defined
      - result_pam_module_set_password_hashing_algorithm_systemauth_option_present.found
        == 0

    - name: Set PAM Password Hashing Algorithm - system-auth - Ensure authselect changes
        are applied
      ansible.builtin.command:
        cmd: authselect apply-changes -b
      when:
      - result_authselect_present.stat.exists
      - |-
        (result_pam_set_password_hashing_algorithm_systemauth_add is defined and result_pam_set_password_hashing_algorithm_systemauth_add.changed)
         or (result_pam_set_password_hashing_algorithm_systemauth_edit is defined and result_pam_set_password_hashing_algorithm_systemauth_edit.changed)
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    - result_pam_auth_file_present.stat.exists
    tags:
    - CJIS-5.6.2.2
    - DISA-STIG-RHEL-08-010159
    - NIST-800-171-3.13.11
    - NIST-800-53-CM-6(a)
    - NIST-800-53-IA-5(1)(c)
    - NIST-800-53-IA-5(c)
    - PCI-DSS-Req-8.2.1
    - PCI-DSSv4-8.3
    - PCI-DSSv4-8.3.2
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - set_password_hashing_algorithm_systemauth

  - name: Set PAM Password Hashing Algorithm - system-auth - Check if /etc/pam.d/system-auth
      File is Present
    ansible.builtin.stat:
      path: /etc/pam.d/system-auth
    register: result_pam_auth_file_present
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    tags:
    - CJIS-5.6.2.2
    - DISA-STIG-RHEL-08-010159
    - NIST-800-171-3.13.11
    - NIST-800-53-CM-6(a)
    - NIST-800-53-IA-5(1)(c)
    - NIST-800-53-IA-5(c)
    - PCI-DSS-Req-8.2.1
    - PCI-DSSv4-8.3
    - PCI-DSSv4-8.3.2
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - set_password_hashing_algorithm_systemauth

  - name: Set PAM Password Hashing Algorithm - system-auth - Check The Proper Remediation
      For The System
    block:

    - name: Set PAM Password Hashing Algorithm - system-auth - Define the PAM file
        to be edited as a local fact
      ansible.builtin.set_fact:
        pam_file_path: /etc/pam.d/system-auth

    - name: Set PAM Password Hashing Algorithm - system-auth - Check if system relies
        on authselect tool
      ansible.builtin.stat:
        path: /usr/bin/authselect
      register: result_authselect_present

    - name: Set PAM Password Hashing Algorithm - system-auth - Ensure authselect custom
        profile is used if authselect is present
      block:

      - name: Set PAM Password Hashing Algorithm - system-auth - Check integrity of
          authselect current profile
        ansible.builtin.command:
          cmd: authselect check
        register: result_authselect_check_cmd
        changed_when: false
        check_mode: false
        failed_when: false

      - name: Set PAM Password Hashing Algorithm - system-auth - Informative message
          based on the authselect integrity check result
        ansible.builtin.assert:
          that:
          - ansible_check_mode or result_authselect_check_cmd.rc == 0
          fail_msg:
          - authselect integrity check failed. Remediation aborted!
          - This remediation could not be applied because an authselect profile was
            not selected or the selected profile is not intact.
          - It is not recommended to manually edit the PAM files when authselect tool
            is available.
          - In cases where the default authselect profile does not cover a specific
            demand, a custom authselect profile is recommended.
          success_msg:
          - authselect integrity check passed

      - name: Set PAM Password Hashing Algorithm - system-auth - Get authselect current
          profile
        ansible.builtin.shell:
          cmd: authselect current -r | awk '{ print $1 }'
        register: result_authselect_profile
        changed_when: false
        when:
        - result_authselect_check_cmd is success

      - name: Set PAM Password Hashing Algorithm - system-auth - Define the current
          authselect profile as a local fact
        ansible.builtin.set_fact:
          authselect_current_profile: '{{ result_authselect_profile.stdout }}'
          authselect_custom_profile: '{{ result_authselect_profile.stdout }}'
        when:
        - result_authselect_profile is not skipped
        - result_authselect_profile.stdout is match("custom/")

      - name: Set PAM Password Hashing Algorithm - system-auth - Define the new authselect
          custom profile as a local fact
        ansible.builtin.set_fact:
          authselect_current_profile: '{{ result_authselect_profile.stdout }}'
          authselect_custom_profile: custom/hardening
        when:
        - result_authselect_profile is not skipped
        - result_authselect_profile.stdout is not match("custom/")

      - name: Set PAM Password Hashing Algorithm - system-auth - Get authselect current
          features to also enable them in the custom profile
        ansible.builtin.shell:
          cmd: authselect current | tail -n+3 | awk '{ print $2 }'
        register: result_authselect_features
        changed_when: false
        check_mode: false
        when:
        - result_authselect_profile is not skipped
        - authselect_current_profile is not match("custom/")

      - name: Set PAM Password Hashing Algorithm - system-auth - Check if any custom
          profile with the same name was already created
        ansible.builtin.stat:
          path: /etc/authselect/{{ authselect_custom_profile }}
        register: result_authselect_custom_profile_present
        changed_when: false
        when:
        - result_authselect_profile is not skipped
        - authselect_current_profile is not match("custom/")

      - name: Set PAM Password Hashing Algorithm - system-auth - Create an authselect
          custom profile based on the current profile
        ansible.builtin.command:
          cmd: authselect create-profile hardening -b {{ authselect_current_profile
            }}
        when:
        - result_authselect_profile is not skipped
        - result_authselect_check_cmd is success
        - authselect_current_profile is not match("^(custom/|local)")
        - not result_authselect_custom_profile_present.stat.exists

      - name: Set PAM Password Hashing Algorithm - system-auth - Create an authselect
          custom profile based on sssd profile
        ansible.builtin.command:
          cmd: authselect create-profile hardening -b sssd
        when:
        - result_authselect_profile is not skipped
        - result_authselect_check_cmd is success
        - authselect_current_profile is match("local")
        - not result_authselect_custom_profile_present.stat.exists

      - name: Set PAM Password Hashing Algorithm - system-auth - Ensure authselect
          changes are applied
        ansible.builtin.command:
          cmd: authselect apply-changes -b --backup=before-hardening-custom-profile
        when:
        - result_authselect_check_cmd is success
        - result_authselect_profile is not skipped
        - authselect_current_profile is not match("custom/")
        - authselect_custom_profile is not match(authselect_current_profile)

      - name: Set PAM Password Hashing Algorithm - system-auth - Ensure the authselect
          custom profile is selected
        ansible.builtin.command:
          cmd: authselect select {{ authselect_custom_profile }}
        register: result_pam_authselect_select_profile
        when:
        - result_authselect_check_cmd is success
        - result_authselect_profile is not skipped
        - authselect_current_profile is not match("custom/")
        - authselect_custom_profile is not match(authselect_current_profile)

      - name: Set PAM Password Hashing Algorithm - system-auth - Restore the authselect
          features in the custom profile
        ansible.builtin.command:
          cmd: authselect enable-feature {{ item }}
        loop: '{{ result_authselect_features.stdout_lines }}'
        register: result_pam_authselect_restore_features
        when:
        - result_authselect_profile is not skipped
        - result_authselect_features is not skipped
        - result_pam_authselect_select_profile is not skipped

      - name: Set PAM Password Hashing Algorithm - system-auth - Ensure authselect
          changes are applied
        ansible.builtin.command:
          cmd: authselect apply-changes -b --backup=after-hardening-custom-profile
        when:
        - result_authselect_check_cmd is success
        - result_authselect_profile is not skipped
        - result_pam_authselect_restore_features is not skipped

      - name: Set PAM Password Hashing Algorithm - system-auth - Change the PAM file
          to be edited according to the custom authselect profile
        ansible.builtin.set_fact:
          pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path
            | basename }}
        when:
        - authselect_custom_profile is defined
      when:
      - result_authselect_present.stat.exists

    - name: Set PAM Password Hashing Algorithm - system-auth - Check if "{{ pam_file_path
        }}" File is Present
      ansible.builtin.stat:
        path: '{{ pam_file_path }}'
      register: pam_file_path_present

    - name: Set PAM Password Hashing Algorithm - system-auth - Ensure That Only the
        Correct Hashing Algorithm Option For pam_unix.so Is Used in {{ pam_file_path
        }}
      ansible.builtin.replace:
        dest: '{{ pam_file_path }}'
        regexp: (^\s*password.*pam_unix\.so.*)\b{{ item }}\b\s*(.*)
        replace: \1\2
      when:
      - item != var_password_hashing_algorithm_pam.split('|')[0]
      - pam_file_path_present.stat.exists
      loop:
      - sha512
      - yescrypt
      - gost_yescrypt
      - blowfish
      - sha256
      - md5
      - bigcrypt
      register: result_pam_hashing_options_removal

    - name: Set PAM Password Hashing Algorithm - system-auth - Ensure authselect changes
        are applied
      ansible.builtin.command:
        cmd: authselect apply-changes -b
      when:
      - result_authselect_present.stat.exists
      - result_pam_hashing_options_removal is changed
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    - result_pam_auth_file_present.stat.exists
    tags:
    - CJIS-5.6.2.2
    - DISA-STIG-RHEL-08-010159
    - NIST-800-171-3.13.11
    - NIST-800-53-CM-6(a)
    - NIST-800-53-IA-5(1)(c)
    - NIST-800-53-IA-5(c)
    - PCI-DSS-Req-8.2.1
    - PCI-DSSv4-8.3
    - PCI-DSSv4-8.3.2
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - set_password_hashing_algorithm_systemauth

  - name: Set Account Expiration Following Inactivity
    ansible.builtin.lineinfile:
      create: true
      dest: /etc/default/useradd
      regexp: ^INACTIVE
      line: INACTIVE={{ var_account_disable_post_pw_expiration }}
    when:
    - '"kernel" in ansible_facts.packages'
    - '"shadow-utils" in ansible_facts.packages'
    tags:
    - CJIS-5.6.2.1.1
    - DISA-STIG-RHEL-08-020260
    - NIST-800-171-3.5.6
    - NIST-800-53-AC-2(3)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-IA-4(e)
    - PCI-DSS-Req-8.1.4
    - PCI-DSSv4-8.2
    - PCI-DSSv4-8.2.6
    - account_disable_post_pw_expiration
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Set Password Maximum Age
    ansible.builtin.lineinfile:
      create: true
      dest: /etc/login.defs
      regexp: ^#?PASS_MAX_DAYS
      line: PASS_MAX_DAYS {{ var_accounts_maximum_age_login_defs }}
    when:
    - '"kernel" in ansible_facts.packages'
    - '"shadow-utils" in ansible_facts.packages'
    tags:
    - CJIS-5.6.2.1
    - DISA-STIG-RHEL-08-020200
    - NIST-800-171-3.5.6
    - NIST-800-53-CM-6(a)
    - NIST-800-53-IA-5(1)(d)
    - NIST-800-53-IA-5(f)
    - PCI-DSS-Req-8.2.4
    - PCI-DSSv4-8.3
    - PCI-DSSv4-8.3.9
    - accounts_maximum_age_login_defs
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Collect users with not correct maximum time period between password changes
    ansible.builtin.command:
      cmd: awk -F':' '(/^[^:]+:[^!*]/ && ($5 > {{ var_accounts_maximum_age_login_defs
        }} || $5 == "")) {print $1}' /etc/shadow
    register: user_names
    changed_when: false
    check_mode: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-020210
    - NIST-800-53-CM-6(a)
    - NIST-800-53-IA-5(1)(d)
    - NIST-800-53-IA-5(f)
    - PCI-DSSv4-8.3
    - PCI-DSSv4-8.3.9
    - accounts_password_set_max_life_existing
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Change the maximum time period between password changes
    ansible.builtin.user:
      user: '{{ item }}'
      password_expire_max: '{{ var_accounts_maximum_age_login_defs }}'
    with_items: '{{ user_names.stdout_lines }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - user_names.stdout_lines | length > 0
    tags:
    - DISA-STIG-RHEL-08-020210
    - NIST-800-53-CM-6(a)
    - NIST-800-53-IA-5(1)(d)
    - NIST-800-53-IA-5(f)
    - PCI-DSSv4-8.3
    - PCI-DSSv4-8.3.9
    - accounts_password_set_max_life_existing
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Set Existing Passwords Warning Age - Collect Users With Incorrect Number
      of Days of Warning Before Password Expires
    ansible.builtin.command:
      cmd: awk -F':' '(($6 < {{ var_accounts_password_warn_age_login_defs }} || $6
        == "") && $2 ~ /^\$/) {print $1}' /etc/shadow
    register: result_pass_warn_age_user_names
    changed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-CM-6(a)
    - NIST-800-53-IA-5(1)(d)
    - NIST-800-53-IA-5(f)
    - PCI-DSSv4-8.3
    - PCI-DSSv4-8.3.9
    - accounts_password_set_warn_age_existing
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set Existing Passwords Warning Age - Ensure the Number of Days of Warning
      Before Password Expires
    ansible.builtin.command:
      cmd: chage --warndays {{ var_accounts_password_warn_age_login_defs }} {{ item
        }}
    with_items: '{{ result_pass_warn_age_user_names.stdout_lines }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - result_pass_warn_age_user_names is not skipped and result_pass_warn_age_user_names.stdout_lines
      | length > 0
    tags:
    - NIST-800-53-CM-6(a)
    - NIST-800-53-IA-5(1)(d)
    - NIST-800-53-IA-5(f)
    - PCI-DSSv4-8.3
    - PCI-DSSv4-8.3.9
    - accounts_password_set_warn_age_existing
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set Password Warning Age
    ansible.builtin.lineinfile:
      dest: /etc/login.defs
      regexp: ^PASS_WARN_AGE *[0-9]*
      state: present
      line: PASS_WARN_AGE        {{ var_accounts_password_warn_age_login_defs }}
      create: true
    when:
    - '"kernel" in ansible_facts.packages'
    - '"shadow-utils" in ansible_facts.packages'
    tags:
    - NIST-800-171-3.5.8
    - NIST-800-53-CM-6(a)
    - NIST-800-53-IA-5(1)(d)
    - NIST-800-53-IA-5(f)
    - PCI-DSS-Req-8.2.4
    - PCI-DSSv4-8.3
    - PCI-DSSv4-8.3.9
    - accounts_password_warn_age_login_defs
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Collect users with not correct INACTIVE parameter set
    ansible.builtin.command:
      cmd: awk -F':' '(($7 > {{ var_account_disable_post_pw_expiration }} || $7 ==
        "") && $2 ~ /^\$/) {print $1}' /etc/shadow
    register: user_names
    changed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-171-3.5.6
    - NIST-800-53-AC-2(3)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-IA-4(e)
    - PCI-DSS-Req-8.1.4
    - PCI-DSSv4-8.2
    - PCI-DSSv4-8.2.6
    - accounts_set_post_pw_existing
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Change the period of inactivity
    ansible.builtin.command:
      cmd: chage --inactive {{ var_account_disable_post_pw_expiration }} {{ item }}
    with_items: '{{ user_names.stdout_lines }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - user_names is not skipped and user_names.stdout_lines | length > 0
    tags:
    - NIST-800-171-3.5.6
    - NIST-800-53-AC-2(3)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-IA-4(e)
    - PCI-DSS-Req-8.1.4
    - PCI-DSSv4-8.2
    - PCI-DSSv4-8.2.6
    - accounts_set_post_pw_existing
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Avoid using remember in pam_unix module - Check if /etc/pam.d/system-auth
      file is present
    ansible.builtin.stat:
      path: /etc/pam.d/system-auth
    register: result_pam_auth_file_present
    when: '"pam" in ansible_facts.packages'
    tags:
    - accounts_password_pam_unix_no_remember
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed

  - name: Avoid using remember in pam_unix module - Check the proper remediation for
      the system
    block:

    - name: Avoid using remember in pam_unix module - Define the PAM file to be edited
        as a local fact
      ansible.builtin.set_fact:
        pam_file_path: /etc/pam.d/system-auth

    - name: Avoid using remember in pam_unix module - Check if system relies on authselect
        tool
      ansible.builtin.stat:
        path: /usr/bin/authselect
      register: result_authselect_present

    - name: Avoid using remember in pam_unix module - Ensure authselect custom profile
        is used if authselect is present
      block:

      - name: Avoid using remember in pam_unix module - Check integrity of authselect
          current profile
        ansible.builtin.command:
          cmd: authselect check
        register: result_authselect_check_cmd
        changed_when: false
        check_mode: false
        failed_when: false

      - name: Avoid using remember in pam_unix module - Informative message based
          on the authselect integrity check result
        ansible.builtin.assert:
          that:
          - ansible_check_mode or result_authselect_check_cmd.rc == 0
          fail_msg:
          - authselect integrity check failed. Remediation aborted!
          - This remediation could not be applied because an authselect profile was
            not selected or the selected profile is not intact.
          - It is not recommended to manually edit the PAM files when authselect tool
            is available.
          - In cases where the default authselect profile does not cover a specific
            demand, a custom authselect profile is recommended.
          success_msg:
          - authselect integrity check passed

      - name: Avoid using remember in pam_unix module - Get authselect current profile
        ansible.builtin.shell:
          cmd: authselect current -r | awk '{ print $1 }'
        register: result_authselect_profile
        changed_when: false
        when:
        - result_authselect_check_cmd is success

      - name: Avoid using remember in pam_unix module - Define the current authselect
          profile as a local fact
        ansible.builtin.set_fact:
          authselect_current_profile: '{{ result_authselect_profile.stdout }}'
          authselect_custom_profile: '{{ result_authselect_profile.stdout }}'
        when:
        - result_authselect_profile is not skipped
        - result_authselect_profile.stdout is match("custom/")

      - name: Avoid using remember in pam_unix module - Define the new authselect
          custom profile as a local fact
        ansible.builtin.set_fact:
          authselect_current_profile: '{{ result_authselect_profile.stdout }}'
          authselect_custom_profile: custom/hardening
        when:
        - result_authselect_profile is not skipped
        - result_authselect_profile.stdout is not match("custom/")

      - name: Avoid using remember in pam_unix module - Get authselect current features
          to also enable them in the custom profile
        ansible.builtin.shell:
          cmd: authselect current | tail -n+3 | awk '{ print $2 }'
        register: result_authselect_features
        changed_when: false
        check_mode: false
        when:
        - result_authselect_profile is not skipped
        - authselect_current_profile is not match("custom/")

      - name: Avoid using remember in pam_unix module - Check if any custom profile
          with the same name was already created
        ansible.builtin.stat:
          path: /etc/authselect/{{ authselect_custom_profile }}
        register: result_authselect_custom_profile_present
        changed_when: false
        when:
        - result_authselect_profile is not skipped
        - authselect_current_profile is not match("custom/")

      - name: Avoid using remember in pam_unix module - Create an authselect custom
          profile based on the current profile
        ansible.builtin.command:
          cmd: authselect create-profile hardening -b {{ authselect_current_profile
            }}
        when:
        - result_authselect_profile is not skipped
        - result_authselect_check_cmd is success
        - authselect_current_profile is not match("^(custom/|local)")
        - not result_authselect_custom_profile_present.stat.exists

      - name: Avoid using remember in pam_unix module - Create an authselect custom
          profile based on sssd profile
        ansible.builtin.command:
          cmd: authselect create-profile hardening -b sssd
        when:
        - result_authselect_profile is not skipped
        - result_authselect_check_cmd is success
        - authselect_current_profile is match("local")
        - not result_authselect_custom_profile_present.stat.exists

      - name: Avoid using remember in pam_unix module - Ensure authselect changes
          are applied
        ansible.builtin.command:
          cmd: authselect apply-changes -b --backup=before-hardening-custom-profile
        when:
        - result_authselect_check_cmd is success
        - result_authselect_profile is not skipped
        - authselect_current_profile is not match("custom/")
        - authselect_custom_profile is not match(authselect_current_profile)

      - name: Avoid using remember in pam_unix module - Ensure the authselect custom
          profile is selected
        ansible.builtin.command:
          cmd: authselect select {{ authselect_custom_profile }}
        register: result_pam_authselect_select_profile
        when:
        - result_authselect_check_cmd is success
        - result_authselect_profile is not skipped
        - authselect_current_profile is not match("custom/")
        - authselect_custom_profile is not match(authselect_current_profile)

      - name: Avoid using remember in pam_unix module - Restore the authselect features
          in the custom profile
        ansible.builtin.command:
          cmd: authselect enable-feature {{ item }}
        loop: '{{ result_authselect_features.stdout_lines }}'
        register: result_pam_authselect_restore_features
        when:
        - result_authselect_profile is not skipped
        - result_authselect_features is not skipped
        - result_pam_authselect_select_profile is not skipped

      - name: Avoid using remember in pam_unix module - Ensure authselect changes
          are applied
        ansible.builtin.command:
          cmd: authselect apply-changes -b --backup=after-hardening-custom-profile
        when:
        - result_authselect_check_cmd is success
        - result_authselect_profile is not skipped
        - result_pam_authselect_restore_features is not skipped

      - name: Avoid using remember in pam_unix module - Change the PAM file to be
          edited according to the custom authselect profile
        ansible.builtin.set_fact:
          pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path
            | basename }}
        when:
        - authselect_custom_profile is defined
      when:
      - result_authselect_present.stat.exists

    - name: Avoid using remember in pam_unix module - Define a fact for control already
        filtered in case filters are used
      ansible.builtin.set_fact:
        pam_module_control: ''

    - name: Avoid using remember in pam_unix module - Check if {{ pam_file_path }}
        file is present
      ansible.builtin.stat:
        path: '{{ pam_file_path }}'
      register: result_pam_file_present

    - name: Avoid using remember in pam_unix module - Ensure the "remember" option
        from "pam_unix.so" is not present in {{ pam_file_path }}
      ansible.builtin.replace:
        dest: '{{ pam_file_path }}'
        regexp: (.*password.*pam_unix.so.*)\bremember\b=?[0-9a-zA-Z]*(.*)
        replace: \1\2
      register: result_pam_option_removal
      when:
      - result_pam_file_present.stat.exists

    - name: Avoid using remember in pam_unix module - Ensure authselect changes are
        applied
      ansible.builtin.command:
        cmd: authselect apply-changes -b
      when:
      - result_authselect_present.stat.exists
      - result_pam_option_removal is changed
    when:
    - '"pam" in ansible_facts.packages'
    - result_pam_auth_file_present.stat.exists
    tags:
    - accounts_password_pam_unix_no_remember
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed

  - name: Avoid using remember in pam_unix module - Check if /etc/pam.d/password-auth
      file is present
    ansible.builtin.stat:
      path: /etc/pam.d/password-auth
    register: result_pam_password_auth_file_present
    when: '"pam" in ansible_facts.packages'
    tags:
    - accounts_password_pam_unix_no_remember
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed

  - name: Avoid using remember in pam_unix module - Check the proper remediation for
      the system
    block:

    - name: Avoid using remember in pam_unix module - Define the PAM file to be edited
        as a local fact
      ansible.builtin.set_fact:
        pam_file_path: /etc/pam.d/password-auth

    - name: Avoid using remember in pam_unix module - Check if system relies on authselect
        tool
      ansible.builtin.stat:
        path: /usr/bin/authselect
      register: result_authselect_present

    - name: Avoid using remember in pam_unix module - Ensure authselect custom profile
        is used if authselect is present
      block:

      - name: Avoid using remember in pam_unix module - Check integrity of authselect
          current profile
        ansible.builtin.command:
          cmd: authselect check
        register: result_authselect_check_cmd
        changed_when: false
        check_mode: false
        failed_when: false

      - name: Avoid using remember in pam_unix module - Informative message based
          on the authselect integrity check result
        ansible.builtin.assert:
          that:
          - ansible_check_mode or result_authselect_check_cmd.rc == 0
          fail_msg:
          - authselect integrity check failed. Remediation aborted!
          - This remediation could not be applied because an authselect profile was
            not selected or the selected profile is not intact.
          - It is not recommended to manually edit the PAM files when authselect tool
            is available.
          - In cases where the default authselect profile does not cover a specific
            demand, a custom authselect profile is recommended.
          success_msg:
          - authselect integrity check passed

      - name: Avoid using remember in pam_unix module - Get authselect current profile
        ansible.builtin.shell:
          cmd: authselect current -r | awk '{ print $1 }'
        register: result_authselect_profile
        changed_when: false
        when:
        - result_authselect_check_cmd is success

      - name: Avoid using remember in pam_unix module - Define the current authselect
          profile as a local fact
        ansible.builtin.set_fact:
          authselect_current_profile: '{{ result_authselect_profile.stdout }}'
          authselect_custom_profile: '{{ result_authselect_profile.stdout }}'
        when:
        - result_authselect_profile is not skipped
        - result_authselect_profile.stdout is match("custom/")

      - name: Avoid using remember in pam_unix module - Define the new authselect
          custom profile as a local fact
        ansible.builtin.set_fact:
          authselect_current_profile: '{{ result_authselect_profile.stdout }}'
          authselect_custom_profile: custom/hardening
        when:
        - result_authselect_profile is not skipped
        - result_authselect_profile.stdout is not match("custom/")

      - name: Avoid using remember in pam_unix module - Get authselect current features
          to also enable them in the custom profile
        ansible.builtin.shell:
          cmd: authselect current | tail -n+3 | awk '{ print $2 }'
        register: result_authselect_features
        changed_when: false
        check_mode: false
        when:
        - result_authselect_profile is not skipped
        - authselect_current_profile is not match("custom/")

      - name: Avoid using remember in pam_unix module - Check if any custom profile
          with the same name was already created
        ansible.builtin.stat:
          path: /etc/authselect/{{ authselect_custom_profile }}
        register: result_authselect_custom_profile_present
        changed_when: false
        when:
        - result_authselect_profile is not skipped
        - authselect_current_profile is not match("custom/")

      - name: Avoid using remember in pam_unix module - Create an authselect custom
          profile based on the current profile
        ansible.builtin.command:
          cmd: authselect create-profile hardening -b {{ authselect_current_profile
            }}
        when:
        - result_authselect_profile is not skipped
        - result_authselect_check_cmd is success
        - authselect_current_profile is not match("^(custom/|local)")
        - not result_authselect_custom_profile_present.stat.exists

      - name: Avoid using remember in pam_unix module - Create an authselect custom
          profile based on sssd profile
        ansible.builtin.command:
          cmd: authselect create-profile hardening -b sssd
        when:
        - result_authselect_profile is not skipped
        - result_authselect_check_cmd is success
        - authselect_current_profile is match("local")
        - not result_authselect_custom_profile_present.stat.exists

      - name: Avoid using remember in pam_unix module - Ensure authselect changes
          are applied
        ansible.builtin.command:
          cmd: authselect apply-changes -b --backup=before-hardening-custom-profile
        when:
        - result_authselect_check_cmd is success
        - result_authselect_profile is not skipped
        - authselect_current_profile is not match("custom/")
        - authselect_custom_profile is not match(authselect_current_profile)

      - name: Avoid using remember in pam_unix module - Ensure the authselect custom
          profile is selected
        ansible.builtin.command:
          cmd: authselect select {{ authselect_custom_profile }}
        register: result_pam_authselect_select_profile
        when:
        - result_authselect_check_cmd is success
        - result_authselect_profile is not skipped
        - authselect_current_profile is not match("custom/")
        - authselect_custom_profile is not match(authselect_current_profile)

      - name: Avoid using remember in pam_unix module - Restore the authselect features
          in the custom profile
        ansible.builtin.command:
          cmd: authselect enable-feature {{ item }}
        loop: '{{ result_authselect_features.stdout_lines }}'
        register: result_pam_authselect_restore_features
        when:
        - result_authselect_profile is not skipped
        - result_authselect_features is not skipped
        - result_pam_authselect_select_profile is not skipped

      - name: Avoid using remember in pam_unix module - Ensure authselect changes
          are applied
        ansible.builtin.command:
          cmd: authselect apply-changes -b --backup=after-hardening-custom-profile
        when:
        - result_authselect_check_cmd is success
        - result_authselect_profile is not skipped
        - result_pam_authselect_restore_features is not skipped

      - name: Avoid using remember in pam_unix module - Change the PAM file to be
          edited according to the custom authselect profile
        ansible.builtin.set_fact:
          pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path
            | basename }}
        when:
        - authselect_custom_profile is defined
      when:
      - result_authselect_present.stat.exists

    - name: Avoid using remember in pam_unix module - Define a fact for control already
        filtered in case filters are used
      ansible.builtin.set_fact:
        pam_module_control: ''

    - name: Avoid using remember in pam_unix module - Check if {{ pam_file_path }}
        file is present
      ansible.builtin.stat:
        path: '{{ pam_file_path }}'
      register: result_pam_file_present

    - name: Avoid using remember in pam_unix module - Ensure the "remember" option
        from "pam_unix.so" is not present in {{ pam_file_path }}
      ansible.builtin.replace:
        dest: '{{ pam_file_path }}'
        regexp: (.*password.*pam_unix.so.*)\bremember\b=?[0-9a-zA-Z]*(.*)
        replace: \1\2
      register: result_pam_option_removal
      when:
      - result_pam_file_present.stat.exists

    - name: Avoid using remember in pam_unix module - Ensure authselect changes are
        applied
      ansible.builtin.command:
        cmd: authselect apply-changes -b
      when:
      - result_authselect_present.stat.exists
      - result_pam_option_removal is changed
    when:
    - '"pam" in ansible_facts.packages'
    - result_pam_password_auth_file_present.stat.exists
    tags:
    - accounts_password_pam_unix_no_remember
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed

  - name: Prevent Login to Accounts With Empty Password - Check if system relies on
      authselect
    ansible.builtin.stat:
      path: /usr/bin/authselect
    register: result_authselect_present
    when: '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.5.2
    - DISA-STIG-RHEL-08-020331
    - DISA-STIG-RHEL-08-020332
    - NIST-800-171-3.1.1
    - NIST-800-171-3.1.5
    - NIST-800-53-CM-6(a)
    - NIST-800-53-IA-5(1)(a)
    - NIST-800-53-IA-5(c)
    - PCI-DSS-Req-8.2.3
    - PCI-DSSv4-8.3
    - PCI-DSSv4-8.3.1
    - configure_strategy
    - high_severity
    - low_complexity
    - medium_disruption
    - no_empty_passwords
    - no_reboot_needed

  - name: Prevent Login to Accounts With Empty Password - Remediate using authselect
    block:

    - name: Prevent Login to Accounts With Empty Password - Check integrity of authselect
        current profile
      ansible.builtin.command:
        cmd: authselect check
      register: result_authselect_check_cmd
      changed_when: false
      check_mode: false
      failed_when: false

    - name: Prevent Login to Accounts With Empty Password - Informative message based
        on the authselect integrity check result
      ansible.builtin.assert:
        that:
        - ansible_check_mode or result_authselect_check_cmd.rc == 0
        fail_msg:
        - authselect integrity check failed. Remediation aborted!
        - This remediation could not be applied because an authselect profile was
          not selected or the selected profile is not intact.
        - It is not recommended to manually edit the PAM files when authselect tool
          is available.
        - In cases where the default authselect profile does not cover a specific
          demand, a custom authselect profile is recommended.
        success_msg:
        - authselect integrity check passed

    - name: Prevent Login to Accounts With Empty Password - Get authselect current
        features
      ansible.builtin.shell:
        cmd: authselect current | tail -n+3 | awk '{ print $2 }'
      register: result_authselect_features
      changed_when: false
      check_mode: false
      when:
      - result_authselect_check_cmd is success

    - name: Prevent Login to Accounts With Empty Password - Ensure "without-nullok"
        feature is enabled using authselect tool
      ansible.builtin.command:
        cmd: authselect enable-feature without-nullok
      register: result_authselect_enable_feature_cmd
      when:
      - result_authselect_check_cmd is success
      - result_authselect_features.stdout is not search("without-nullok")

    - name: Prevent Login to Accounts With Empty Password - Ensure authselect changes
        are applied
      ansible.builtin.command:
        cmd: authselect apply-changes -b
      when:
      - result_authselect_enable_feature_cmd is not skipped
      - result_authselect_enable_feature_cmd is success
    when:
    - '"kernel" in ansible_facts.packages'
    - result_authselect_present.stat.exists
    tags:
    - CJIS-5.5.2
    - DISA-STIG-RHEL-08-020331
    - DISA-STIG-RHEL-08-020332
    - NIST-800-171-3.1.1
    - NIST-800-171-3.1.5
    - NIST-800-53-CM-6(a)
    - NIST-800-53-IA-5(1)(a)
    - NIST-800-53-IA-5(c)
    - PCI-DSS-Req-8.2.3
    - PCI-DSSv4-8.3
    - PCI-DSSv4-8.3.1
    - configure_strategy
    - high_severity
    - low_complexity
    - medium_disruption
    - no_empty_passwords
    - no_reboot_needed

  - name: Prevent Login to Accounts With Empty Password - Remediate directly editing
      PAM files
    ansible.builtin.replace:
      dest: '{{ item }}'
      regexp: nullok
    loop:
    - /etc/pam.d/system-auth
    - /etc/pam.d/password-auth
    when:
    - '"kernel" in ansible_facts.packages'
    - not result_authselect_present.stat.exists
    tags:
    - CJIS-5.5.2
    - DISA-STIG-RHEL-08-020331
    - DISA-STIG-RHEL-08-020332
    - NIST-800-171-3.1.1
    - NIST-800-171-3.1.5
    - NIST-800-53-CM-6(a)
    - NIST-800-53-IA-5(1)(a)
    - NIST-800-53-IA-5(c)
    - PCI-DSS-Req-8.2.3
    - PCI-DSSv4-8.3
    - PCI-DSSv4-8.3.1
    - configure_strategy
    - high_severity
    - low_complexity
    - medium_disruption
    - no_empty_passwords
    - no_reboot_needed

  - name: Collect users with no password
    ansible.builtin.command: |
      awk -F: '!$2 {print $1}' /etc/shadow
    register: users_nopasswd
    changed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-010121
    - NIST-800-53-CM-6(b)
    - NIST-800-53-CM-6.1(iv)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.2
    - high_severity
    - low_complexity
    - low_disruption
    - no_empty_passwords_etc_shadow
    - no_reboot_needed
    - restrict_strategy

  - name: Lock users with no password
    ansible.builtin.command: |
      passwd -l {{ item }}
    with_items: '{{ users_nopasswd.stdout_lines }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - users_nopasswd is not skipped and users_nopasswd.stdout_lines | length > 0
    tags:
    - DISA-STIG-RHEL-08-010121
    - NIST-800-53-CM-6(b)
    - NIST-800-53-CM-6.1(iv)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.2
    - high_severity
    - low_complexity
    - low_disruption
    - no_empty_passwords_etc_shadow
    - no_reboot_needed
    - restrict_strategy

  - name: Get all /etc/passwd file entries
    ansible.builtin.getent:
      database: passwd
      split: ':'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040200
    - NIST-800-171-3.1.1
    - NIST-800-171-3.1.5
    - NIST-800-53-AC-6(5)
    - NIST-800-53-IA-2
    - NIST-800-53-IA-4(b)
    - PCI-DSS-Req-8.5
    - PCI-DSSv4-8.2
    - PCI-DSSv4-8.2.1
    - accounts_no_uid_except_zero
    - high_severity
    - low_complexity
    - low_disruption
    - no_reboot_needed
    - restrict_strategy

  - name: Lock the password of the user accounts other than root with uid 0
    ansible.builtin.command: passwd -l {{ item.key }}
    loop: '{{ getent_passwd | dict2items | rejectattr(''key'', ''equalto'', ''root'')
      | list }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - item.value.1  == '0'
    tags:
    - DISA-STIG-RHEL-08-040200
    - NIST-800-171-3.1.1
    - NIST-800-171-3.1.5
    - NIST-800-53-AC-6(5)
    - NIST-800-53-IA-2
    - NIST-800-53-IA-4(b)
    - PCI-DSS-Req-8.5
    - PCI-DSSv4-8.2
    - PCI-DSSv4-8.2.1
    - accounts_no_uid_except_zero
    - high_severity
    - low_complexity
    - low_disruption
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure the Group Used by pam_wheel.so Module Exists on System and is Empty
      - Ensure {{ var_pam_wheel_group_for_su }} Group Exists
    ansible.builtin.group:
      name: '{{ var_pam_wheel_group_for_su }}'
      state: present
    when: '"kernel" in ansible_facts.packages'
    tags:
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - ensure_pam_wheel_group_empty
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure the Group Used by pam_wheel.so Module Exists on System and is Empty
      - Ensure {{ var_pam_wheel_group_for_su }} Group is Empty
    ansible.builtin.lineinfile:
      path: /etc/group
      regexp: ^({{ var_pam_wheel_group_for_su }}:[^:]+:[0-9]+:).*$
      line: \1
      backrefs: true
    when: '"kernel" in ansible_facts.packages'
    tags:
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - ensure_pam_wheel_group_empty
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure that System Accounts Are Locked - Get All Local Users From /etc/passwd
    ansible.builtin.getent:
      database: passwd
      split: ':'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-8.2
    - PCI-DSSv4-8.2.2
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_password_auth_for_systemaccounts
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure that System Accounts Are Locked - Create local_users Variable From
      getent_passwd Facts
    ansible.builtin.set_fact:
      local_users: '{{ ansible_facts.getent_passwd | dict2items }}'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-8.2
    - PCI-DSSv4-8.2.2
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_password_auth_for_systemaccounts
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure that System Accounts Are Locked - Lock System Accounts
    ansible.builtin.user:
      name: '{{ item.key }}'
      password_lock: true
    loop: '{{ local_users }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - item.value[1]|int < 1000
    - item.key not in ['root', 'halt', 'sync', 'shutdown', 'nfsnobody']
    tags:
    - NIST-800-53-AC-6
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-8.2
    - PCI-DSSv4-8.2.2
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_password_auth_for_systemaccounts
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure that System Accounts Do Not Run a Shell Upon Login - Get All Local
      Users From /etc/passwd
    ansible.builtin.getent:
      database: passwd
      split: ':'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-6(b)
    - NIST-800-53-CM-6.1(iv)
    - PCI-DSSv4-8.2
    - PCI-DSSv4-8.2.2
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - no_shelllogin_for_systemaccounts
    - restrict_strategy

  - name: Ensure that System Accounts Do Not Run a Shell Upon Login - Create local_users
      Variable From getent_passwd Facts
    ansible.builtin.set_fact:
      local_users: '{{ ansible_facts.getent_passwd | dict2items }}'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-6(b)
    - NIST-800-53-CM-6.1(iv)
    - PCI-DSSv4-8.2
    - PCI-DSSv4-8.2.2
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - no_shelllogin_for_systemaccounts
    - restrict_strategy

  - name: Ensure that System Accounts Do Not Run a Shell Upon Login -  Disable Login
      Shell for System Accounts
    ansible.builtin.user:
      name: '{{ item.key }}'
      shell: /sbin/nologin
    loop: '{{ local_users }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - item.key not in ['root']
    - item.value[1]|int < 1000
    - item.value[5] not in ['/sbin/shutdown', '/sbin/halt', '/bin/sync']
    tags:
    - NIST-800-53-AC-6
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-6(b)
    - NIST-800-53-CM-6.1(iv)
    - PCI-DSSv4-8.2
    - PCI-DSSv4-8.2.2
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - no_shelllogin_for_systemaccounts
    - restrict_strategy

  - name: Correct any occurrence of TMOUT in /etc/profile
    ansible.builtin.replace:
      path: /etc/profile
      regexp: ^[^#].*TMOUT=.*
      replace: typeset -xr TMOUT={{ var_accounts_tmout }}
    register: profile_replaced
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-020353
    - NIST-800-171-3.1.11
    - NIST-800-53-AC-12
    - NIST-800-53-AC-2(5)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-SC-10
    - PCI-DSSv4-8.6
    - PCI-DSSv4-8.6.1
    - accounts_tmout
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Set Interactive Session Timeout
    ansible.builtin.lineinfile:
      path: /etc/profile.d/tmout.sh
      create: true
      regexp: TMOUT=
      line: typeset -xr TMOUT={{ var_accounts_tmout }}
      state: present
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-020353
    - NIST-800-171-3.1.11
    - NIST-800-53-AC-12
    - NIST-800-53-AC-2(5)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-SC-10
    - PCI-DSSv4-8.6
    - PCI-DSSv4-8.6.1
    - accounts_tmout
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: User Initialization Files Must Be Group-Owned By The Primary Group - Get
      interactive users from passwd file
    ansible.builtin.getent:
      database: passwd
    register: passwd_entries
    when: '"kernel" in ansible_facts.packages'
    tags:
    - accounts_user_dot_group_ownership
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: User Initialization Files Must Be Group-Owned By The Primary Group - Create
      list of interactive users with GID and home directory
    ansible.builtin.set_fact:
      interactive_users: '{{ interactive_users | default([]) + [{''home'': item.value[4],
        ''gid'': item.value[2]}] }}'
    loop: '{{ passwd_entries.ansible_facts.getent_passwd | dict2items }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - item.value[2] | int >= 1000 | int
    - item.value[2] | int != 65534 | int
    - item.value[4] != ""
    tags:
    - accounts_user_dot_group_ownership
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: User Initialization Files Must Be Group-Owned By The Primary Group - Find
      dot files in interactive user home directories
    ansible.builtin.find:
      paths: '{{ item.home }}'
      patterns: .*
      file_type: file
      hidden: true
      depth: 1
      follow: false
    register: user_dotfiles
    loop: '{{ interactive_users | default([]) }}'
    failed_when: false
    when:
    - '"kernel" in ansible_facts.packages'
    - item.home != ""
    tags:
    - accounts_user_dot_group_ownership
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: User Initialization Files Must Be Group-Owned By The Primary Group - Set
      correct group ownership for user initialization files
    ansible.builtin.file:
      path: '{{ item.1.path }}'
      group: '{{ item.0.item.gid }}'
      follow: false
    loop: '{{ user_dotfiles.results | subelements(''files'', skip_missing=True) }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - item.0 is not skipped
    - item.1.path is defined
    tags:
    - accounts_user_dot_group_ownership
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: User Initialization Files Must Be Owned By the Primary User - Get interactive
      users from passwd file
    ansible.builtin.getent:
      database: passwd
    register: passwd_entries
    when: '"kernel" in ansible_facts.packages'
    tags:
    - accounts_user_dot_user_ownership
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: User Initialization Files Must Be Owned By the Primary User - Create list
      of interactive users with UID and home directory
    ansible.builtin.set_fact:
      interactive_users: '{{ interactive_users | default([]) + [{''uid'': item.value[1],
        ''home'': item.value[4], ''username'': item.key}] }}'
    loop: '{{ passwd_entries.ansible_facts.getent_passwd | dict2items }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - item.value[1] | int >= 1000 | int
    - item.value[1] | int != 65534 | int
    - item.value[4] != ""
    tags:
    - accounts_user_dot_user_ownership
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: User Initialization Files Must Be Owned By the Primary User - Find dot files
      in interactive user home directories
    ansible.builtin.find:
      paths: '{{ item.home }}'
      patterns: .*
      file_type: file
      hidden: true
      depth: 1
      follow: false
    register: user_dotfiles
    loop: '{{ interactive_users | default([]) }}'
    failed_when: false
    when:
    - '"kernel" in ansible_facts.packages'
    - item.home != ""
    tags:
    - accounts_user_dot_user_ownership
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: User Initialization Files Must Be Owned By the Primary User - Set correct
      ownership for user initialization files
    ansible.builtin.file:
      path: '{{ item.1.path }}'
      owner: '{{ item.0.item.username }}'
      follow: false
    loop: '{{ user_dotfiles.results | subelements(''files'', skip_missing=True) }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - item.0 is not skipped
    - item.0 is not failed
    - item.0.item is defined
    - item.0.item.username is defined
    - item.1.path is defined
    tags:
    - accounts_user_dot_user_ownership
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Get all local users from /etc/passwd
    ansible.builtin.getent:
      database: passwd
      split: ':'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-010750
    - accounts_user_interactive_home_directory_exists
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Create local_users variable from the getent output
    ansible.builtin.set_fact:
      local_users: '{{ ansible_facts.getent_passwd|dict2items }}'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-010750
    - accounts_user_interactive_home_directory_exists
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure interactive users have a home directory exists
    ansible.builtin.user:
      name: '{{ item.key }}'
      create_home: true
    loop: '{{ local_users }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - item.value[1]|int >= 1000
    - item.value[1]|int != 65534
    tags:
    - DISA-STIG-RHEL-08-010750
    - accounts_user_interactive_home_directory_exists
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Get all local users from /etc/passwd
    ansible.builtin.getent:
      database: passwd
      split: ':'
    tags:
    - file_ownership_home_directories
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Create local_users variable from the getent output
    ansible.builtin.set_fact:
      local_users: '{{ ansible_facts.getent_passwd|dict2items }}'
    tags:
    - file_ownership_home_directories
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Test for existence of home directories to avoid creating them, but only
      fixing ownership
    ansible.builtin.stat:
      path: '{{ item.value[4] }}'
    register: path_exists
    loop: '{{ local_users }}'
    when:
    - item.value[1]|int >= 1000
    - item.value[1]|int != 65534
    tags:
    - file_ownership_home_directories
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure interactive local users are the owners of their respective home directories
    ansible.builtin.file:
      path: '{{ item.0.value[4] }}'
      owner: '{{ item.0.value[1] }}'
    loop: '{{ local_users|zip(path_exists.results)|list }}'
    when: item.1.stat is defined and item.1.stat.exists
    tags:
    - file_ownership_home_directories
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure User Bash History File Has Correct Permissions - Gather User Info
    ansible.builtin.getent:
      database: passwd
    when: '"bash" in ansible_facts.packages'
    tags:
    - file_permission_user_bash_history
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure User Bash History File Has Correct Permissions - Check Bash History
      Files Existence
    ansible.builtin.stat:
      path: '{{ item.value[4] }}/.bash_history'
    register: bash_history_files
    with_dict: '{{ ansible_facts.getent_passwd }}'
    when:
    - '"bash" in ansible_facts.packages'
    - item.value[4] != "/sbin/nologin"
    - item.key not in ["nobody", "nfsnobody"]
    - item.value[1] | int >= 1000
    tags:
    - file_permission_user_bash_history
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure User Bash History File Has Correct Permissions - Fix Bash History
      Files Permissions
    ansible.builtin.file:
      path: '{{ item.stat.path }}'
      mode: u-sx,go=
    with_items: '{{ bash_history_files.results }}'
    when:
    - '"bash" in ansible_facts.packages'
    - item.stat is defined
    - item.stat.exists
    tags:
    - file_permission_user_bash_history
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure All User Initialization Files Have Mode 0740 Or Less Permissive -
      Gather User Info
    ansible.builtin.getent:
      database: passwd
    tags:
    - file_permission_user_init_files
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure All User Initialization Files Have Mode 0740 Or Less Permissive -
      Find Init Files
    ansible.builtin.find:
      paths: '{{ item.value[4] }}'
      pattern: '{{ var_user_initialization_files_regex }}'
      hidden: true
      use_regex: true
    with_dict: '{{ ansible_facts.getent_passwd }}'
    when:
    - item.value[4] != "/sbin/nologin"
    - item.key not in ["nobody", "nfsnobody"]
    - item.value[1] | int >= 1000
    register: found_init_files
    tags:
    - file_permission_user_init_files
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure All User Initialization Files Have Mode 0740 Or Less Permissive -
      Fix Init Files Permissions
    ansible.builtin.file:
      path: '{{ item.1.path }}'
      mode: u-s,g-wxs,o=
    loop: '{{ q(''ansible.builtin.subelements'', found_init_files.results, ''files'',
      {''skip_missing'': True}) }}'
    tags:
    - file_permission_user_init_files
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Get all local users from /etc/passwd
    ansible.builtin.getent:
      database: passwd
      split: ':'
    tags:
    - DISA-STIG-RHEL-08-010730
    - file_permissions_home_directories
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Create local_users variable from the getent output
    ansible.builtin.set_fact:
      local_users: '{{ ansible_facts.getent_passwd|dict2items }}'
    tags:
    - DISA-STIG-RHEL-08-010730
    - file_permissions_home_directories
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Test for existence home directories to avoid creating them.
    ansible.builtin.stat:
      path: '{{ item.value[4] }}'
    register: path_exists
    loop: '{{ local_users }}'
    when:
    - item.value[1]|int >= 1000
    - item.value[1]|int != 65534
    - item.value[4] != "/"
    tags:
    - DISA-STIG-RHEL-08-010730
    - file_permissions_home_directories
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure interactive local users have proper permissions on their respective
      home directories
    ansible.builtin.file:
      path: '{{ item.0.value[4] }}'
      mode: u-s,g-w-s,o=-
      follow: false
      recurse: false
    loop: '{{ local_users|zip(path_exists.results)|list }}'
    when: item.1.stat is defined and item.1.stat.exists
    tags:
    - DISA-STIG-RHEL-08-010730
    - file_permissions_home_directories
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Get root paths which are not symbolic links
    ansible.builtin.stat:
      path: '{{ item }}'
    changed_when: false
    failed_when: false
    register: root_paths
    with_items: '{{ ansible_env.PATH.split('':'') }}'
    tags:
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-6(a)
    - accounts_root_path_dirs_no_write
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Disable writability to root directories
    ansible.builtin.file:
      path: '{{ item.item }}'
      mode: g-w,o-w
    with_items: '{{ root_paths.results }}'
    when:
    - root_paths.results is defined
    - item.stat.exists
    - not item.stat.islnk
    tags:
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-6(a)
    - accounts_root_path_dirs_no_write
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Check if umask in /etc/bashrc is already set
    ansible.builtin.lineinfile:
      path: /etc/bashrc
      regexp: ^[^#]*\bumask\s+\d+$
      state: absent
    check_mode: true
    changed_when: false
    register: umask_replace
    when: '"bash" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - accounts_umask_etc_bashrc
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Replace user umask in /etc/bashrc
    ansible.builtin.replace:
      path: /etc/bashrc
      regexp: ^([^#]*\b)umask\s+\d+$
      replace: \g<1>umask {{ var_accounts_user_umask }}
    when:
    - '"bash" in ansible_facts.packages'
    - umask_replace.found > 0
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - accounts_umask_etc_bashrc
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure the Default umask is Appended Correctly
    ansible.builtin.lineinfile:
      create: true
      path: /etc/bashrc
      line: umask {{ var_accounts_user_umask }}
    when:
    - '"bash" in ansible_facts.packages'
    - umask_replace.found == 0
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - accounts_umask_etc_bashrc
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Check if UMASK is already set
    ansible.builtin.lineinfile:
      path: /etc/login.defs
      regexp: ^(\s*)UMASK\s+.*
      state: absent
    check_mode: true
    changed_when: false
    register: result_umask_is_set
    when: ( "shadow-utils" in ansible_facts.packages and "kernel" in ansible_facts.packages
      )
    tags:
    - DISA-STIG-RHEL-08-020351
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - accounts_umask_etc_login_defs
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Replace user UMASK in /etc/login.defs
    ansible.builtin.replace:
      path: /etc/login.defs
      regexp: ^(\s*)UMASK(\s+).*
      replace: \g<1>UMASK\g<2>{{ var_accounts_user_umask }}
    when:
    - ( "shadow-utils" in ansible_facts.packages and "kernel" in ansible_facts.packages
      )
    - result_umask_is_set.found > 0
    tags:
    - DISA-STIG-RHEL-08-020351
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - accounts_umask_etc_login_defs
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure the Default UMASK is Appended Correctly
    ansible.builtin.lineinfile:
      create: true
      path: /etc/login.defs
      line: UMASK {{ var_accounts_user_umask }}
    when:
    - ( "shadow-utils" in ansible_facts.packages and "kernel" in ansible_facts.packages
      )
    - result_umask_is_set.found == 0
    tags:
    - DISA-STIG-RHEL-08-020351
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - accounts_umask_etc_login_defs
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure the Default Umask is Set Correctly in /etc/profile - Locate Profile
      Configuration Files Where umask Is Defined
    ansible.builtin.find:
      paths:
      - /etc/profile.d
      patterns:
      - sh.local
      - '*.sh'
      contains: ^[\s]*umask\s+\d+
    register: result_profile_d_files
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - accounts_umask_etc_profile
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure the Default Umask is Set Correctly in /etc/profile - Replace Existing
      umask Value in Files From /etc/profile.d
    ansible.builtin.replace:
      path: '{{ item.path }}'
      regexp: ^(\s*)umask\s+\d+
      replace: \1umask {{ var_accounts_user_umask }}
    loop: '{{ result_profile_d_files.files }}'
    register: result_umask_replaced_profile_d
    when: result_profile_d_files.matched
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - accounts_umask_etc_profile
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure the Default Umask is Set Correctly in /etc/profile - Ensure umask
      Is Set in /etc/profile if Not Already Set Elsewhere
    ansible.builtin.lineinfile:
      create: true
      mode: 420
      path: /etc/profile
      line: umask {{ var_accounts_user_umask }}
    when: not result_profile_d_files.matched
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - accounts_umask_etc_profile
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure the Default Umask is Set Correctly in /etc/profile - Ensure umask
      Value For All Existing umask Definition in /etc/profile
    ansible.builtin.replace:
      path: /etc/profile
      regexp: ^(\s*)umask\s+\d+
      replace: \1umask {{ var_accounts_user_umask }}
    register: result_umask_replaced_profile
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - accounts_umask_etc_profile
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Set the file_groupowner_grub2_cfg_newgroup variable if represented by gid
    ansible.builtin.set_fact:
      file_groupowner_grub2_cfg_newgroup: '0'
    when:
    - ( "grub2-common" in ansible_facts.packages and "kernel" in ansible_facts.packages
      )
    - not ('/sys/firmware/efi' is directory)
    - not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"]
      )
    tags:
    - CJIS-5.5.2.2
    - NIST-800-171-3.4.5
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-7.1
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_groupowner_grub2_cfg
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /boot/grub2/grub.cfg
    ansible.builtin.stat:
      path: /boot/grub2/grub.cfg
    register: file_exists
    when:
    - ( "grub2-common" in ansible_facts.packages and "kernel" in ansible_facts.packages
      )
    - not ('/sys/firmware/efi' is directory)
    - not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"]
      )
    tags:
    - CJIS-5.5.2.2
    - NIST-800-171-3.4.5
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-7.1
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_groupowner_grub2_cfg
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure group owner on /boot/grub2/grub.cfg
    ansible.builtin.file:
      path: /boot/grub2/grub.cfg
      follow: false
      group: '{{ file_groupowner_grub2_cfg_newgroup }}'
    when:
    - ( "grub2-common" in ansible_facts.packages and "kernel" in ansible_facts.packages
      )
    - not ('/sys/firmware/efi' is directory)
    - not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"]
      )
    - file_exists.stat is defined and file_exists.stat.exists
    tags:
    - CJIS-5.5.2.2
    - NIST-800-171-3.4.5
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-7.1
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_groupowner_grub2_cfg
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set the file_groupowner_user_cfg_newgroup variable if represented by gid
    ansible.builtin.set_fact:
      file_groupowner_user_cfg_newgroup: '0'
    when:
    - ( "grub2-common" in ansible_facts.packages and "kernel" in ansible_facts.packages
      )
    - not ('/sys/firmware/efi' is directory)
    - not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"]
      )
    tags:
    - CJIS-5.5.2.2
    - NIST-800-171-3.4.5
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-7.1
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_groupowner_user_cfg
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /boot/grub2/user.cfg
    ansible.builtin.stat:
      path: /boot/grub2/user.cfg
    register: file_exists
    when:
    - ( "grub2-common" in ansible_facts.packages and "kernel" in ansible_facts.packages
      )
    - not ('/sys/firmware/efi' is directory)
    - not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"]
      )
    tags:
    - CJIS-5.5.2.2
    - NIST-800-171-3.4.5
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-7.1
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_groupowner_user_cfg
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure group owner on /boot/grub2/user.cfg
    ansible.builtin.file:
      path: /boot/grub2/user.cfg
      follow: false
      group: '{{ file_groupowner_user_cfg_newgroup }}'
    when:
    - ( "grub2-common" in ansible_facts.packages and "kernel" in ansible_facts.packages
      )
    - not ('/sys/firmware/efi' is directory)
    - not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"]
      )
    - file_exists.stat is defined and file_exists.stat.exists
    tags:
    - CJIS-5.5.2.2
    - NIST-800-171-3.4.5
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-7.1
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_groupowner_user_cfg
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set the file_owner_grub2_cfg_newown variable if represented by uid
    ansible.builtin.set_fact:
      file_owner_grub2_cfg_newown: '0'
    when:
    - ( "grub2-common" in ansible_facts.packages and "kernel" in ansible_facts.packages
      )
    - not ('/sys/firmware/efi' is directory)
    - not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"]
      )
    tags:
    - CJIS-5.5.2.2
    - NIST-800-171-3.4.5
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-7.1
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_owner_grub2_cfg
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /boot/grub2/grub.cfg
    ansible.builtin.stat:
      path: /boot/grub2/grub.cfg
    register: file_exists
    when:
    - ( "grub2-common" in ansible_facts.packages and "kernel" in ansible_facts.packages
      )
    - not ('/sys/firmware/efi' is directory)
    - not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"]
      )
    tags:
    - CJIS-5.5.2.2
    - NIST-800-171-3.4.5
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-7.1
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_owner_grub2_cfg
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure owner on /boot/grub2/grub.cfg
    ansible.builtin.file:
      path: /boot/grub2/grub.cfg
      follow: false
      owner: '{{ file_owner_grub2_cfg_newown }}'
    when:
    - ( "grub2-common" in ansible_facts.packages and "kernel" in ansible_facts.packages
      )
    - not ('/sys/firmware/efi' is directory)
    - not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"]
      )
    - file_exists.stat is defined and file_exists.stat.exists
    tags:
    - CJIS-5.5.2.2
    - NIST-800-171-3.4.5
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-7.1
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_owner_grub2_cfg
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set the file_owner_user_cfg_newown variable if represented by uid
    ansible.builtin.set_fact:
      file_owner_user_cfg_newown: '0'
    when:
    - ( "grub2-common" in ansible_facts.packages and "kernel" in ansible_facts.packages
      )
    - not ('/sys/firmware/efi' is directory)
    - not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"]
      )
    tags:
    - CJIS-5.5.2.2
    - NIST-800-171-3.4.5
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-7.1
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_owner_user_cfg
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /boot/grub2/user.cfg
    ansible.builtin.stat:
      path: /boot/grub2/user.cfg
    register: file_exists
    when:
    - ( "grub2-common" in ansible_facts.packages and "kernel" in ansible_facts.packages
      )
    - not ('/sys/firmware/efi' is directory)
    - not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"]
      )
    tags:
    - CJIS-5.5.2.2
    - NIST-800-171-3.4.5
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-7.1
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_owner_user_cfg
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure owner on /boot/grub2/user.cfg
    ansible.builtin.file:
      path: /boot/grub2/user.cfg
      follow: false
      owner: '{{ file_owner_user_cfg_newown }}'
    when:
    - ( "grub2-common" in ansible_facts.packages and "kernel" in ansible_facts.packages
      )
    - not ('/sys/firmware/efi' is directory)
    - not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"]
      )
    - file_exists.stat is defined and file_exists.stat.exists
    tags:
    - CJIS-5.5.2.2
    - NIST-800-171-3.4.5
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-7.1
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_owner_user_cfg
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /boot/grub2/grub.cfg
    ansible.builtin.stat:
      path: /boot/grub2/grub.cfg
    register: file_exists
    when:
    - ( "grub2-common" in ansible_facts.packages and "kernel" in ansible_facts.packages
      )
    - not ('/sys/firmware/efi' is directory)
    - not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"]
      )
    tags:
    - NIST-800-171-3.4.5
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_permissions_grub2_cfg
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure permission u-xs,g-xwrs,o-xwrt on /boot/grub2/grub.cfg
    ansible.builtin.file:
      path: /boot/grub2/grub.cfg
      mode: u-xs,g-xwrs,o-xwrt
    when:
    - ( "grub2-common" in ansible_facts.packages and "kernel" in ansible_facts.packages
      )
    - not ('/sys/firmware/efi' is directory)
    - not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"]
      )
    - file_exists.stat is defined and file_exists.stat.exists
    tags:
    - NIST-800-171-3.4.5
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_permissions_grub2_cfg
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /boot/grub2/user.cfg
    ansible.builtin.stat:
      path: /boot/grub2/user.cfg
    register: file_exists
    when:
    - ( "grub2-common" in ansible_facts.packages and "kernel" in ansible_facts.packages
      )
    - not ('/sys/firmware/efi' is directory)
    - not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"]
      )
    tags:
    - NIST-800-171-3.4.5
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_permissions_user_cfg
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure permission u-xs,g-xwrs,o-xwrt on /boot/grub2/user.cfg
    ansible.builtin.file:
      path: /boot/grub2/user.cfg
      mode: u-xs,g-xwrs,o-xwrt
    when:
    - ( "grub2-common" in ansible_facts.packages and "kernel" in ansible_facts.packages
      )
    - not ('/sys/firmware/efi' is directory)
    - not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"]
      )
    - file_exists.stat is defined and file_exists.stat.exists
    tags:
    - NIST-800-171-3.4.5
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_permissions_user_cfg
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set the file_groupowner_efi_grub2_cfg_newgroup variable if represented by
      gid
    ansible.builtin.set_fact:
      file_groupowner_efi_grub2_cfg_newgroup: '0'
    when:
    - '"/boot/efi" in ansible_mounts | map(attribute="mount") | list'
    - ( "grub2-common" in ansible_facts.packages and "kernel" in ansible_facts.packages
      )
    tags:
    - CJIS-5.5.2.2
    - NIST-800-171-3.4.5
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-7.1
    - configure_strategy
    - file_groupowner_efi_grub2_cfg
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /boot/efi/EFI/almalinux/grub.cfg
    ansible.builtin.stat:
      path: /boot/efi/EFI/almalinux/grub.cfg
    register: file_exists
    when:
    - '"/boot/efi" in ansible_mounts | map(attribute="mount") | list'
    - ( "grub2-common" in ansible_facts.packages and "kernel" in ansible_facts.packages
      )
    tags:
    - CJIS-5.5.2.2
    - NIST-800-171-3.4.5
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-7.1
    - configure_strategy
    - file_groupowner_efi_grub2_cfg
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure group owner on /boot/efi/EFI/almalinux/grub.cfg
    ansible.builtin.file:
      path: /boot/efi/EFI/almalinux/grub.cfg
      follow: false
      group: '{{ file_groupowner_efi_grub2_cfg_newgroup }}'
    when:
    - '"/boot/efi" in ansible_mounts | map(attribute="mount") | list'
    - ( "grub2-common" in ansible_facts.packages and "kernel" in ansible_facts.packages
      )
    - file_exists.stat is defined and file_exists.stat.exists
    tags:
    - CJIS-5.5.2.2
    - NIST-800-171-3.4.5
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-7.1
    - configure_strategy
    - file_groupowner_efi_grub2_cfg
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set the file_groupowner_efi_user_cfg_newgroup variable if represented by
      gid
    ansible.builtin.set_fact:
      file_groupowner_efi_user_cfg_newgroup: '0'
    when:
    - '"/boot/efi" in ansible_mounts | map(attribute="mount") | list'
    - ( "grub2-common" in ansible_facts.packages and "kernel" in ansible_facts.packages
      )
    tags:
    - CJIS-5.5.2.2
    - NIST-800-171-3.4.5
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-7.1
    - configure_strategy
    - file_groupowner_efi_user_cfg
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /boot/efi/EFI/almalinux/user.cfg
    ansible.builtin.stat:
      path: /boot/efi/EFI/almalinux/user.cfg
    register: file_exists
    when:
    - '"/boot/efi" in ansible_mounts | map(attribute="mount") | list'
    - ( "grub2-common" in ansible_facts.packages and "kernel" in ansible_facts.packages
      )
    tags:
    - CJIS-5.5.2.2
    - NIST-800-171-3.4.5
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-7.1
    - configure_strategy
    - file_groupowner_efi_user_cfg
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure group owner on /boot/efi/EFI/almalinux/user.cfg
    ansible.builtin.file:
      path: /boot/efi/EFI/almalinux/user.cfg
      follow: false
      group: '{{ file_groupowner_efi_user_cfg_newgroup }}'
    when:
    - '"/boot/efi" in ansible_mounts | map(attribute="mount") | list'
    - ( "grub2-common" in ansible_facts.packages and "kernel" in ansible_facts.packages
      )
    - file_exists.stat is defined and file_exists.stat.exists
    tags:
    - CJIS-5.5.2.2
    - NIST-800-171-3.4.5
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-7.1
    - configure_strategy
    - file_groupowner_efi_user_cfg
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set the file_owner_efi_grub2_cfg_newown variable if represented by uid
    ansible.builtin.set_fact:
      file_owner_efi_grub2_cfg_newown: '0'
    when:
    - '"/boot/efi" in ansible_mounts | map(attribute="mount") | list'
    - ( "grub2-common" in ansible_facts.packages and "kernel" in ansible_facts.packages
      )
    tags:
    - CJIS-5.5.2.2
    - NIST-800-171-3.4.5
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-7.1
    - configure_strategy
    - file_owner_efi_grub2_cfg
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /boot/efi/EFI/almalinux/grub.cfg
    ansible.builtin.stat:
      path: /boot/efi/EFI/almalinux/grub.cfg
    register: file_exists
    when:
    - '"/boot/efi" in ansible_mounts | map(attribute="mount") | list'
    - ( "grub2-common" in ansible_facts.packages and "kernel" in ansible_facts.packages
      )
    tags:
    - CJIS-5.5.2.2
    - NIST-800-171-3.4.5
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-7.1
    - configure_strategy
    - file_owner_efi_grub2_cfg
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure owner on /boot/efi/EFI/almalinux/grub.cfg
    ansible.builtin.file:
      path: /boot/efi/EFI/almalinux/grub.cfg
      follow: false
      owner: '{{ file_owner_efi_grub2_cfg_newown }}'
    when:
    - '"/boot/efi" in ansible_mounts | map(attribute="mount") | list'
    - ( "grub2-common" in ansible_facts.packages and "kernel" in ansible_facts.packages
      )
    - file_exists.stat is defined and file_exists.stat.exists
    tags:
    - CJIS-5.5.2.2
    - NIST-800-171-3.4.5
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-7.1
    - configure_strategy
    - file_owner_efi_grub2_cfg
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set the file_owner_efi_user_cfg_newown variable if represented by uid
    ansible.builtin.set_fact:
      file_owner_efi_user_cfg_newown: '0'
    when:
    - '"/boot/efi" in ansible_mounts | map(attribute="mount") | list'
    - ( "grub2-common" in ansible_facts.packages and "kernel" in ansible_facts.packages
      )
    tags:
    - CJIS-5.5.2.2
    - NIST-800-171-3.4.5
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-7.1
    - configure_strategy
    - file_owner_efi_user_cfg
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /boot/efi/EFI/almalinux/user.cfg
    ansible.builtin.stat:
      path: /boot/efi/EFI/almalinux/user.cfg
    register: file_exists
    when:
    - '"/boot/efi" in ansible_mounts | map(attribute="mount") | list'
    - ( "grub2-common" in ansible_facts.packages and "kernel" in ansible_facts.packages
      )
    tags:
    - CJIS-5.5.2.2
    - NIST-800-171-3.4.5
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-7.1
    - configure_strategy
    - file_owner_efi_user_cfg
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure owner on /boot/efi/EFI/almalinux/user.cfg
    ansible.builtin.file:
      path: /boot/efi/EFI/almalinux/user.cfg
      follow: false
      owner: '{{ file_owner_efi_user_cfg_newown }}'
    when:
    - '"/boot/efi" in ansible_mounts | map(attribute="mount") | list'
    - ( "grub2-common" in ansible_facts.packages and "kernel" in ansible_facts.packages
      )
    - file_exists.stat is defined and file_exists.stat.exists
    tags:
    - CJIS-5.5.2.2
    - NIST-800-171-3.4.5
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-7.1
    - configure_strategy
    - file_owner_efi_user_cfg
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /boot/efi/EFI/almalinux/grub.cfg
    ansible.builtin.stat:
      path: /boot/efi/EFI/almalinux/grub.cfg
    register: file_exists
    when:
    - '"/boot/efi" in ansible_mounts | map(attribute="mount") | list'
    - ( "grub2-common" in ansible_facts.packages and "kernel" in ansible_facts.packages
      )
    tags:
    - NIST-800-171-3.4.5
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - configure_strategy
    - file_permissions_efi_grub2_cfg
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure permission u-s,g-xwrs,o-xwrt on /boot/efi/EFI/almalinux/grub.cfg
    ansible.builtin.file:
      path: /boot/efi/EFI/almalinux/grub.cfg
      mode: u-s,g-xwrs,o-xwrt
    when:
    - '"/boot/efi" in ansible_mounts | map(attribute="mount") | list'
    - ( "grub2-common" in ansible_facts.packages and "kernel" in ansible_facts.packages
      )
    - file_exists.stat is defined and file_exists.stat.exists
    tags:
    - NIST-800-171-3.4.5
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - configure_strategy
    - file_permissions_efi_grub2_cfg
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /boot/efi/EFI/almalinux/user.cfg
    ansible.builtin.stat:
      path: /boot/efi/EFI/almalinux/user.cfg
    register: file_exists
    when:
    - '"/boot/efi" in ansible_mounts | map(attribute="mount") | list'
    - ( "grub2-common" in ansible_facts.packages and "kernel" in ansible_facts.packages
      )
    tags:
    - NIST-800-171-3.4.5
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - configure_strategy
    - file_permissions_efi_user_cfg
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure permission u-s,g-xwrs,o-xwrt on /boot/efi/EFI/almalinux/user.cfg
    ansible.builtin.file:
      path: /boot/efi/EFI/almalinux/user.cfg
      mode: u-s,g-xwrs,o-xwrt
    when:
    - '"/boot/efi" in ansible_mounts | map(attribute="mount") | list'
    - ( "grub2-common" in ansible_facts.packages and "kernel" in ansible_facts.packages
      )
    - file_exists.stat is defined and file_exists.stat.exists
    tags:
    - NIST-800-171-3.4.5
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - configure_strategy
    - file_permissions_efi_user_cfg
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure rsyslog Default File Permissions Configured - Search for $FileCreateMode
      Parameter in rsyslog Main Config File
    ansible.builtin.find:
      paths: /etc
      pattern: rsyslog.conf
      contains: ^\s*\$FileCreateMode\s*\d+
    register: rsyslog_main_file_with_filecreatemode
    when: '"kernel" in ansible_facts.packages'
    tags:
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - rsyslog_filecreatemode

  - name: Ensure rsyslog Default File Permissions Configured - Search for $FileCreateMode
      Parameter in rsyslog Include Files
    ansible.builtin.find:
      paths: /etc/rsyslog.d/
      pattern: '*.conf'
      contains: ^\s*\$FileCreateMode\s*\d+
    register: rsyslog_includes_with_filecreatemode
    when: '"kernel" in ansible_facts.packages'
    tags:
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - rsyslog_filecreatemode

  - name: Ensure rsyslog Default File Permissions Configured - Assemble List of rsyslog
      Configuration Files with $FileCreateMode Parameter
    ansible.builtin.set_fact:
      rsyslog_filecreatemode_files: '{{ rsyslog_main_file_with_filecreatemode.files
        | map(attribute=''path'') | list + rsyslog_includes_with_filecreatemode.files
        | map(attribute=''path'') | list }}'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - rsyslog_filecreatemode

  - name: Ensure rsyslog Default File Permissions Configured - Remove $FileCreateMode
      Parameter from Multiple Files to Avoid Conflicts
    ansible.builtin.lineinfile:
      path: '{{ item }}'
      regexp: \$FileCreateMode.*
      state: absent
    register: result_rsyslog_filecreatemode_removed
    loop: '{{ rsyslog_filecreatemode_files }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - rsyslog_filecreatemode_files | length > 1
    tags:
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - rsyslog_filecreatemode

  - name: Ensure rsyslog Default File Permissions Configured - Add $FileCreateMode
      Parameter and Expected Value
    ansible.builtin.lineinfile:
      path: /etc/rsyslog.d/00-rsyslog_filecreatemode.conf
      line: $FileCreateMode 0640
      mode: 416
      create: true
    when:
    - '"kernel" in ansible_facts.packages'
    - rsyslog_filecreatemode_files | length == 0 or result_rsyslog_filecreatemode_removed
      is not skipped
    tags:
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - rsyslog_filecreatemode

  - name: Ensure rsyslog Default File Permissions Configured - Ensure Correct Value
      of Existing $FileCreateMode Parameter
    ansible.builtin.lineinfile:
      path: '{{ item }}'
      regexp: ^\$FileCreateMode
      line: $FileCreateMode 0640
    loop: '{{ rsyslog_filecreatemode_files }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - rsyslog_filecreatemode_files | length == 1
    tags:
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - rsyslog_filecreatemode

  - name: Ensure Log Files Are Owned By Appropriate Group - Set rsyslog logfile configuration
      facts
    ansible.builtin.set_fact:
      rsyslog_etc_config: /etc/rsyslog.conf
    when:
    - '"kernel" in ansible_facts.packages'
    - '"rsyslog" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.1
    - PCI-DSS-Req-10.5.2
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.2
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - rsyslog_files_groupownership

  - name: Ensure Log Files Are Owned By Appropriate Group - Get IncludeConfig directive
    ansible.builtin.shell: |
      set -o pipefail
      grep -e '$IncludeConfig' {{ rsyslog_etc_config }} | cut -d ' ' -f 2 || true
    register: rsyslog_old_inc
    changed_when: false
    when:
    - '"kernel" in ansible_facts.packages'
    - '"rsyslog" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.1
    - PCI-DSS-Req-10.5.2
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.2
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - rsyslog_files_groupownership

  - name: Ensure Log Files Are Owned By Appropriate Group - Get include files directives
    ansible.builtin.shell: |
      set -o pipefail
      awk '/)/{f=0} /include\(/{f=1} f{ nf=gensub("^(include\\(|\\s*)file=\"(\\S+)\".*","\\2",1); if($0!=nf){ print nf }}' {{ rsyslog_etc_config }} || true
    register: rsyslog_new_inc
    changed_when: false
    when:
    - '"kernel" in ansible_facts.packages'
    - '"rsyslog" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.1
    - PCI-DSS-Req-10.5.2
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.2
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - rsyslog_files_groupownership

  - name: Ensure Log Files Are Owned By Appropriate Group - Aggregate rsyslog includes
    ansible.builtin.set_fact:
      include_config_output: '{{ rsyslog_old_inc.stdout_lines + rsyslog_new_inc.stdout_lines
        }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - '"rsyslog" in ansible_facts.packages'
    - rsyslog_old_inc is not skipped and rsyslog_new_inc is not skipped
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.1
    - PCI-DSS-Req-10.5.2
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.2
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - rsyslog_files_groupownership

  - name: Ensure Log Files Are Owned By Appropriate Group - List all config files
    ansible.builtin.find:
      paths: '{{ item | dirname }}'
      patterns: '{{ item | basename }}'
      hidden: false
      follow: true
    loop: '{{ include_config_output | list + [rsyslog_etc_config] }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - '"rsyslog" in ansible_facts.packages'
    - include_config_output is defined
    register: rsyslog_config_files
    failed_when: false
    changed_when: false
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.1
    - PCI-DSS-Req-10.5.2
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.2
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - rsyslog_files_groupownership

  - name: Ensure Log Files Are Owned By Appropriate Group - Extract log files old
      format
    ansible.builtin.shell: |
      set -o pipefail
      grep -oP '^[^(\s|#|\$)]+[\s]*.*[\s]+-?(/+[^:;\s]+);*\.*$' {{ item.1.path }} | \
      awk '{print $NF}' | \
      sed -e 's/^-//' || true
    loop: '{{ rsyslog_config_files.results | default([]) | subelements(''files'')
      }}'
    register: log_files_old
    changed_when: false
    when:
    - '"kernel" in ansible_facts.packages'
    - '"rsyslog" in ansible_facts.packages'
    - rsyslog_config_files is not skipped
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.1
    - PCI-DSS-Req-10.5.2
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.2
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - rsyslog_files_groupownership

  - name: Ensure Log Files Are Owned By Appropriate Group - Extract log files new
      format
    ansible.builtin.shell: |
      set -o pipefail
      grep -iozP "action\s*\(\s*type\s*=\s*\"omfile\"[^\)]*\)" {{ item.1.path }} | \
      grep -iaoP "\bFile\s*=\s*\"([/[:alnum:][:punct:]]*)\"\s*\)" | \
      grep -oE "\"([/[:alnum:][:punct:]]*)\"" | \
      tr -d "\"" | \
      grep -v '^/dev/' || true
    loop: '{{ rsyslog_config_files.results | default([]) | subelements(''files'')
      }}'
    register: log_files_new
    changed_when: false
    when:
    - '"kernel" in ansible_facts.packages'
    - '"rsyslog" in ansible_facts.packages'
    - rsyslog_config_files is not skipped
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.1
    - PCI-DSS-Req-10.5.2
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.2
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - rsyslog_files_groupownership

  - name: Ensure Log Files Are Owned By Appropriate Group - Sum all log files found
    ansible.builtin.set_fact:
      log_files: '{{ log_files_new.results | map(attribute=''stdout_lines'') | list
        | flatten | unique + log_files_old.results | map(attribute=''stdout_lines'')
        | list | flatten | unique }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - '"rsyslog" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.1
    - PCI-DSS-Req-10.5.2
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.2
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - rsyslog_files_groupownership

  - name: Ensure Log Files Are Owned By Appropriate Group -Setup log files attribute
    ansible.builtin.file:
      path: '{{ item }}'
      group: root
      state: file
    loop: '{{ log_files | list | flatten | unique }}'
    failed_when: false
    when:
    - '"kernel" in ansible_facts.packages'
    - '"rsyslog" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.1
    - PCI-DSS-Req-10.5.2
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.2
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - rsyslog_files_groupownership

  - name: Ensure Log Files Are Owned By Appropriate User - Set rsyslog logfile configuration
      facts
    ansible.builtin.set_fact:
      rsyslog_etc_config: /etc/rsyslog.conf
    when:
    - '"kernel" in ansible_facts.packages'
    - '"rsyslog" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.1
    - PCI-DSS-Req-10.5.2
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.2
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - rsyslog_files_ownership

  - name: Ensure Log Files Are Owned By Appropriate User - Get IncludeConfig directive
    ansible.builtin.shell: |
      set -o pipefail
      grep -e '$IncludeConfig' {{ rsyslog_etc_config }} | cut -d ' ' -f 2 || true
    register: rsyslog_old_inc
    changed_when: false
    when:
    - '"kernel" in ansible_facts.packages'
    - '"rsyslog" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.1
    - PCI-DSS-Req-10.5.2
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.2
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - rsyslog_files_ownership

  - name: Ensure Log Files Are Owned By Appropriate User - Get include files directives
    ansible.builtin.shell: |
      set -o pipefail
      awk '/)/{f=0} /include\(/{f=1} f{ nf=gensub("^(include\\(|\\s*)file=\"(\\S+)\".*","\\2",1); if($0!=nf){ print nf }}' {{ rsyslog_etc_config }} || true
    register: rsyslog_new_inc
    changed_when: false
    when:
    - '"kernel" in ansible_facts.packages'
    - '"rsyslog" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.1
    - PCI-DSS-Req-10.5.2
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.2
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - rsyslog_files_ownership

  - name: Ensure Log Files Are Owned By Appropriate User - Aggregate rsyslog includes
    ansible.builtin.set_fact:
      include_config_output: '{{ rsyslog_old_inc.stdout_lines + rsyslog_new_inc.stdout_lines
        }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - '"rsyslog" in ansible_facts.packages'
    - rsyslog_old_inc is not skipped and rsyslog_new_inc is not skipped
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.1
    - PCI-DSS-Req-10.5.2
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.2
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - rsyslog_files_ownership

  - name: Ensure Log Files Are Owned By Appropriate User - List all config files
    ansible.builtin.find:
      paths: '{{ item | dirname }}'
      patterns: '{{ item | basename }}'
      hidden: false
      follow: true
    loop: '{{ include_config_output | list + [rsyslog_etc_config] }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - '"rsyslog" in ansible_facts.packages'
    - include_config_output is defined
    register: rsyslog_config_files
    failed_when: false
    changed_when: false
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.1
    - PCI-DSS-Req-10.5.2
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.2
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - rsyslog_files_ownership

  - name: Ensure Log Files Are Owned By Appropriate User - Extract log files old format
    ansible.builtin.shell: |
      set -o pipefail
      grep -oP '^[^(\s|#|\$)]+[\s]*.*[\s]+-?(/+[^:;\s]+);*\.*$' {{ item.1.path }} | \
      awk '{print $NF}' | \
      sed -e 's/^-//' || true
    loop: '{{ rsyslog_config_files.results | default([]) | subelements(''files'')
      }}'
    register: log_files_old
    changed_when: false
    when:
    - '"kernel" in ansible_facts.packages'
    - '"rsyslog" in ansible_facts.packages'
    - rsyslog_config_files is not skipped
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.1
    - PCI-DSS-Req-10.5.2
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.2
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - rsyslog_files_ownership

  - name: Ensure Log Files Are Owned By Appropriate User - Extract log files new format
    ansible.builtin.shell: |
      set -o pipefail
      grep -iozP "action\s*\(\s*type\s*=\s*\"omfile\"[^\)]*\)" {{ item.1.path }} | \
      grep -iaoP "\bFile\s*=\s*\"([/[:alnum:][:punct:]]*)\"\s*\)" | \
      grep -oE "\"([/[:alnum:][:punct:]]*)\"" | \
      tr -d "\"" | \
      grep -v '^/dev/' || true
    loop: '{{ rsyslog_config_files.results | default([]) | subelements(''files'')
      }}'
    register: log_files_new
    changed_when: false
    when:
    - '"kernel" in ansible_facts.packages'
    - '"rsyslog" in ansible_facts.packages'
    - rsyslog_config_files is not skipped
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.1
    - PCI-DSS-Req-10.5.2
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.2
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - rsyslog_files_ownership

  - name: Ensure Log Files Are Owned By Appropriate User - Sum all log files found
    ansible.builtin.set_fact:
      log_files: '{{ log_files_new.results | map(attribute=''stdout_lines'') | list
        | flatten | unique + log_files_old.results | map(attribute=''stdout_lines'')
        | list | flatten | unique }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - '"rsyslog" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.1
    - PCI-DSS-Req-10.5.2
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.2
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - rsyslog_files_ownership

  - name: Ensure Log Files Are Owned By Appropriate User -Setup log files attribute
    ansible.builtin.file:
      path: '{{ item }}'
      owner: root
      state: file
    loop: '{{ log_files | list | flatten | unique }}'
    failed_when: false
    when:
    - '"kernel" in ansible_facts.packages'
    - '"rsyslog" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.1
    - PCI-DSS-Req-10.5.2
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.2
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - rsyslog_files_ownership

  - name: Ensure System Log Files Have Correct Permissions - Set rsyslog logfile configuration
      facts
    ansible.builtin.set_fact:
      rsyslog_etc_config: /etc/rsyslog.conf
    when:
    - '"kernel" in ansible_facts.packages'
    - '"rsyslog" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.1
    - PCI-DSS-Req-10.5.2
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.1
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - rsyslog_files_permissions

  - name: Ensure System Log Files Have Correct Permissions - Get IncludeConfig directive
    ansible.builtin.shell: |
      set -o pipefail
      grep -e '$IncludeConfig' {{ rsyslog_etc_config }} | cut -d ' ' -f 2 || true
    register: rsyslog_old_inc
    changed_when: false
    when:
    - '"kernel" in ansible_facts.packages'
    - '"rsyslog" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.1
    - PCI-DSS-Req-10.5.2
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.1
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - rsyslog_files_permissions

  - name: Ensure System Log Files Have Correct Permissions - Get include files directives
    ansible.builtin.shell: |
      set -o pipefail
      awk '/)/{f=0} /include\(/{f=1} f{ nf=gensub("^(include\\(|\\s*)file=\"(\\S+)\".*","\\2",1); if($0!=nf){ print nf }}' {{ rsyslog_etc_config }} || true
    register: rsyslog_new_inc
    changed_when: false
    when:
    - '"kernel" in ansible_facts.packages'
    - '"rsyslog" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.1
    - PCI-DSS-Req-10.5.2
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.1
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - rsyslog_files_permissions

  - name: Ensure System Log Files Have Correct Permissions - Aggregate rsyslog includes
    ansible.builtin.set_fact:
      include_config_output: '{{ rsyslog_old_inc.stdout_lines + rsyslog_new_inc.stdout_lines
        }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - '"rsyslog" in ansible_facts.packages'
    - rsyslog_old_inc is not skipped and rsyslog_new_inc is not skipped
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.1
    - PCI-DSS-Req-10.5.2
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.1
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - rsyslog_files_permissions

  - name: Ensure System Log Files Have Correct Permissions - List all config files
    ansible.builtin.find:
      paths: '{{ item | dirname }}'
      patterns: '{{ item | basename }}'
      hidden: false
      follow: true
    loop: '{{ include_config_output | list + [rsyslog_etc_config] }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - '"rsyslog" in ansible_facts.packages'
    - include_config_output is defined
    register: rsyslog_config_files
    failed_when: false
    changed_when: false
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.1
    - PCI-DSS-Req-10.5.2
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.1
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - rsyslog_files_permissions

  - name: Ensure System Log Files Have Correct Permissions - Extract log files old
      format
    ansible.builtin.shell: |
      set -o pipefail
      grep -oP '^[^(\s|#|\$)]+[\s]*.*[\s]+-?(/+[^:;\s]+);*\.*$' {{ item.1.path }} | \
      awk '{print $NF}' | \
      sed -e 's/^-//' || true
    loop: '{{ rsyslog_config_files.results | default([]) | subelements(''files'')
      }}'
    register: log_files_old
    changed_when: false
    when:
    - '"kernel" in ansible_facts.packages'
    - '"rsyslog" in ansible_facts.packages'
    - rsyslog_config_files is not skipped
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.1
    - PCI-DSS-Req-10.5.2
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.1
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - rsyslog_files_permissions

  - name: Ensure System Log Files Have Correct Permissions - Extract log files new
      format
    ansible.builtin.shell: |
      set -o pipefail
      grep -iozP "action\s*\(\s*type\s*=\s*\"omfile\"[^\)]*\)" {{ item.1.path }} | \
      grep -iaoP "\bFile\s*=\s*\"([/[:alnum:][:punct:]]*)\"\s*\)" | \
      grep -oE "\"([/[:alnum:][:punct:]]*)\"" | \
      tr -d "\"" | \
      grep -v '^/dev/' || true
    loop: '{{ rsyslog_config_files.results | default([]) | subelements(''files'')
      }}'
    register: log_files_new
    changed_when: false
    when:
    - '"kernel" in ansible_facts.packages'
    - '"rsyslog" in ansible_facts.packages'
    - rsyslog_config_files is not skipped
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.1
    - PCI-DSS-Req-10.5.2
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.1
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - rsyslog_files_permissions

  - name: Ensure System Log Files Have Correct Permissions - Sum all log files found
    ansible.builtin.set_fact:
      log_files: '{{ log_files_new.results | map(attribute=''stdout_lines'') | list
        | flatten | unique + log_files_old.results | map(attribute=''stdout_lines'')
        | list | flatten | unique }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - '"rsyslog" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.1
    - PCI-DSS-Req-10.5.2
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.1
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - rsyslog_files_permissions

  - name: Ensure System Log Files Have Correct Permissions -Setup log files attribute
    ansible.builtin.file:
      path: '{{ item }}'
      mode: '0640'
      state: file
    loop: '{{ log_files | list | flatten | unique }}'
    failed_when: false
    when:
    - '"kernel" in ansible_facts.packages'
    - '"rsyslog" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.1
    - PCI-DSS-Req-10.5.2
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.1
    - configure_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - rsyslog_files_permissions

  - name: Setting unquoted shell-style assignment of 'Compress' to 'yes' in '/etc/systemd/journald.conf'
    block:

    - name: Check for duplicate values
      ansible.builtin.lineinfile:
        path: /etc/systemd/journald.conf
        create: true
        regexp: (?i)^\s*Compress=
        state: absent
      check_mode: true
      changed_when: false
      register: dupes

    - name: Deduplicate values from /etc/systemd/journald.conf
      ansible.builtin.lineinfile:
        path: /etc/systemd/journald.conf
        create: true
        regexp: (?i)^\s*Compress=
        state: absent
      when: dupes.found is defined and dupes.found > 1

    - name: Insert correct line to /etc/systemd/journald.conf
      ansible.builtin.lineinfile:
        path: /etc/systemd/journald.conf
        create: true
        regexp: (?i)^\s*Compress=
        line: Compress=yes
        state: present
        insertbefore: ^# Compress
        validate: /usr/bin/bash -n %s
    when: '"kernel" in ansible_facts.packages'
    tags:
    - journald_compress
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Setting unquoted shell-style assignment of 'ForwardToSyslog' to 'no' in
      '/etc/systemd/journald.conf'
    block:

    - name: Check for duplicate values
      ansible.builtin.lineinfile:
        path: /etc/systemd/journald.conf
        create: true
        regexp: (?i)^\s*ForwardToSyslog=
        state: absent
      check_mode: true
      changed_when: false
      register: dupes

    - name: Deduplicate values from /etc/systemd/journald.conf
      ansible.builtin.lineinfile:
        path: /etc/systemd/journald.conf
        create: true
        regexp: (?i)^\s*ForwardToSyslog=
        state: absent
      when: dupes.found is defined and dupes.found > 1

    - name: Insert correct line to /etc/systemd/journald.conf
      ansible.builtin.lineinfile:
        path: /etc/systemd/journald.conf
        create: true
        regexp: (?i)^\s*ForwardToSyslog=
        line: ForwardToSyslog=no
        state: present
        insertbefore: ^# ForwardToSyslog
        validate: /usr/bin/bash -n %s
    when:
    - '"kernel" in ansible_facts.packages'
    - '"systemd" in ansible_facts.packages'
    tags:
    - journald_disable_forward_to_syslog
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Setting unquoted shell-style assignment of 'Storage' to 'persistent' in
      '/etc/systemd/journald.conf'
    block:

    - name: Check for duplicate values
      ansible.builtin.lineinfile:
        path: /etc/systemd/journald.conf
        create: true
        regexp: (?i)^\s*Storage=
        state: absent
      check_mode: true
      changed_when: false
      register: dupes

    - name: Deduplicate values from /etc/systemd/journald.conf
      ansible.builtin.lineinfile:
        path: /etc/systemd/journald.conf
        create: true
        regexp: (?i)^\s*Storage=
        state: absent
      when: dupes.found is defined and dupes.found > 1

    - name: Insert correct line to /etc/systemd/journald.conf
      ansible.builtin.lineinfile:
        path: /etc/systemd/journald.conf
        create: true
        regexp: (?i)^\s*Storage=
        line: Storage=persistent
        state: present
        insertbefore: ^# Storage
        validate: /usr/bin/bash -n %s
    when: '"kernel" in ansible_facts.packages'
    tags:
    - journald_storage
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Disable systemd-journal-remote Socket - Collect systemd Socket Units Present
      in the System
    ansible.builtin.command:
      cmd: systemctl -q list-unit-files --type socket
    register: result_systemd_unit_files
    changed_when: false
    check_mode: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - disable_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - socket_systemd-journal-remote_disabled

  - name: Disable systemd-journal-remote Socket - Ensure systemd-journal-remote.socket
      is Masked
    ansible.builtin.systemd:
      name: systemd-journal-remote.socket
      state: stopped
      enabled: false
      masked: true
    when:
    - '"kernel" in ansible_facts.packages'
    - result_systemd_unit_files.stdout_lines is search("systemd-journal-remote.socket")
    tags:
    - disable_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - socket_systemd-journal-remote_disabled

  - name: Ensure rsyslog Does Not Accept Remote Messages Unless Acting As Log Server
      - Define Rsyslog Config Lines Regex in Legacy Syntax
    ansible.builtin.set_fact:
      rsyslog_listen_legacy_regex: ^\s*\$(((Input(TCP|RELP)|UDP)ServerRun)|ModLoad\s+(imtcp|imudp|imrelp))
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - rsyslog_nolisten

  - name: Ensure rsyslog Does Not Accept Remote Messages Unless Acting As Log Server
      - Search for Legacy Config Lines in Rsyslog Main Config File
    ansible.builtin.find:
      paths: /etc
      pattern: rsyslog.conf
      contains: '{{ rsyslog_listen_legacy_regex }}'
    register: rsyslog_listen_legacy_main_file
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - rsyslog_nolisten

  - name: Ensure rsyslog Does Not Accept Remote Messages Unless Acting As Log Server
      - Search for Legacy Config Lines in Rsyslog Include Files
    ansible.builtin.find:
      paths: /etc/rsyslog.d/
      pattern: '*.conf'
      contains: '{{ rsyslog_listen_legacy_regex }}'
    register: rsyslog_listen_legacy_include_files
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - rsyslog_nolisten

  - name: Ensure rsyslog Does Not Accept Remote Messages Unless Acting As Log Server
      - Assemble List of Config Files With Listen Lines in Legacy Syntax
    ansible.builtin.set_fact:
      rsyslog_legacy_remote_listen_files: '{{ rsyslog_listen_legacy_main_file.files
        | map(attribute=''path'') | list + rsyslog_listen_legacy_include_files.files
        | map(attribute=''path'') | list }}'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - rsyslog_nolisten

  - name: Ensure rsyslog Does Not Accept Remote Messages Unless Acting As Log Server
      - Comment Listen Config Lines Wherever Defined Using Legacy Syntax
    ansible.builtin.replace:
      path: '{{ item }}'
      regexp: '{{ rsyslog_listen_legacy_regex }}'
      replace: '# \1'
    loop: '{{ rsyslog_legacy_remote_listen_files }}'
    register: rsyslog_listen_legacy_comment
    when:
    - '"kernel" in ansible_facts.packages'
    - rsyslog_legacy_remote_listen_files | length > 0
    tags:
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - rsyslog_nolisten

  - name: Ensure rsyslog Does Not Accept Remote Messages Unless Acting As Log Server
      - Define Rsyslog Config Lines Regex in RainerScript Syntax
    ansible.builtin.set_fact:
      rsyslog_listen_rainer_regex: ^\s*(module|input)\((load|type)="(imtcp|imudp)".*$
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - rsyslog_nolisten

  - name: Ensure rsyslog Does Not Accept Remote Messages Unless Acting As Log Server
      - Search for RainerScript Config Lines in Rsyslog Main Config File
    ansible.builtin.find:
      paths: /etc
      pattern: rsyslog.conf
      contains: '{{ rsyslog_listen_rainer_regex }}'
    register: rsyslog_rainer_remote_main_file
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - rsyslog_nolisten

  - name: Ensure rsyslog Does Not Accept Remote Messages Unless Acting As Log Server
      - Search for RainerScript Config Lines in Rsyslog Include Files
    ansible.builtin.find:
      paths: /etc/rsyslog.d/
      pattern: '*.conf'
      contains: '{{ rsyslog_listen_rainer_regex }}'
    register: rsyslog_rainer_remote_include_files
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - rsyslog_nolisten

  - name: Ensure rsyslog Does Not Accept Remote Messages Unless Acting As Log Server
      - Assemble List of Config Files With Listen Lines in RainerScript
    ansible.builtin.set_fact:
      rsyslog_rainer_remote_listen_files: '{{ rsyslog_rainer_remote_main_file.files
        | map(attribute=''path'') | list + rsyslog_rainer_remote_include_files.files
        | map(attribute=''path'') | list }}'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - rsyslog_nolisten

  - name: Ensure rsyslog Does Not Accept Remote Messages Unless Acting As Log Server
      - Comment Listen Config Lines Wherever Defined Using RainerScript
    ansible.builtin.replace:
      path: '{{ item }}'
      regexp: '{{ rsyslog_listen_rainer_regex }}'
      replace: '# \1'
    loop: '{{ rsyslog_rainer_remote_listen_files }}'
    register: rsyslog_listen_rainer_comment
    when:
    - '"kernel" in ansible_facts.packages'
    - rsyslog_rainer_remote_listen_files | length > 0
    tags:
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - rsyslog_nolisten

  - name: Ensure rsyslog Does Not Accept Remote Messages Unless Acting As Log Server
      - Restart Rsyslog if Any Line Were Commented Out
    ansible.builtin.service:
      name: rsyslog
      state: restarted
    when:
    - '"kernel" in ansible_facts.packages'
    - rsyslog_listen_legacy_comment is changed or rsyslog_listen_rainer_comment is
      changed
    tags:
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - rsyslog_nolisten

  - name: Setting unquoted shell-style assignment of 'FirewallBackend' to 'nftables'
      in '/etc/firewalld/firewalld.conf'
    block:

    - name: Check for duplicate values
      ansible.builtin.lineinfile:
        path: /etc/firewalld/firewalld.conf
        create: true
        regexp: (?i)^\s*FirewallBackend=
        state: absent
      check_mode: true
      changed_when: false
      register: dupes

    - name: Deduplicate values from /etc/firewalld/firewalld.conf
      ansible.builtin.lineinfile:
        path: /etc/firewalld/firewalld.conf
        create: true
        regexp: (?i)^\s*FirewallBackend=
        state: absent
      when: dupes.found is defined and dupes.found > 1

    - name: Insert correct line to /etc/firewalld/firewalld.conf
      ansible.builtin.lineinfile:
        path: /etc/firewalld/firewalld.conf
        create: true
        regexp: (?i)^\s*FirewallBackend=
        line: FirewallBackend=nftables
        state: present
        insertbefore: ^# FirewallBackend
        validate: /usr/bin/bash -n %s
    when:
    - '"kernel" in ansible_facts.packages'
    - '"firewalld" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040150
    - NIST-800-53-SC-5
    - firewalld-backend
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Configure Accepting Router Advertisements on All IPv6 Interfaces - Set fact
      for sysctl paths
    ansible.builtin.set_fact:
      sysctl_paths:
      - /etc/sysctl.d/
      - /run/sysctl.d/
      - /usr/local/lib/sysctl.d/
      - /usr/lib/sysctl.d/
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040261
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv6_conf_all_accept_ra

  - name: Configure Accepting Router Advertisements on All IPv6 Interfaces - Find
      all files that contain net.ipv6.conf.all.accept_ra
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*net.ipv6.conf.all.accept_ra\s*=\s*.*$'
    register: find_all_values
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040261
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv6_conf_all_accept_ra

  - name: Configure Accepting Router Advertisements on All IPv6 Interfaces - Find
      all files that set net.ipv6.conf.all.accept_ra to correct value
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*net.ipv6.conf.all.accept_ra\s*=\s*{{ sysctl_net_ipv6_conf_all_accept_ra_value
        }}$'
    register: find_correct_value
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040261
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv6_conf_all_accept_ra

  - name: Configure Accepting Router Advertisements on All IPv6 Interfaces - Comment
      out any occurrences of net.ipv6.conf.all.accept_ra from config files
    ansible.builtin.replace:
      path: '{{ item | split(":") | first }}'
      regexp: ^[\s]*net.ipv6.conf.all.accept_ra
      replace: '#net.ipv6.conf.all.accept_ra'
    loop: '{{ find_all_values.stdout_lines }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
      | length > find_correct_value.stdout_lines | length
    tags:
    - DISA-STIG-RHEL-08-040261
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv6_conf_all_accept_ra

  - name: Configure Accepting Router Advertisements on All IPv6 Interfaces - Comment
      out any occurrences of net.ipv6.conf.all.accept_ra from /etc/sysctl.conf
    ansible.builtin.replace:
      path: '{{ item }}'
      regexp: ^[\s]*net.ipv6.conf.all.accept_ra
      replace: '#net.ipv6.conf.all.accept_ra'
    with_fileglob:
    - /etc/sysctl.conf
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040261
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv6_conf_all_accept_ra

  - name: Configure Accepting Router Advertisements on All IPv6 Interfaces - Ensure
      sysctl net.ipv6.conf.all.accept_ra is set
    ansible.posix.sysctl:
      name: net.ipv6.conf.all.accept_ra
      value: '{{ sysctl_net_ipv6_conf_all_accept_ra_value }}'
      sysctl_file: /etc/sysctl.d/net_ipv6_conf_all_accept_ra.conf
      state: present
      reload: true
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040261
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv6_conf_all_accept_ra

  - name: Disable Accepting ICMP Redirects for All IPv6 Interfaces - Set fact for
      sysctl paths
    ansible.builtin.set_fact:
      sysctl_paths:
      - /etc/sysctl.d/
      - /run/sysctl.d/
      - /usr/local/lib/sysctl.d/
      - /usr/lib/sysctl.d/
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040280
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-6(b)
    - NIST-800-53-CM-6.1(iv)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv6_conf_all_accept_redirects

  - name: Disable Accepting ICMP Redirects for All IPv6 Interfaces - Find all files
      that contain net.ipv6.conf.all.accept_redirects
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*net.ipv6.conf.all.accept_redirects\s*=\s*.*$'
    register: find_all_values
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040280
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-6(b)
    - NIST-800-53-CM-6.1(iv)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv6_conf_all_accept_redirects

  - name: Disable Accepting ICMP Redirects for All IPv6 Interfaces - Find all files
      that set net.ipv6.conf.all.accept_redirects to correct value
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*net.ipv6.conf.all.accept_redirects\s*=\s*{{ sysctl_net_ipv6_conf_all_accept_redirects_value
        }}$'
    register: find_correct_value
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040280
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-6(b)
    - NIST-800-53-CM-6.1(iv)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv6_conf_all_accept_redirects

  - name: Disable Accepting ICMP Redirects for All IPv6 Interfaces - Comment out any
      occurrences of net.ipv6.conf.all.accept_redirects from config files
    ansible.builtin.replace:
      path: '{{ item | split(":") | first }}'
      regexp: ^[\s]*net.ipv6.conf.all.accept_redirects
      replace: '#net.ipv6.conf.all.accept_redirects'
    loop: '{{ find_all_values.stdout_lines }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
      | length > find_correct_value.stdout_lines | length
    tags:
    - DISA-STIG-RHEL-08-040280
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-6(b)
    - NIST-800-53-CM-6.1(iv)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv6_conf_all_accept_redirects

  - name: Disable Accepting ICMP Redirects for All IPv6 Interfaces - Comment out any
      occurrences of net.ipv6.conf.all.accept_redirects from /etc/sysctl.conf
    ansible.builtin.replace:
      path: '{{ item }}'
      regexp: ^[\s]*net.ipv6.conf.all.accept_redirects
      replace: '#net.ipv6.conf.all.accept_redirects'
    with_fileglob:
    - /etc/sysctl.conf
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040280
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-6(b)
    - NIST-800-53-CM-6.1(iv)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv6_conf_all_accept_redirects

  - name: Disable Accepting ICMP Redirects for All IPv6 Interfaces - Ensure sysctl
      net.ipv6.conf.all.accept_redirects is set
    ansible.posix.sysctl:
      name: net.ipv6.conf.all.accept_redirects
      value: '{{ sysctl_net_ipv6_conf_all_accept_redirects_value }}'
      sysctl_file: /etc/sysctl.d/net_ipv6_conf_all_accept_redirects.conf
      state: present
      reload: true
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040280
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-6(b)
    - NIST-800-53-CM-6.1(iv)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv6_conf_all_accept_redirects

  - name: Disable Kernel Parameter for Accepting Source-Routed Packets on all IPv6
      Interfaces - Set fact for sysctl paths
    ansible.builtin.set_fact:
      sysctl_paths:
      - /etc/sysctl.d/
      - /run/sysctl.d/
      - /usr/local/lib/sysctl.d/
      - /usr/lib/sysctl.d/
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040240
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv6_conf_all_accept_source_route

  - name: Disable Kernel Parameter for Accepting Source-Routed Packets on all IPv6
      Interfaces - Find all files that contain net.ipv6.conf.all.accept_source_route
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*net.ipv6.conf.all.accept_source_route\s*=\s*.*$'
    register: find_all_values
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040240
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv6_conf_all_accept_source_route

  - name: Disable Kernel Parameter for Accepting Source-Routed Packets on all IPv6
      Interfaces - Find all files that set net.ipv6.conf.all.accept_source_route to
      correct value
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*net.ipv6.conf.all.accept_source_route\s*=\s*{{ sysctl_net_ipv6_conf_all_accept_source_route_value
        }}$'
    register: find_correct_value
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040240
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv6_conf_all_accept_source_route

  - name: Disable Kernel Parameter for Accepting Source-Routed Packets on all IPv6
      Interfaces - Comment out any occurrences of net.ipv6.conf.all.accept_source_route
      from config files
    ansible.builtin.replace:
      path: '{{ item | split(":") | first }}'
      regexp: ^[\s]*net.ipv6.conf.all.accept_source_route
      replace: '#net.ipv6.conf.all.accept_source_route'
    loop: '{{ find_all_values.stdout_lines }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
      | length > find_correct_value.stdout_lines | length
    tags:
    - DISA-STIG-RHEL-08-040240
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv6_conf_all_accept_source_route

  - name: Disable Kernel Parameter for Accepting Source-Routed Packets on all IPv6
      Interfaces - Comment out any occurrences of net.ipv6.conf.all.accept_source_route
      from /etc/sysctl.conf
    ansible.builtin.replace:
      path: '{{ item }}'
      regexp: ^[\s]*net.ipv6.conf.all.accept_source_route
      replace: '#net.ipv6.conf.all.accept_source_route'
    with_fileglob:
    - /etc/sysctl.conf
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040240
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv6_conf_all_accept_source_route

  - name: Disable Kernel Parameter for Accepting Source-Routed Packets on all IPv6
      Interfaces - Ensure sysctl net.ipv6.conf.all.accept_source_route is set
    ansible.posix.sysctl:
      name: net.ipv6.conf.all.accept_source_route
      value: '{{ sysctl_net_ipv6_conf_all_accept_source_route_value }}'
      sysctl_file: /etc/sysctl.d/net_ipv6_conf_all_accept_source_route.conf
      state: present
      reload: true
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040240
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv6_conf_all_accept_source_route

  - name: Disable Kernel Parameter for IPv6 Forwarding - Set fact for sysctl paths
    ansible.builtin.set_fact:
      sysctl_paths:
      - /etc/sysctl.d/
      - /run/sysctl.d/
      - /usr/local/lib/sysctl.d/
      - /usr/lib/sysctl.d/
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040260
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-6(b)
    - NIST-800-53-CM-6.1(iv)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv6_conf_all_forwarding

  - name: Disable Kernel Parameter for IPv6 Forwarding - Find all files that contain
      net.ipv6.conf.all.forwarding
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*net.ipv6.conf.all.forwarding\s*=\s*.*$'
    register: find_all_values
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040260
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-6(b)
    - NIST-800-53-CM-6.1(iv)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv6_conf_all_forwarding

  - name: Disable Kernel Parameter for IPv6 Forwarding - Find all files that set net.ipv6.conf.all.forwarding
      to correct value
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*net.ipv6.conf.all.forwarding\s*=\s*{{ sysctl_net_ipv6_conf_all_forwarding_value
        }}$'
    register: find_correct_value
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040260
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-6(b)
    - NIST-800-53-CM-6.1(iv)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv6_conf_all_forwarding

  - name: Disable Kernel Parameter for IPv6 Forwarding - Comment out any occurrences
      of net.ipv6.conf.all.forwarding from config files
    ansible.builtin.replace:
      path: '{{ item | split(":") | first }}'
      regexp: ^[\s]*net.ipv6.conf.all.forwarding
      replace: '#net.ipv6.conf.all.forwarding'
    loop: '{{ find_all_values.stdout_lines }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
      | length > find_correct_value.stdout_lines | length
    tags:
    - DISA-STIG-RHEL-08-040260
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-6(b)
    - NIST-800-53-CM-6.1(iv)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv6_conf_all_forwarding

  - name: Disable Kernel Parameter for IPv6 Forwarding - Comment out any occurrences
      of net.ipv6.conf.all.forwarding from /etc/sysctl.conf
    ansible.builtin.replace:
      path: '{{ item }}'
      regexp: ^[\s]*net.ipv6.conf.all.forwarding
      replace: '#net.ipv6.conf.all.forwarding'
    with_fileglob:
    - /etc/sysctl.conf
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040260
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-6(b)
    - NIST-800-53-CM-6.1(iv)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv6_conf_all_forwarding

  - name: Disable Kernel Parameter for IPv6 Forwarding - Ensure sysctl net.ipv6.conf.all.forwarding
      is set
    ansible.posix.sysctl:
      name: net.ipv6.conf.all.forwarding
      value: '{{ sysctl_net_ipv6_conf_all_forwarding_value }}'
      sysctl_file: /etc/sysctl.d/net_ipv6_conf_all_forwarding.conf
      state: present
      reload: true
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040260
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-6(b)
    - NIST-800-53-CM-6.1(iv)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv6_conf_all_forwarding

  - name: Disable Accepting Router Advertisements on all IPv6 Interfaces by Default
      - Set fact for sysctl paths
    ansible.builtin.set_fact:
      sysctl_paths:
      - /etc/sysctl.d/
      - /run/sysctl.d/
      - /usr/local/lib/sysctl.d/
      - /usr/lib/sysctl.d/
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040262
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv6_conf_default_accept_ra

  - name: Disable Accepting Router Advertisements on all IPv6 Interfaces by Default
      - Find all files that contain net.ipv6.conf.default.accept_ra
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*net.ipv6.conf.default.accept_ra\s*=\s*.*$'
    register: find_all_values
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040262
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv6_conf_default_accept_ra

  - name: Disable Accepting Router Advertisements on all IPv6 Interfaces by Default
      - Find all files that set net.ipv6.conf.default.accept_ra to correct value
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*net.ipv6.conf.default.accept_ra\s*=\s*{{ sysctl_net_ipv6_conf_default_accept_ra_value
        }}$'
    register: find_correct_value
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040262
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv6_conf_default_accept_ra

  - name: Disable Accepting Router Advertisements on all IPv6 Interfaces by Default
      - Comment out any occurrences of net.ipv6.conf.default.accept_ra from config
      files
    ansible.builtin.replace:
      path: '{{ item | split(":") | first }}'
      regexp: ^[\s]*net.ipv6.conf.default.accept_ra
      replace: '#net.ipv6.conf.default.accept_ra'
    loop: '{{ find_all_values.stdout_lines }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
      | length > find_correct_value.stdout_lines | length
    tags:
    - DISA-STIG-RHEL-08-040262
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv6_conf_default_accept_ra

  - name: Disable Accepting Router Advertisements on all IPv6 Interfaces by Default
      - Comment out any occurrences of net.ipv6.conf.default.accept_ra from /etc/sysctl.conf
    ansible.builtin.replace:
      path: '{{ item }}'
      regexp: ^[\s]*net.ipv6.conf.default.accept_ra
      replace: '#net.ipv6.conf.default.accept_ra'
    with_fileglob:
    - /etc/sysctl.conf
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040262
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv6_conf_default_accept_ra

  - name: Disable Accepting Router Advertisements on all IPv6 Interfaces by Default
      - Ensure sysctl net.ipv6.conf.default.accept_ra is set
    ansible.posix.sysctl:
      name: net.ipv6.conf.default.accept_ra
      value: '{{ sysctl_net_ipv6_conf_default_accept_ra_value }}'
      sysctl_file: /etc/sysctl.d/net_ipv6_conf_default_accept_ra.conf
      state: present
      reload: true
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040262
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv6_conf_default_accept_ra

  - name: Disable Kernel Parameter for Accepting ICMP Redirects by Default on IPv6
      Interfaces - Set fact for sysctl paths
    ansible.builtin.set_fact:
      sysctl_paths:
      - /etc/sysctl.d/
      - /run/sysctl.d/
      - /usr/local/lib/sysctl.d/
      - /usr/lib/sysctl.d/
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040210
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv6_conf_default_accept_redirects

  - name: Disable Kernel Parameter for Accepting ICMP Redirects by Default on IPv6
      Interfaces - Find all files that contain net.ipv6.conf.default.accept_redirects
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*net.ipv6.conf.default.accept_redirects\s*=\s*.*$'
    register: find_all_values
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040210
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv6_conf_default_accept_redirects

  - name: Disable Kernel Parameter for Accepting ICMP Redirects by Default on IPv6
      Interfaces - Find all files that set net.ipv6.conf.default.accept_redirects
      to correct value
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*net.ipv6.conf.default.accept_redirects\s*=\s*{{ sysctl_net_ipv6_conf_default_accept_redirects_value
        }}$'
    register: find_correct_value
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040210
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv6_conf_default_accept_redirects

  - name: Disable Kernel Parameter for Accepting ICMP Redirects by Default on IPv6
      Interfaces - Comment out any occurrences of net.ipv6.conf.default.accept_redirects
      from config files
    ansible.builtin.replace:
      path: '{{ item | split(":") | first }}'
      regexp: ^[\s]*net.ipv6.conf.default.accept_redirects
      replace: '#net.ipv6.conf.default.accept_redirects'
    loop: '{{ find_all_values.stdout_lines }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
      | length > find_correct_value.stdout_lines | length
    tags:
    - DISA-STIG-RHEL-08-040210
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv6_conf_default_accept_redirects

  - name: Disable Kernel Parameter for Accepting ICMP Redirects by Default on IPv6
      Interfaces - Comment out any occurrences of net.ipv6.conf.default.accept_redirects
      from /etc/sysctl.conf
    ansible.builtin.replace:
      path: '{{ item }}'
      regexp: ^[\s]*net.ipv6.conf.default.accept_redirects
      replace: '#net.ipv6.conf.default.accept_redirects'
    with_fileglob:
    - /etc/sysctl.conf
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040210
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv6_conf_default_accept_redirects

  - name: Disable Kernel Parameter for Accepting ICMP Redirects by Default on IPv6
      Interfaces - Ensure sysctl net.ipv6.conf.default.accept_redirects is set
    ansible.posix.sysctl:
      name: net.ipv6.conf.default.accept_redirects
      value: '{{ sysctl_net_ipv6_conf_default_accept_redirects_value }}'
      sysctl_file: /etc/sysctl.d/net_ipv6_conf_default_accept_redirects.conf
      state: present
      reload: true
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040210
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv6_conf_default_accept_redirects

  - name: Disable Kernel Parameter for Accepting Source-Routed Packets on IPv6 Interfaces
      by Default - Set fact for sysctl paths
    ansible.builtin.set_fact:
      sysctl_paths:
      - /etc/sysctl.d/
      - /run/sysctl.d/
      - /usr/local/lib/sysctl.d/
      - /usr/lib/sysctl.d/
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040250
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-6(b)
    - NIST-800-53-CM-6.1(iv)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - PCI-DSS-Req-1.4.3
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.2
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv6_conf_default_accept_source_route

  - name: Disable Kernel Parameter for Accepting Source-Routed Packets on IPv6 Interfaces
      by Default - Find all files that contain net.ipv6.conf.default.accept_source_route
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*net.ipv6.conf.default.accept_source_route\s*=\s*.*$'
    register: find_all_values
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040250
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-6(b)
    - NIST-800-53-CM-6.1(iv)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - PCI-DSS-Req-1.4.3
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.2
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv6_conf_default_accept_source_route

  - name: Disable Kernel Parameter for Accepting Source-Routed Packets on IPv6 Interfaces
      by Default - Find all files that set net.ipv6.conf.default.accept_source_route
      to correct value
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*net.ipv6.conf.default.accept_source_route\s*=\s*{{ sysctl_net_ipv6_conf_default_accept_source_route_value
        }}$'
    register: find_correct_value
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040250
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-6(b)
    - NIST-800-53-CM-6.1(iv)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - PCI-DSS-Req-1.4.3
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.2
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv6_conf_default_accept_source_route

  - name: Disable Kernel Parameter for Accepting Source-Routed Packets on IPv6 Interfaces
      by Default - Comment out any occurrences of net.ipv6.conf.default.accept_source_route
      from config files
    ansible.builtin.replace:
      path: '{{ item | split(":") | first }}'
      regexp: ^[\s]*net.ipv6.conf.default.accept_source_route
      replace: '#net.ipv6.conf.default.accept_source_route'
    loop: '{{ find_all_values.stdout_lines }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
      | length > find_correct_value.stdout_lines | length
    tags:
    - DISA-STIG-RHEL-08-040250
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-6(b)
    - NIST-800-53-CM-6.1(iv)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - PCI-DSS-Req-1.4.3
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.2
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv6_conf_default_accept_source_route

  - name: Disable Kernel Parameter for Accepting Source-Routed Packets on IPv6 Interfaces
      by Default - Comment out any occurrences of net.ipv6.conf.default.accept_source_route
      from /etc/sysctl.conf
    ansible.builtin.replace:
      path: '{{ item }}'
      regexp: ^[\s]*net.ipv6.conf.default.accept_source_route
      replace: '#net.ipv6.conf.default.accept_source_route'
    with_fileglob:
    - /etc/sysctl.conf
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040250
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-6(b)
    - NIST-800-53-CM-6.1(iv)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - PCI-DSS-Req-1.4.3
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.2
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv6_conf_default_accept_source_route

  - name: Disable Kernel Parameter for Accepting Source-Routed Packets on IPv6 Interfaces
      by Default - Ensure sysctl net.ipv6.conf.default.accept_source_route is set
    ansible.posix.sysctl:
      name: net.ipv6.conf.default.accept_source_route
      value: '{{ sysctl_net_ipv6_conf_default_accept_source_route_value }}'
      sysctl_file: /etc/sysctl.d/net_ipv6_conf_default_accept_source_route.conf
      state: present
      reload: true
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040250
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-6(b)
    - NIST-800-53-CM-6.1(iv)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - PCI-DSS-Req-1.4.3
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.2
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv6_conf_default_accept_source_route

  - name: Disable Kernel Parameter for IPv6 Forwarding by default - Set fact for sysctl
      paths
    ansible.builtin.set_fact:
      sysctl_paths:
      - /etc/sysctl.d/
      - /run/sysctl.d/
      - /usr/local/lib/sysctl.d/
      - /usr/lib/sysctl.d/
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-CM-6(b)
    - NIST-800-53-CM-6.1(iv)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv6_conf_default_forwarding

  - name: Disable Kernel Parameter for IPv6 Forwarding by default - Find all files
      that contain net.ipv6.conf.default.forwarding
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*net.ipv6.conf.default.forwarding\s*=\s*.*$'
    register: find_all_values
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-CM-6(b)
    - NIST-800-53-CM-6.1(iv)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv6_conf_default_forwarding

  - name: Disable Kernel Parameter for IPv6 Forwarding by default - Find all files
      that set net.ipv6.conf.default.forwarding to correct value
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*net.ipv6.conf.default.forwarding\s*=\s*{{ sysctl_net_ipv6_conf_default_forwarding_value
        }}$'
    register: find_correct_value
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-CM-6(b)
    - NIST-800-53-CM-6.1(iv)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv6_conf_default_forwarding

  - name: Disable Kernel Parameter for IPv6 Forwarding by default - Comment out any
      occurrences of net.ipv6.conf.default.forwarding from config files
    ansible.builtin.replace:
      path: '{{ item | split(":") | first }}'
      regexp: ^[\s]*net.ipv6.conf.default.forwarding
      replace: '#net.ipv6.conf.default.forwarding'
    loop: '{{ find_all_values.stdout_lines }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
      | length > find_correct_value.stdout_lines | length
    tags:
    - NIST-800-53-CM-6(b)
    - NIST-800-53-CM-6.1(iv)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv6_conf_default_forwarding

  - name: Disable Kernel Parameter for IPv6 Forwarding by default - Comment out any
      occurrences of net.ipv6.conf.default.forwarding from /etc/sysctl.conf
    ansible.builtin.replace:
      path: '{{ item }}'
      regexp: ^[\s]*net.ipv6.conf.default.forwarding
      replace: '#net.ipv6.conf.default.forwarding'
    with_fileglob:
    - /etc/sysctl.conf
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-CM-6(b)
    - NIST-800-53-CM-6.1(iv)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv6_conf_default_forwarding

  - name: Disable Kernel Parameter for IPv6 Forwarding by default - Ensure sysctl
      net.ipv6.conf.default.forwarding is set
    ansible.posix.sysctl:
      name: net.ipv6.conf.default.forwarding
      value: '{{ sysctl_net_ipv6_conf_default_forwarding_value }}'
      sysctl_file: /etc/sysctl.d/net_ipv6_conf_default_forwarding.conf
      state: present
      reload: true
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-CM-6(b)
    - NIST-800-53-CM-6.1(iv)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv6_conf_default_forwarding

  - name: Disable Accepting ICMP Redirects for All IPv4 Interfaces - Set fact for
      sysctl paths
    ansible.builtin.set_fact:
      sysctl_paths:
      - /etc/sysctl.d/
      - /run/sysctl.d/
      - /usr/local/lib/sysctl.d/
      - /usr/lib/sysctl.d/
    when: '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.10.1.1
    - DISA-STIG-RHEL-08-040279
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-7(a)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_all_accept_redirects

  - name: Disable Accepting ICMP Redirects for All IPv4 Interfaces - Find all files
      that contain net.ipv4.conf.all.accept_redirects
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*net.ipv4.conf.all.accept_redirects\s*=\s*.*$'
    register: find_all_values
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.10.1.1
    - DISA-STIG-RHEL-08-040279
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-7(a)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_all_accept_redirects

  - name: Disable Accepting ICMP Redirects for All IPv4 Interfaces - Find all files
      that set net.ipv4.conf.all.accept_redirects to correct value
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*net.ipv4.conf.all.accept_redirects\s*=\s*{{ sysctl_net_ipv4_conf_all_accept_redirects_value
        }}$'
    register: find_correct_value
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.10.1.1
    - DISA-STIG-RHEL-08-040279
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-7(a)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_all_accept_redirects

  - name: Disable Accepting ICMP Redirects for All IPv4 Interfaces - Comment out any
      occurrences of net.ipv4.conf.all.accept_redirects from config files
    ansible.builtin.replace:
      path: '{{ item | split(":") | first }}'
      regexp: ^[\s]*net.ipv4.conf.all.accept_redirects
      replace: '#net.ipv4.conf.all.accept_redirects'
    loop: '{{ find_all_values.stdout_lines }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
      | length > find_correct_value.stdout_lines | length
    tags:
    - CJIS-5.10.1.1
    - DISA-STIG-RHEL-08-040279
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-7(a)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_all_accept_redirects

  - name: Disable Accepting ICMP Redirects for All IPv4 Interfaces - Comment out any
      occurrences of net.ipv4.conf.all.accept_redirects from /etc/sysctl.conf
    ansible.builtin.replace:
      path: '{{ item }}'
      regexp: ^[\s]*net.ipv4.conf.all.accept_redirects
      replace: '#net.ipv4.conf.all.accept_redirects'
    with_fileglob:
    - /etc/sysctl.conf
    when: '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.10.1.1
    - DISA-STIG-RHEL-08-040279
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-7(a)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_all_accept_redirects

  - name: Disable Accepting ICMP Redirects for All IPv4 Interfaces - Ensure sysctl
      net.ipv4.conf.all.accept_redirects is set
    ansible.posix.sysctl:
      name: net.ipv4.conf.all.accept_redirects
      value: '{{ sysctl_net_ipv4_conf_all_accept_redirects_value }}'
      sysctl_file: /etc/sysctl.d/net_ipv4_conf_all_accept_redirects.conf
      state: present
      reload: true
    when: '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.10.1.1
    - DISA-STIG-RHEL-08-040279
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-7(a)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_all_accept_redirects

  - name: Disable Kernel Parameter for Accepting Source-Routed Packets on all IPv4
      Interfaces - Set fact for sysctl paths
    ansible.builtin.set_fact:
      sysctl_paths:
      - /etc/sysctl.d/
      - /run/sysctl.d/
      - /usr/local/lib/sysctl.d/
      - /usr/lib/sysctl.d/
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040239
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5
    - NIST-800-53-SC-7(a)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_all_accept_source_route

  - name: Disable Kernel Parameter for Accepting Source-Routed Packets on all IPv4
      Interfaces - Find all files that contain net.ipv4.conf.all.accept_source_route
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*net.ipv4.conf.all.accept_source_route\s*=\s*.*$'
    register: find_all_values
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040239
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5
    - NIST-800-53-SC-7(a)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_all_accept_source_route

  - name: Disable Kernel Parameter for Accepting Source-Routed Packets on all IPv4
      Interfaces - Find all files that set net.ipv4.conf.all.accept_source_route to
      correct value
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*net.ipv4.conf.all.accept_source_route\s*=\s*{{ sysctl_net_ipv4_conf_all_accept_source_route_value
        }}$'
    register: find_correct_value
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040239
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5
    - NIST-800-53-SC-7(a)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_all_accept_source_route

  - name: Disable Kernel Parameter for Accepting Source-Routed Packets on all IPv4
      Interfaces - Comment out any occurrences of net.ipv4.conf.all.accept_source_route
      from config files
    ansible.builtin.replace:
      path: '{{ item | split(":") | first }}'
      regexp: ^[\s]*net.ipv4.conf.all.accept_source_route
      replace: '#net.ipv4.conf.all.accept_source_route'
    loop: '{{ find_all_values.stdout_lines }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
      | length > find_correct_value.stdout_lines | length
    tags:
    - DISA-STIG-RHEL-08-040239
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5
    - NIST-800-53-SC-7(a)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_all_accept_source_route

  - name: Disable Kernel Parameter for Accepting Source-Routed Packets on all IPv4
      Interfaces - Comment out any occurrences of net.ipv4.conf.all.accept_source_route
      from /etc/sysctl.conf
    ansible.builtin.replace:
      path: '{{ item }}'
      regexp: ^[\s]*net.ipv4.conf.all.accept_source_route
      replace: '#net.ipv4.conf.all.accept_source_route'
    with_fileglob:
    - /etc/sysctl.conf
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040239
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5
    - NIST-800-53-SC-7(a)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_all_accept_source_route

  - name: Disable Kernel Parameter for Accepting Source-Routed Packets on all IPv4
      Interfaces - Ensure sysctl net.ipv4.conf.all.accept_source_route is set
    ansible.posix.sysctl:
      name: net.ipv4.conf.all.accept_source_route
      value: '{{ sysctl_net_ipv4_conf_all_accept_source_route_value }}'
      sysctl_file: /etc/sysctl.d/net_ipv4_conf_all_accept_source_route.conf
      state: present
      reload: true
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040239
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5
    - NIST-800-53-SC-7(a)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_all_accept_source_route

  - name: Disable Kernel Parameter for IPv4 Forwarding on all IPv4 Interfaces - Set
      fact for sysctl paths
    ansible.builtin.set_fact:
      sysctl_paths:
      - /etc/sysctl.d/
      - /run/sysctl.d/
      - /usr/local/lib/sysctl.d/
      - /usr/lib/sysctl.d/
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040259
    - NIST-800-53-CM-6(b)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_all_forwarding

  - name: Disable Kernel Parameter for IPv4 Forwarding on all IPv4 Interfaces - Find
      all files that contain net.ipv4.conf.all.forwarding
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*net.ipv4.conf.all.forwarding\s*=\s*.*$'
    register: find_all_values
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040259
    - NIST-800-53-CM-6(b)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_all_forwarding

  - name: Disable Kernel Parameter for IPv4 Forwarding on all IPv4 Interfaces - Find
      all files that set net.ipv4.conf.all.forwarding to correct value
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*net.ipv4.conf.all.forwarding\s*=\s*{{ sysctl_net_ipv4_conf_all_forwarding_value
        }}$'
    register: find_correct_value
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040259
    - NIST-800-53-CM-6(b)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_all_forwarding

  - name: Disable Kernel Parameter for IPv4 Forwarding on all IPv4 Interfaces - Comment
      out any occurrences of net.ipv4.conf.all.forwarding from config files
    ansible.builtin.replace:
      path: '{{ item | split(":") | first }}'
      regexp: ^[\s]*net.ipv4.conf.all.forwarding
      replace: '#net.ipv4.conf.all.forwarding'
    loop: '{{ find_all_values.stdout_lines }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
      | length > find_correct_value.stdout_lines | length
    tags:
    - DISA-STIG-RHEL-08-040259
    - NIST-800-53-CM-6(b)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_all_forwarding

  - name: Disable Kernel Parameter for IPv4 Forwarding on all IPv4 Interfaces - Comment
      out any occurrences of net.ipv4.conf.all.forwarding from /etc/sysctl.conf
    ansible.builtin.replace:
      path: '{{ item }}'
      regexp: ^[\s]*net.ipv4.conf.all.forwarding
      replace: '#net.ipv4.conf.all.forwarding'
    with_fileglob:
    - /etc/sysctl.conf
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040259
    - NIST-800-53-CM-6(b)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_all_forwarding

  - name: Disable Kernel Parameter for IPv4 Forwarding on all IPv4 Interfaces - Ensure
      sysctl net.ipv4.conf.all.forwarding is set
    ansible.posix.sysctl:
      name: net.ipv4.conf.all.forwarding
      value: '{{ sysctl_net_ipv4_conf_all_forwarding_value }}'
      sysctl_file: /etc/sysctl.d/net_ipv4_conf_all_forwarding.conf
      state: present
      reload: true
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040259
    - NIST-800-53-CM-6(b)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_all_forwarding

  - name: Enable Kernel Parameter to Log Martian Packets on all IPv4 Interfaces -
      Set fact for sysctl paths
    ansible.builtin.set_fact:
      sysctl_paths:
      - /etc/sysctl.d/
      - /run/sysctl.d/
      - /usr/local/lib/sysctl.d/
      - /usr/lib/sysctl.d/
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5(3)(a)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - reboot_required
    - sysctl_net_ipv4_conf_all_log_martians
    - unknown_severity

  - name: Enable Kernel Parameter to Log Martian Packets on all IPv4 Interfaces -
      Find all files that contain net.ipv4.conf.all.log_martians
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*net.ipv4.conf.all.log_martians\s*=\s*.*$'
    register: find_all_values
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5(3)(a)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - reboot_required
    - sysctl_net_ipv4_conf_all_log_martians
    - unknown_severity

  - name: Enable Kernel Parameter to Log Martian Packets on all IPv4 Interfaces -
      Find all files that set net.ipv4.conf.all.log_martians to correct value
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*net.ipv4.conf.all.log_martians\s*=\s*{{ sysctl_net_ipv4_conf_all_log_martians_value
        }}$'
    register: find_correct_value
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5(3)(a)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - reboot_required
    - sysctl_net_ipv4_conf_all_log_martians
    - unknown_severity

  - name: Enable Kernel Parameter to Log Martian Packets on all IPv4 Interfaces -
      Comment out any occurrences of net.ipv4.conf.all.log_martians from config files
    ansible.builtin.replace:
      path: '{{ item | split(":") | first }}'
      regexp: ^[\s]*net.ipv4.conf.all.log_martians
      replace: '#net.ipv4.conf.all.log_martians'
    loop: '{{ find_all_values.stdout_lines }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
      | length > find_correct_value.stdout_lines | length
    tags:
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5(3)(a)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - reboot_required
    - sysctl_net_ipv4_conf_all_log_martians
    - unknown_severity

  - name: Enable Kernel Parameter to Log Martian Packets on all IPv4 Interfaces -
      Comment out any occurrences of net.ipv4.conf.all.log_martians from /etc/sysctl.conf
    ansible.builtin.replace:
      path: '{{ item }}'
      regexp: ^[\s]*net.ipv4.conf.all.log_martians
      replace: '#net.ipv4.conf.all.log_martians'
    with_fileglob:
    - /etc/sysctl.conf
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5(3)(a)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - reboot_required
    - sysctl_net_ipv4_conf_all_log_martians
    - unknown_severity

  - name: Enable Kernel Parameter to Log Martian Packets on all IPv4 Interfaces -
      Ensure sysctl net.ipv4.conf.all.log_martians is set
    ansible.posix.sysctl:
      name: net.ipv4.conf.all.log_martians
      value: '{{ sysctl_net_ipv4_conf_all_log_martians_value }}'
      sysctl_file: /etc/sysctl.d/net_ipv4_conf_all_log_martians.conf
      state: present
      reload: true
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5(3)(a)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - reboot_required
    - sysctl_net_ipv4_conf_all_log_martians
    - unknown_severity

  - name: Enable Kernel Parameter to Use Reverse Path Filtering on all IPv4 Interfaces
      - Set fact for sysctl paths
    ansible.builtin.set_fact:
      sysctl_paths:
      - /etc/sysctl.d/
      - /run/sysctl.d/
      - /usr/local/lib/sysctl.d/
      - /usr/lib/sysctl.d/
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040285
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-7(a)
    - PCI-DSS-Req-1.4.3
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.3
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_all_rp_filter

  - name: Enable Kernel Parameter to Use Reverse Path Filtering on all IPv4 Interfaces
      - Find all files that contain net.ipv4.conf.all.rp_filter
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*net.ipv4.conf.all.rp_filter\s*=\s*.*$'
    register: find_all_values
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040285
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-7(a)
    - PCI-DSS-Req-1.4.3
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.3
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_all_rp_filter

  - name: Enable Kernel Parameter to Use Reverse Path Filtering on all IPv4 Interfaces
      - Find all files that set net.ipv4.conf.all.rp_filter to correct value
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*net.ipv4.conf.all.rp_filter\s*=\s*{{ sysctl_net_ipv4_conf_all_rp_filter_value
        }}$'
    register: find_correct_value
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040285
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-7(a)
    - PCI-DSS-Req-1.4.3
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.3
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_all_rp_filter

  - name: Enable Kernel Parameter to Use Reverse Path Filtering on all IPv4 Interfaces
      - Comment out any occurrences of net.ipv4.conf.all.rp_filter from config files
    ansible.builtin.replace:
      path: '{{ item | split(":") | first }}'
      regexp: ^[\s]*net.ipv4.conf.all.rp_filter
      replace: '#net.ipv4.conf.all.rp_filter'
    loop: '{{ find_all_values.stdout_lines }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
      | length > find_correct_value.stdout_lines | length
    tags:
    - DISA-STIG-RHEL-08-040285
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-7(a)
    - PCI-DSS-Req-1.4.3
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.3
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_all_rp_filter

  - name: Enable Kernel Parameter to Use Reverse Path Filtering on all IPv4 Interfaces
      - Comment out any occurrences of net.ipv4.conf.all.rp_filter from /etc/sysctl.conf
    ansible.builtin.replace:
      path: '{{ item }}'
      regexp: ^[\s]*net.ipv4.conf.all.rp_filter
      replace: '#net.ipv4.conf.all.rp_filter'
    with_fileglob:
    - /etc/sysctl.conf
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040285
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-7(a)
    - PCI-DSS-Req-1.4.3
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.3
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_all_rp_filter

  - name: Enable Kernel Parameter to Use Reverse Path Filtering on all IPv4 Interfaces
      - Ensure sysctl net.ipv4.conf.all.rp_filter is set
    ansible.posix.sysctl:
      name: net.ipv4.conf.all.rp_filter
      value: '{{ sysctl_net_ipv4_conf_all_rp_filter_value }}'
      sysctl_file: /etc/sysctl.d/net_ipv4_conf_all_rp_filter.conf
      state: present
      reload: true
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040285
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-7(a)
    - PCI-DSS-Req-1.4.3
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.3
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_all_rp_filter

  - name: Disable Kernel Parameter for Accepting Secure ICMP Redirects on all IPv4
      Interfaces - Set fact for sysctl paths
    ansible.builtin.set_fact:
      sysctl_paths:
      - /etc/sysctl.d/
      - /run/sysctl.d/
      - /usr/local/lib/sysctl.d/
      - /usr/lib/sysctl.d/
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-7(a)
    - PCI-DSS-Req-1.4.3
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.3
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_all_secure_redirects

  - name: Disable Kernel Parameter for Accepting Secure ICMP Redirects on all IPv4
      Interfaces - Find all files that contain net.ipv4.conf.all.secure_redirects
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*net.ipv4.conf.all.secure_redirects\s*=\s*.*$'
    register: find_all_values
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-7(a)
    - PCI-DSS-Req-1.4.3
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.3
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_all_secure_redirects

  - name: Disable Kernel Parameter for Accepting Secure ICMP Redirects on all IPv4
      Interfaces - Find all files that set net.ipv4.conf.all.secure_redirects to correct
      value
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*net.ipv4.conf.all.secure_redirects\s*=\s*{{ sysctl_net_ipv4_conf_all_secure_redirects_value
        }}$'
    register: find_correct_value
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-7(a)
    - PCI-DSS-Req-1.4.3
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.3
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_all_secure_redirects

  - name: Disable Kernel Parameter for Accepting Secure ICMP Redirects on all IPv4
      Interfaces - Comment out any occurrences of net.ipv4.conf.all.secure_redirects
      from config files
    ansible.builtin.replace:
      path: '{{ item | split(":") | first }}'
      regexp: ^[\s]*net.ipv4.conf.all.secure_redirects
      replace: '#net.ipv4.conf.all.secure_redirects'
    loop: '{{ find_all_values.stdout_lines }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
      | length > find_correct_value.stdout_lines | length
    tags:
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-7(a)
    - PCI-DSS-Req-1.4.3
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.3
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_all_secure_redirects

  - name: Disable Kernel Parameter for Accepting Secure ICMP Redirects on all IPv4
      Interfaces - Comment out any occurrences of net.ipv4.conf.all.secure_redirects
      from /etc/sysctl.conf
    ansible.builtin.replace:
      path: '{{ item }}'
      regexp: ^[\s]*net.ipv4.conf.all.secure_redirects
      replace: '#net.ipv4.conf.all.secure_redirects'
    with_fileglob:
    - /etc/sysctl.conf
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-7(a)
    - PCI-DSS-Req-1.4.3
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.3
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_all_secure_redirects

  - name: Disable Kernel Parameter for Accepting Secure ICMP Redirects on all IPv4
      Interfaces - Ensure sysctl net.ipv4.conf.all.secure_redirects is set
    ansible.posix.sysctl:
      name: net.ipv4.conf.all.secure_redirects
      value: '{{ sysctl_net_ipv4_conf_all_secure_redirects_value }}'
      sysctl_file: /etc/sysctl.d/net_ipv4_conf_all_secure_redirects.conf
      state: present
      reload: true
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-7(a)
    - PCI-DSS-Req-1.4.3
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.3
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_all_secure_redirects

  - name: Disable Kernel Parameter for Accepting ICMP Redirects by Default on IPv4
      Interfaces - Set fact for sysctl paths
    ansible.builtin.set_fact:
      sysctl_paths:
      - /etc/sysctl.d/
      - /run/sysctl.d/
      - /usr/local/lib/sysctl.d/
      - /usr/lib/sysctl.d/
    when: '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.10.1.1
    - DISA-STIG-RHEL-08-040209
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-7(a)
    - PCI-DSS-Req-1.4.3
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.3
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_default_accept_redirects

  - name: Disable Kernel Parameter for Accepting ICMP Redirects by Default on IPv4
      Interfaces - Find all files that contain net.ipv4.conf.default.accept_redirects
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*net.ipv4.conf.default.accept_redirects\s*=\s*.*$'
    register: find_all_values
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.10.1.1
    - DISA-STIG-RHEL-08-040209
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-7(a)
    - PCI-DSS-Req-1.4.3
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.3
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_default_accept_redirects

  - name: Disable Kernel Parameter for Accepting ICMP Redirects by Default on IPv4
      Interfaces - Find all files that set net.ipv4.conf.default.accept_redirects
      to correct value
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*net.ipv4.conf.default.accept_redirects\s*=\s*{{ sysctl_net_ipv4_conf_default_accept_redirects_value
        }}$'
    register: find_correct_value
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.10.1.1
    - DISA-STIG-RHEL-08-040209
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-7(a)
    - PCI-DSS-Req-1.4.3
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.3
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_default_accept_redirects

  - name: Disable Kernel Parameter for Accepting ICMP Redirects by Default on IPv4
      Interfaces - Comment out any occurrences of net.ipv4.conf.default.accept_redirects
      from config files
    ansible.builtin.replace:
      path: '{{ item | split(":") | first }}'
      regexp: ^[\s]*net.ipv4.conf.default.accept_redirects
      replace: '#net.ipv4.conf.default.accept_redirects'
    loop: '{{ find_all_values.stdout_lines }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
      | length > find_correct_value.stdout_lines | length
    tags:
    - CJIS-5.10.1.1
    - DISA-STIG-RHEL-08-040209
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-7(a)
    - PCI-DSS-Req-1.4.3
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.3
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_default_accept_redirects

  - name: Disable Kernel Parameter for Accepting ICMP Redirects by Default on IPv4
      Interfaces - Comment out any occurrences of net.ipv4.conf.default.accept_redirects
      from /etc/sysctl.conf
    ansible.builtin.replace:
      path: '{{ item }}'
      regexp: ^[\s]*net.ipv4.conf.default.accept_redirects
      replace: '#net.ipv4.conf.default.accept_redirects'
    with_fileglob:
    - /etc/sysctl.conf
    when: '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.10.1.1
    - DISA-STIG-RHEL-08-040209
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-7(a)
    - PCI-DSS-Req-1.4.3
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.3
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_default_accept_redirects

  - name: Disable Kernel Parameter for Accepting ICMP Redirects by Default on IPv4
      Interfaces - Ensure sysctl net.ipv4.conf.default.accept_redirects is set
    ansible.posix.sysctl:
      name: net.ipv4.conf.default.accept_redirects
      value: '{{ sysctl_net_ipv4_conf_default_accept_redirects_value }}'
      sysctl_file: /etc/sysctl.d/net_ipv4_conf_default_accept_redirects.conf
      state: present
      reload: true
    when: '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.10.1.1
    - DISA-STIG-RHEL-08-040209
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-7(a)
    - PCI-DSS-Req-1.4.3
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.3
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_default_accept_redirects

  - name: Disable Kernel Parameter for Accepting Source-Routed Packets on IPv4 Interfaces
      by Default - Set fact for sysctl paths
    ansible.builtin.set_fact:
      sysctl_paths:
      - /etc/sysctl.d/
      - /run/sysctl.d/
      - /usr/local/lib/sysctl.d/
      - /usr/lib/sysctl.d/
    when: '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.10.1.1
    - DISA-STIG-RHEL-08-040249
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5
    - NIST-800-53-SC-7(a)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_default_accept_source_route

  - name: Disable Kernel Parameter for Accepting Source-Routed Packets on IPv4 Interfaces
      by Default - Find all files that contain net.ipv4.conf.default.accept_source_route
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*net.ipv4.conf.default.accept_source_route\s*=\s*.*$'
    register: find_all_values
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.10.1.1
    - DISA-STIG-RHEL-08-040249
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5
    - NIST-800-53-SC-7(a)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_default_accept_source_route

  - name: Disable Kernel Parameter for Accepting Source-Routed Packets on IPv4 Interfaces
      by Default - Find all files that set net.ipv4.conf.default.accept_source_route
      to correct value
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*net.ipv4.conf.default.accept_source_route\s*=\s*{{ sysctl_net_ipv4_conf_default_accept_source_route_value
        }}$'
    register: find_correct_value
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.10.1.1
    - DISA-STIG-RHEL-08-040249
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5
    - NIST-800-53-SC-7(a)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_default_accept_source_route

  - name: Disable Kernel Parameter for Accepting Source-Routed Packets on IPv4 Interfaces
      by Default - Comment out any occurrences of net.ipv4.conf.default.accept_source_route
      from config files
    ansible.builtin.replace:
      path: '{{ item | split(":") | first }}'
      regexp: ^[\s]*net.ipv4.conf.default.accept_source_route
      replace: '#net.ipv4.conf.default.accept_source_route'
    loop: '{{ find_all_values.stdout_lines }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
      | length > find_correct_value.stdout_lines | length
    tags:
    - CJIS-5.10.1.1
    - DISA-STIG-RHEL-08-040249
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5
    - NIST-800-53-SC-7(a)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_default_accept_source_route

  - name: Disable Kernel Parameter for Accepting Source-Routed Packets on IPv4 Interfaces
      by Default - Comment out any occurrences of net.ipv4.conf.default.accept_source_route
      from /etc/sysctl.conf
    ansible.builtin.replace:
      path: '{{ item }}'
      regexp: ^[\s]*net.ipv4.conf.default.accept_source_route
      replace: '#net.ipv4.conf.default.accept_source_route'
    with_fileglob:
    - /etc/sysctl.conf
    when: '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.10.1.1
    - DISA-STIG-RHEL-08-040249
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5
    - NIST-800-53-SC-7(a)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_default_accept_source_route

  - name: Disable Kernel Parameter for Accepting Source-Routed Packets on IPv4 Interfaces
      by Default - Ensure sysctl net.ipv4.conf.default.accept_source_route is set
    ansible.posix.sysctl:
      name: net.ipv4.conf.default.accept_source_route
      value: '{{ sysctl_net_ipv4_conf_default_accept_source_route_value }}'
      sysctl_file: /etc/sysctl.d/net_ipv4_conf_default_accept_source_route.conf
      state: present
      reload: true
    when: '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.10.1.1
    - DISA-STIG-RHEL-08-040249
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5
    - NIST-800-53-SC-7(a)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_default_accept_source_route

  - name: Disable Kernel Parameter for IPv4 Forwarding By Default - Set fact for sysctl
      paths
    ansible.builtin.set_fact:
      sysctl_paths:
      - /etc/sysctl.d/
      - /run/sysctl.d/
      - /usr/local/lib/sysctl.d/
      - /usr/lib/sysctl.d/
    when: '"kernel" in ansible_facts.packages'
    tags:
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_default_forwarding

  - name: Disable Kernel Parameter for IPv4 Forwarding By Default - Find all files
      that contain net.ipv4.conf.default.forwarding
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*net.ipv4.conf.default.forwarding\s*=\s*.*$'
    register: find_all_values
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_default_forwarding

  - name: Disable Kernel Parameter for IPv4 Forwarding By Default - Find all files
      that set net.ipv4.conf.default.forwarding to correct value
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*net.ipv4.conf.default.forwarding\s*=\s*{{ sysctl_net_ipv4_conf_default_forwarding_value
        }}$'
    register: find_correct_value
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_default_forwarding

  - name: Disable Kernel Parameter for IPv4 Forwarding By Default - Comment out any
      occurrences of net.ipv4.conf.default.forwarding from config files
    ansible.builtin.replace:
      path: '{{ item | split(":") | first }}'
      regexp: ^[\s]*net.ipv4.conf.default.forwarding
      replace: '#net.ipv4.conf.default.forwarding'
    loop: '{{ find_all_values.stdout_lines }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
      | length > find_correct_value.stdout_lines | length
    tags:
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_default_forwarding

  - name: Disable Kernel Parameter for IPv4 Forwarding By Default - Comment out any
      occurrences of net.ipv4.conf.default.forwarding from /etc/sysctl.conf
    ansible.builtin.replace:
      path: '{{ item }}'
      regexp: ^[\s]*net.ipv4.conf.default.forwarding
      replace: '#net.ipv4.conf.default.forwarding'
    with_fileglob:
    - /etc/sysctl.conf
    when: '"kernel" in ansible_facts.packages'
    tags:
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_default_forwarding

  - name: Disable Kernel Parameter for IPv4 Forwarding By Default - Ensure sysctl
      net.ipv4.conf.default.forwarding is set
    ansible.posix.sysctl:
      name: net.ipv4.conf.default.forwarding
      value: '{{ sysctl_net_ipv4_conf_default_forwarding_value }}'
      sysctl_file: /etc/sysctl.d/net_ipv4_conf_default_forwarding.conf
      state: present
      reload: true
    when: '"kernel" in ansible_facts.packages'
    tags:
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_default_forwarding

  - name: Enable Kernel Parameter to Log Martian Packets on all IPv4 Interfaces by
      Default - Set fact for sysctl paths
    ansible.builtin.set_fact:
      sysctl_paths:
      - /etc/sysctl.d/
      - /run/sysctl.d/
      - /usr/local/lib/sysctl.d/
      - /usr/lib/sysctl.d/
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5(3)(a)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - reboot_required
    - sysctl_net_ipv4_conf_default_log_martians
    - unknown_severity

  - name: Enable Kernel Parameter to Log Martian Packets on all IPv4 Interfaces by
      Default - Find all files that contain net.ipv4.conf.default.log_martians
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*net.ipv4.conf.default.log_martians\s*=\s*.*$'
    register: find_all_values
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5(3)(a)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - reboot_required
    - sysctl_net_ipv4_conf_default_log_martians
    - unknown_severity

  - name: Enable Kernel Parameter to Log Martian Packets on all IPv4 Interfaces by
      Default - Find all files that set net.ipv4.conf.default.log_martians to correct
      value
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*net.ipv4.conf.default.log_martians\s*=\s*{{ sysctl_net_ipv4_conf_default_log_martians_value
        }}$'
    register: find_correct_value
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5(3)(a)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - reboot_required
    - sysctl_net_ipv4_conf_default_log_martians
    - unknown_severity

  - name: Enable Kernel Parameter to Log Martian Packets on all IPv4 Interfaces by
      Default - Comment out any occurrences of net.ipv4.conf.default.log_martians
      from config files
    ansible.builtin.replace:
      path: '{{ item | split(":") | first }}'
      regexp: ^[\s]*net.ipv4.conf.default.log_martians
      replace: '#net.ipv4.conf.default.log_martians'
    loop: '{{ find_all_values.stdout_lines }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
      | length > find_correct_value.stdout_lines | length
    tags:
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5(3)(a)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - reboot_required
    - sysctl_net_ipv4_conf_default_log_martians
    - unknown_severity

  - name: Enable Kernel Parameter to Log Martian Packets on all IPv4 Interfaces by
      Default - Comment out any occurrences of net.ipv4.conf.default.log_martians
      from /etc/sysctl.conf
    ansible.builtin.replace:
      path: '{{ item }}'
      regexp: ^[\s]*net.ipv4.conf.default.log_martians
      replace: '#net.ipv4.conf.default.log_martians'
    with_fileglob:
    - /etc/sysctl.conf
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5(3)(a)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - reboot_required
    - sysctl_net_ipv4_conf_default_log_martians
    - unknown_severity

  - name: Enable Kernel Parameter to Log Martian Packets on all IPv4 Interfaces by
      Default - Ensure sysctl net.ipv4.conf.default.log_martians is set
    ansible.posix.sysctl:
      name: net.ipv4.conf.default.log_martians
      value: '{{ sysctl_net_ipv4_conf_default_log_martians_value }}'
      sysctl_file: /etc/sysctl.d/net_ipv4_conf_default_log_martians.conf
      state: present
      reload: true
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5(3)(a)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - reboot_required
    - sysctl_net_ipv4_conf_default_log_martians
    - unknown_severity

  - name: Enable Kernel Parameter to Use Reverse Path Filtering on all IPv4 Interfaces
      by Default - Set fact for sysctl paths
    ansible.builtin.set_fact:
      sysctl_paths:
      - /etc/sysctl.d/
      - /run/sysctl.d/
      - /usr/local/lib/sysctl.d/
      - /usr/lib/sysctl.d/
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-7(a)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_default_rp_filter

  - name: Enable Kernel Parameter to Use Reverse Path Filtering on all IPv4 Interfaces
      by Default - Find all files that contain net.ipv4.conf.default.rp_filter
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*net.ipv4.conf.default.rp_filter\s*=\s*.*$'
    register: find_all_values
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-7(a)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_default_rp_filter

  - name: Enable Kernel Parameter to Use Reverse Path Filtering on all IPv4 Interfaces
      by Default - Find all files that set net.ipv4.conf.default.rp_filter to correct
      value
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*net.ipv4.conf.default.rp_filter\s*=\s*{{ sysctl_net_ipv4_conf_default_rp_filter_value
        }}$'
    register: find_correct_value
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-7(a)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_default_rp_filter

  - name: Enable Kernel Parameter to Use Reverse Path Filtering on all IPv4 Interfaces
      by Default - Comment out any occurrences of net.ipv4.conf.default.rp_filter
      from config files
    ansible.builtin.replace:
      path: '{{ item | split(":") | first }}'
      regexp: ^[\s]*net.ipv4.conf.default.rp_filter
      replace: '#net.ipv4.conf.default.rp_filter'
    loop: '{{ find_all_values.stdout_lines }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
      | length > find_correct_value.stdout_lines | length
    tags:
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-7(a)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_default_rp_filter

  - name: Enable Kernel Parameter to Use Reverse Path Filtering on all IPv4 Interfaces
      by Default - Comment out any occurrences of net.ipv4.conf.default.rp_filter
      from /etc/sysctl.conf
    ansible.builtin.replace:
      path: '{{ item }}'
      regexp: ^[\s]*net.ipv4.conf.default.rp_filter
      replace: '#net.ipv4.conf.default.rp_filter'
    with_fileglob:
    - /etc/sysctl.conf
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-7(a)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_default_rp_filter

  - name: Enable Kernel Parameter to Use Reverse Path Filtering on all IPv4 Interfaces
      by Default - Ensure sysctl net.ipv4.conf.default.rp_filter is set
    ansible.posix.sysctl:
      name: net.ipv4.conf.default.rp_filter
      value: '{{ sysctl_net_ipv4_conf_default_rp_filter_value }}'
      sysctl_file: /etc/sysctl.d/net_ipv4_conf_default_rp_filter.conf
      state: present
      reload: true
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-7(a)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_default_rp_filter

  - name: Configure Kernel Parameter for Accepting Secure Redirects By Default - Set
      fact for sysctl paths
    ansible.builtin.set_fact:
      sysctl_paths:
      - /etc/sysctl.d/
      - /run/sysctl.d/
      - /usr/local/lib/sysctl.d/
      - /usr/lib/sysctl.d/
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5
    - NIST-800-53-SC-7(a)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_default_secure_redirects

  - name: Configure Kernel Parameter for Accepting Secure Redirects By Default - Find
      all files that contain net.ipv4.conf.default.secure_redirects
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*net.ipv4.conf.default.secure_redirects\s*=\s*.*$'
    register: find_all_values
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5
    - NIST-800-53-SC-7(a)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_default_secure_redirects

  - name: Configure Kernel Parameter for Accepting Secure Redirects By Default - Find
      all files that set net.ipv4.conf.default.secure_redirects to correct value
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*net.ipv4.conf.default.secure_redirects\s*=\s*{{ sysctl_net_ipv4_conf_default_secure_redirects_value
        }}$'
    register: find_correct_value
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5
    - NIST-800-53-SC-7(a)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_default_secure_redirects

  - name: Configure Kernel Parameter for Accepting Secure Redirects By Default - Comment
      out any occurrences of net.ipv4.conf.default.secure_redirects from config files
    ansible.builtin.replace:
      path: '{{ item | split(":") | first }}'
      regexp: ^[\s]*net.ipv4.conf.default.secure_redirects
      replace: '#net.ipv4.conf.default.secure_redirects'
    loop: '{{ find_all_values.stdout_lines }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
      | length > find_correct_value.stdout_lines | length
    tags:
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5
    - NIST-800-53-SC-7(a)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_default_secure_redirects

  - name: Configure Kernel Parameter for Accepting Secure Redirects By Default - Comment
      out any occurrences of net.ipv4.conf.default.secure_redirects from /etc/sysctl.conf
    ansible.builtin.replace:
      path: '{{ item }}'
      regexp: ^[\s]*net.ipv4.conf.default.secure_redirects
      replace: '#net.ipv4.conf.default.secure_redirects'
    with_fileglob:
    - /etc/sysctl.conf
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5
    - NIST-800-53-SC-7(a)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_default_secure_redirects

  - name: Configure Kernel Parameter for Accepting Secure Redirects By Default - Ensure
      sysctl net.ipv4.conf.default.secure_redirects is set
    ansible.posix.sysctl:
      name: net.ipv4.conf.default.secure_redirects
      value: '{{ sysctl_net_ipv4_conf_default_secure_redirects_value }}'
      sysctl_file: /etc/sysctl.d/net_ipv4_conf_default_secure_redirects.conf
      state: present
      reload: true
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5
    - NIST-800-53-SC-7(a)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_default_secure_redirects

  - name: Enable Kernel Parameter to Ignore ICMP Broadcast Echo Requests on IPv4 Interfaces
      - Set fact for sysctl paths
    ansible.builtin.set_fact:
      sysctl_paths:
      - /etc/sysctl.d/
      - /run/sysctl.d/
      - /usr/local/lib/sysctl.d/
      - /usr/lib/sysctl.d/
    when: '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.10.1.1
    - DISA-STIG-RHEL-08-040230
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5
    - PCI-DSS-Req-1.4.3
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.2
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_icmp_echo_ignore_broadcasts

  - name: Enable Kernel Parameter to Ignore ICMP Broadcast Echo Requests on IPv4 Interfaces
      - Find all files that contain net.ipv4.icmp_echo_ignore_broadcasts
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*net.ipv4.icmp_echo_ignore_broadcasts\s*=\s*.*$'
    register: find_all_values
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.10.1.1
    - DISA-STIG-RHEL-08-040230
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5
    - PCI-DSS-Req-1.4.3
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.2
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_icmp_echo_ignore_broadcasts

  - name: Enable Kernel Parameter to Ignore ICMP Broadcast Echo Requests on IPv4 Interfaces
      - Find all files that set net.ipv4.icmp_echo_ignore_broadcasts to correct value
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*net.ipv4.icmp_echo_ignore_broadcasts\s*=\s*{{ sysctl_net_ipv4_icmp_echo_ignore_broadcasts_value
        }}$'
    register: find_correct_value
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.10.1.1
    - DISA-STIG-RHEL-08-040230
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5
    - PCI-DSS-Req-1.4.3
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.2
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_icmp_echo_ignore_broadcasts

  - name: Enable Kernel Parameter to Ignore ICMP Broadcast Echo Requests on IPv4 Interfaces
      - Comment out any occurrences of net.ipv4.icmp_echo_ignore_broadcasts from config
      files
    ansible.builtin.replace:
      path: '{{ item | split(":") | first }}'
      regexp: ^[\s]*net.ipv4.icmp_echo_ignore_broadcasts
      replace: '#net.ipv4.icmp_echo_ignore_broadcasts'
    loop: '{{ find_all_values.stdout_lines }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
      | length > find_correct_value.stdout_lines | length
    tags:
    - CJIS-5.10.1.1
    - DISA-STIG-RHEL-08-040230
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5
    - PCI-DSS-Req-1.4.3
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.2
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_icmp_echo_ignore_broadcasts

  - name: Enable Kernel Parameter to Ignore ICMP Broadcast Echo Requests on IPv4 Interfaces
      - Comment out any occurrences of net.ipv4.icmp_echo_ignore_broadcasts from /etc/sysctl.conf
    ansible.builtin.replace:
      path: '{{ item }}'
      regexp: ^[\s]*net.ipv4.icmp_echo_ignore_broadcasts
      replace: '#net.ipv4.icmp_echo_ignore_broadcasts'
    with_fileglob:
    - /etc/sysctl.conf
    when: '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.10.1.1
    - DISA-STIG-RHEL-08-040230
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5
    - PCI-DSS-Req-1.4.3
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.2
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_icmp_echo_ignore_broadcasts

  - name: Enable Kernel Parameter to Ignore ICMP Broadcast Echo Requests on IPv4 Interfaces
      - Ensure sysctl net.ipv4.icmp_echo_ignore_broadcasts is set
    ansible.posix.sysctl:
      name: net.ipv4.icmp_echo_ignore_broadcasts
      value: '{{ sysctl_net_ipv4_icmp_echo_ignore_broadcasts_value }}'
      sysctl_file: /etc/sysctl.d/net_ipv4_icmp_echo_ignore_broadcasts.conf
      state: present
      reload: true
    when: '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.10.1.1
    - DISA-STIG-RHEL-08-040230
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5
    - PCI-DSS-Req-1.4.3
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.2
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_icmp_echo_ignore_broadcasts

  - name: Enable Kernel Parameter to Ignore Bogus ICMP Error Responses on IPv4 Interfaces
      - Set fact for sysctl paths
    ansible.builtin.set_fact:
      sysctl_paths:
      - /etc/sysctl.d/
      - /run/sysctl.d/
      - /usr/local/lib/sysctl.d/
      - /usr/lib/sysctl.d/
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5
    - PCI-DSS-Req-1.4.3
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.2
    - disable_strategy
    - low_complexity
    - medium_disruption
    - reboot_required
    - sysctl_net_ipv4_icmp_ignore_bogus_error_responses
    - unknown_severity

  - name: Enable Kernel Parameter to Ignore Bogus ICMP Error Responses on IPv4 Interfaces
      - Find all files that contain net.ipv4.icmp_ignore_bogus_error_responses
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*net.ipv4.icmp_ignore_bogus_error_responses\s*=\s*.*$'
    register: find_all_values
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5
    - PCI-DSS-Req-1.4.3
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.2
    - disable_strategy
    - low_complexity
    - medium_disruption
    - reboot_required
    - sysctl_net_ipv4_icmp_ignore_bogus_error_responses
    - unknown_severity

  - name: Enable Kernel Parameter to Ignore Bogus ICMP Error Responses on IPv4 Interfaces
      - Find all files that set net.ipv4.icmp_ignore_bogus_error_responses to correct
      value
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*net.ipv4.icmp_ignore_bogus_error_responses\s*=\s*{{ sysctl_net_ipv4_icmp_ignore_bogus_error_responses_value
        }}$'
    register: find_correct_value
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5
    - PCI-DSS-Req-1.4.3
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.2
    - disable_strategy
    - low_complexity
    - medium_disruption
    - reboot_required
    - sysctl_net_ipv4_icmp_ignore_bogus_error_responses
    - unknown_severity

  - name: Enable Kernel Parameter to Ignore Bogus ICMP Error Responses on IPv4 Interfaces
      - Comment out any occurrences of net.ipv4.icmp_ignore_bogus_error_responses
      from config files
    ansible.builtin.replace:
      path: '{{ item | split(":") | first }}'
      regexp: ^[\s]*net.ipv4.icmp_ignore_bogus_error_responses
      replace: '#net.ipv4.icmp_ignore_bogus_error_responses'
    loop: '{{ find_all_values.stdout_lines }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
      | length > find_correct_value.stdout_lines | length
    tags:
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5
    - PCI-DSS-Req-1.4.3
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.2
    - disable_strategy
    - low_complexity
    - medium_disruption
    - reboot_required
    - sysctl_net_ipv4_icmp_ignore_bogus_error_responses
    - unknown_severity

  - name: Enable Kernel Parameter to Ignore Bogus ICMP Error Responses on IPv4 Interfaces
      - Comment out any occurrences of net.ipv4.icmp_ignore_bogus_error_responses
      from /etc/sysctl.conf
    ansible.builtin.replace:
      path: '{{ item }}'
      regexp: ^[\s]*net.ipv4.icmp_ignore_bogus_error_responses
      replace: '#net.ipv4.icmp_ignore_bogus_error_responses'
    with_fileglob:
    - /etc/sysctl.conf
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5
    - PCI-DSS-Req-1.4.3
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.2
    - disable_strategy
    - low_complexity
    - medium_disruption
    - reboot_required
    - sysctl_net_ipv4_icmp_ignore_bogus_error_responses
    - unknown_severity

  - name: Enable Kernel Parameter to Ignore Bogus ICMP Error Responses on IPv4 Interfaces
      - Ensure sysctl net.ipv4.icmp_ignore_bogus_error_responses is set
    ansible.posix.sysctl:
      name: net.ipv4.icmp_ignore_bogus_error_responses
      value: '{{ sysctl_net_ipv4_icmp_ignore_bogus_error_responses_value }}'
      sysctl_file: /etc/sysctl.d/net_ipv4_icmp_ignore_bogus_error_responses.conf
      state: present
      reload: true
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5
    - PCI-DSS-Req-1.4.3
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.2
    - disable_strategy
    - low_complexity
    - medium_disruption
    - reboot_required
    - sysctl_net_ipv4_icmp_ignore_bogus_error_responses
    - unknown_severity

  - name: Enable Kernel Parameter to Use TCP Syncookies on Network Interfaces - Set
      fact for sysctl paths
    ansible.builtin.set_fact:
      sysctl_paths:
      - /etc/sysctl.d/
      - /run/sysctl.d/
      - /usr/local/lib/sysctl.d/
      - /usr/lib/sysctl.d/
    when: '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.10.1.1
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5(1)
    - NIST-800-53-SC-5(2)
    - NIST-800-53-SC-5(3)(a)
    - PCI-DSS-Req-1.4.1
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.3
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_tcp_syncookies

  - name: Enable Kernel Parameter to Use TCP Syncookies on Network Interfaces - Find
      all files that contain net.ipv4.tcp_syncookies
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*net.ipv4.tcp_syncookies\s*=\s*.*$'
    register: find_all_values
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.10.1.1
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5(1)
    - NIST-800-53-SC-5(2)
    - NIST-800-53-SC-5(3)(a)
    - PCI-DSS-Req-1.4.1
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.3
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_tcp_syncookies

  - name: Enable Kernel Parameter to Use TCP Syncookies on Network Interfaces - Find
      all files that set net.ipv4.tcp_syncookies to correct value
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*net.ipv4.tcp_syncookies\s*=\s*{{ sysctl_net_ipv4_tcp_syncookies_value
        }}$'
    register: find_correct_value
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.10.1.1
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5(1)
    - NIST-800-53-SC-5(2)
    - NIST-800-53-SC-5(3)(a)
    - PCI-DSS-Req-1.4.1
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.3
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_tcp_syncookies

  - name: Enable Kernel Parameter to Use TCP Syncookies on Network Interfaces - Comment
      out any occurrences of net.ipv4.tcp_syncookies from config files
    ansible.builtin.replace:
      path: '{{ item | split(":") | first }}'
      regexp: ^[\s]*net.ipv4.tcp_syncookies
      replace: '#net.ipv4.tcp_syncookies'
    loop: '{{ find_all_values.stdout_lines }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
      | length > find_correct_value.stdout_lines | length
    tags:
    - CJIS-5.10.1.1
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5(1)
    - NIST-800-53-SC-5(2)
    - NIST-800-53-SC-5(3)(a)
    - PCI-DSS-Req-1.4.1
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.3
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_tcp_syncookies

  - name: Enable Kernel Parameter to Use TCP Syncookies on Network Interfaces - Comment
      out any occurrences of net.ipv4.tcp_syncookies from /etc/sysctl.conf
    ansible.builtin.replace:
      path: '{{ item }}'
      regexp: ^[\s]*net.ipv4.tcp_syncookies
      replace: '#net.ipv4.tcp_syncookies'
    with_fileglob:
    - /etc/sysctl.conf
    when: '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.10.1.1
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5(1)
    - NIST-800-53-SC-5(2)
    - NIST-800-53-SC-5(3)(a)
    - PCI-DSS-Req-1.4.1
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.3
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_tcp_syncookies

  - name: Enable Kernel Parameter to Use TCP Syncookies on Network Interfaces - Ensure
      sysctl net.ipv4.tcp_syncookies is set
    ansible.posix.sysctl:
      name: net.ipv4.tcp_syncookies
      value: '{{ sysctl_net_ipv4_tcp_syncookies_value }}'
      sysctl_file: /etc/sysctl.d/net_ipv4_tcp_syncookies.conf
      state: present
      reload: true
    when: '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.10.1.1
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5(1)
    - NIST-800-53-SC-5(2)
    - NIST-800-53-SC-5(3)(a)
    - PCI-DSS-Req-1.4.1
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.3
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_tcp_syncookies

  - name: Disable Kernel Parameter for Sending ICMP Redirects on all IPv4 Interfaces
      - Set fact for sysctl paths
    ansible.builtin.set_fact:
      sysctl_paths:
      - /etc/sysctl.d/
      - /run/sysctl.d/
      - /usr/local/lib/sysctl.d/
      - /usr/lib/sysctl.d/
    when: '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.10.1.1
    - DISA-STIG-RHEL-08-040220
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5
    - NIST-800-53-SC-7(a)
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.5
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_all_send_redirects

  - name: Disable Kernel Parameter for Sending ICMP Redirects on all IPv4 Interfaces
      - Find all files that contain net.ipv4.conf.all.send_redirects
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*net.ipv4.conf.all.send_redirects\s*=\s*.*$'
    register: find_all_values
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.10.1.1
    - DISA-STIG-RHEL-08-040220
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5
    - NIST-800-53-SC-7(a)
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.5
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_all_send_redirects

  - name: Disable Kernel Parameter for Sending ICMP Redirects on all IPv4 Interfaces
      - Find all files that set net.ipv4.conf.all.send_redirects to correct value
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*net.ipv4.conf.all.send_redirects\s*=\s*0$'
    register: find_correct_value
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.10.1.1
    - DISA-STIG-RHEL-08-040220
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5
    - NIST-800-53-SC-7(a)
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.5
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_all_send_redirects

  - name: Disable Kernel Parameter for Sending ICMP Redirects on all IPv4 Interfaces
      - Comment out any occurrences of net.ipv4.conf.all.send_redirects from config
      files
    ansible.builtin.replace:
      path: '{{ item | split(":") | first }}'
      regexp: ^[\s]*net.ipv4.conf.all.send_redirects
      replace: '#net.ipv4.conf.all.send_redirects'
    loop: '{{ find_all_values.stdout_lines }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
      | length > find_correct_value.stdout_lines | length
    tags:
    - CJIS-5.10.1.1
    - DISA-STIG-RHEL-08-040220
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5
    - NIST-800-53-SC-7(a)
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.5
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_all_send_redirects

  - name: Disable Kernel Parameter for Sending ICMP Redirects on all IPv4 Interfaces
      - Comment out any occurrences of net.ipv4.conf.all.send_redirects from /etc/sysctl.conf
    ansible.builtin.replace:
      path: '{{ item }}'
      regexp: ^[\s]*net.ipv4.conf.all.send_redirects
      replace: '#net.ipv4.conf.all.send_redirects'
    with_fileglob:
    - /etc/sysctl.conf
    when: '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.10.1.1
    - DISA-STIG-RHEL-08-040220
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5
    - NIST-800-53-SC-7(a)
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.5
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_all_send_redirects

  - name: Disable Kernel Parameter for Sending ICMP Redirects on all IPv4 Interfaces
      - Ensure sysctl net.ipv4.conf.all.send_redirects is set to 0
    ansible.posix.sysctl:
      name: net.ipv4.conf.all.send_redirects
      value: '0'
      sysctl_file: /etc/sysctl.d/net_ipv4_conf_all_send_redirects.conf
      state: present
      reload: true
    when: '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.10.1.1
    - DISA-STIG-RHEL-08-040220
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5
    - NIST-800-53-SC-7(a)
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.5
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_all_send_redirects

  - name: Disable Kernel Parameter for Sending ICMP Redirects on all IPv4 Interfaces
      by Default - Set fact for sysctl paths
    ansible.builtin.set_fact:
      sysctl_paths:
      - /etc/sysctl.d/
      - /run/sysctl.d/
      - /usr/local/lib/sysctl.d/
      - /usr/lib/sysctl.d/
    when: '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.10.1.1
    - DISA-STIG-RHEL-08-040270
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5
    - NIST-800-53-SC-7(a)
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.5
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_default_send_redirects

  - name: Disable Kernel Parameter for Sending ICMP Redirects on all IPv4 Interfaces
      by Default - Find all files that contain net.ipv4.conf.default.send_redirects
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*net.ipv4.conf.default.send_redirects\s*=\s*.*$'
    register: find_all_values
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.10.1.1
    - DISA-STIG-RHEL-08-040270
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5
    - NIST-800-53-SC-7(a)
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.5
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_default_send_redirects

  - name: Disable Kernel Parameter for Sending ICMP Redirects on all IPv4 Interfaces
      by Default - Find all files that set net.ipv4.conf.default.send_redirects to
      correct value
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*net.ipv4.conf.default.send_redirects\s*=\s*0$'
    register: find_correct_value
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.10.1.1
    - DISA-STIG-RHEL-08-040270
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5
    - NIST-800-53-SC-7(a)
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.5
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_default_send_redirects

  - name: Disable Kernel Parameter for Sending ICMP Redirects on all IPv4 Interfaces
      by Default - Comment out any occurrences of net.ipv4.conf.default.send_redirects
      from config files
    ansible.builtin.replace:
      path: '{{ item | split(":") | first }}'
      regexp: ^[\s]*net.ipv4.conf.default.send_redirects
      replace: '#net.ipv4.conf.default.send_redirects'
    loop: '{{ find_all_values.stdout_lines }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
      | length > find_correct_value.stdout_lines | length
    tags:
    - CJIS-5.10.1.1
    - DISA-STIG-RHEL-08-040270
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5
    - NIST-800-53-SC-7(a)
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.5
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_default_send_redirects

  - name: Disable Kernel Parameter for Sending ICMP Redirects on all IPv4 Interfaces
      by Default - Comment out any occurrences of net.ipv4.conf.default.send_redirects
      from /etc/sysctl.conf
    ansible.builtin.replace:
      path: '{{ item }}'
      regexp: ^[\s]*net.ipv4.conf.default.send_redirects
      replace: '#net.ipv4.conf.default.send_redirects'
    with_fileglob:
    - /etc/sysctl.conf
    when: '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.10.1.1
    - DISA-STIG-RHEL-08-040270
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5
    - NIST-800-53-SC-7(a)
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.5
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_default_send_redirects

  - name: Disable Kernel Parameter for Sending ICMP Redirects on all IPv4 Interfaces
      by Default - Ensure sysctl net.ipv4.conf.default.send_redirects is set to 0
    ansible.posix.sysctl:
      name: net.ipv4.conf.default.send_redirects
      value: '0'
      sysctl_file: /etc/sysctl.d/net_ipv4_conf_default_send_redirects.conf
      state: present
      reload: true
    when: '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.10.1.1
    - DISA-STIG-RHEL-08-040270
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5
    - NIST-800-53-SC-7(a)
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.5
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_conf_default_send_redirects

  - name: Disable Kernel Parameter for IP Forwarding on IPv4 Interfaces - Set fact
      for sysctl paths
    ansible.builtin.set_fact:
      sysctl_paths:
      - /etc/sysctl.d/
      - /run/sysctl.d/
      - /usr/local/lib/sysctl.d/
      - /usr/lib/sysctl.d/
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5
    - NIST-800-53-SC-7(a)
    - PCI-DSS-Req-1.3.1
    - PCI-DSS-Req-1.3.2
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.3
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_ip_forward

  - name: Disable Kernel Parameter for IP Forwarding on IPv4 Interfaces - Find all
      files that contain net.ipv4.ip_forward
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*net.ipv4.ip_forward\s*=\s*.*$'
    register: find_all_values
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5
    - NIST-800-53-SC-7(a)
    - PCI-DSS-Req-1.3.1
    - PCI-DSS-Req-1.3.2
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.3
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_ip_forward

  - name: Disable Kernel Parameter for IP Forwarding on IPv4 Interfaces - Find all
      files that set net.ipv4.ip_forward to correct value
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*net.ipv4.ip_forward\s*=\s*0$'
    register: find_correct_value
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5
    - NIST-800-53-SC-7(a)
    - PCI-DSS-Req-1.3.1
    - PCI-DSS-Req-1.3.2
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.3
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_ip_forward

  - name: Disable Kernel Parameter for IP Forwarding on IPv4 Interfaces - Comment
      out any occurrences of net.ipv4.ip_forward from config files
    ansible.builtin.replace:
      path: '{{ item | split(":") | first }}'
      regexp: ^[\s]*net.ipv4.ip_forward
      replace: '#net.ipv4.ip_forward'
    loop: '{{ find_all_values.stdout_lines }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
      | length > find_correct_value.stdout_lines | length
    tags:
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5
    - NIST-800-53-SC-7(a)
    - PCI-DSS-Req-1.3.1
    - PCI-DSS-Req-1.3.2
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.3
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_ip_forward

  - name: Disable Kernel Parameter for IP Forwarding on IPv4 Interfaces - Comment
      out any occurrences of net.ipv4.ip_forward from /etc/sysctl.conf
    ansible.builtin.replace:
      path: '{{ item }}'
      regexp: ^[\s]*net.ipv4.ip_forward
      replace: '#net.ipv4.ip_forward'
    with_fileglob:
    - /etc/sysctl.conf
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5
    - NIST-800-53-SC-7(a)
    - PCI-DSS-Req-1.3.1
    - PCI-DSS-Req-1.3.2
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.3
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_ip_forward

  - name: Disable Kernel Parameter for IP Forwarding on IPv4 Interfaces - Ensure sysctl
      net.ipv4.ip_forward is set to 0
    ansible.posix.sysctl:
      name: net.ipv4.ip_forward
      value: '0'
      sysctl_file: /etc/sysctl.d/net_ipv4_ip_forward.conf
      state: present
      reload: true
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-171-3.1.20
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-SC-5
    - NIST-800-53-SC-7(a)
    - PCI-DSS-Req-1.3.1
    - PCI-DSS-Req-1.3.2
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.3
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_net_ipv4_ip_forward

  - name: Ensure kernel module 'atm' is disabled
    ansible.builtin.lineinfile:
      create: true
      dest: /etc/modprobe.d/atm.conf
      regexp: install\s+atm
      line: install atm /bin/false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040021
    - NIST-800-53-AC-18
    - disable_strategy
    - kernel_module_atm_disabled
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required

  - name: Ensure kernel module 'can' is disabled
    ansible.builtin.lineinfile:
      create: true
      dest: /etc/modprobe.d/can.conf
      regexp: install\s+can
      line: install can /bin/false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040022
    - NIST-800-53-AC-18
    - disable_strategy
    - kernel_module_can_disabled
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required

  - name: Ensure kernel module 'dccp' is disabled
    ansible.builtin.lineinfile:
      create: true
      dest: /etc/modprobe.d/dccp.conf
      regexp: install\s+dccp
      line: install dccp /bin/false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.10.1
    - NIST-800-171-3.4.6
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - PCI-DSS-Req-1.4.2
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.2
    - disable_strategy
    - kernel_module_dccp_disabled
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required

  - name: Ensure kernel module 'firewire-core' is disabled
    ansible.builtin.lineinfile:
      create: true
      dest: /etc/modprobe.d/firewire-core.conf
      regexp: install\s+firewire-core
      line: install firewire-core /bin/false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040026
    - NIST-800-53-AC-18
    - disable_strategy
    - kernel_module_firewire-core_disabled
    - low_complexity
    - low_severity
    - medium_disruption
    - reboot_required

  - name: Ensure kernel module 'rds' is disabled
    ansible.builtin.lineinfile:
      create: true
      dest: /etc/modprobe.d/rds.conf
      regexp: install\s+rds
      line: install rds /bin/false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - disable_strategy
    - kernel_module_rds_disabled
    - low_complexity
    - low_severity
    - medium_disruption
    - reboot_required

  - name: Ensure kernel module 'sctp' is disabled
    ansible.builtin.lineinfile:
      create: true
      dest: /etc/modprobe.d/sctp.conf
      regexp: install\s+sctp
      line: install sctp /bin/false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.10.1
    - DISA-STIG-RHEL-08-040023
    - NIST-800-171-3.4.6
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - PCI-DSS-Req-1.4.2
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.2
    - disable_strategy
    - kernel_module_sctp_disabled
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required

  - name: Ensure kernel module 'tipc' is disabled
    ansible.builtin.lineinfile:
      create: true
      dest: /etc/modprobe.d/tipc.conf
      regexp: install\s+tipc
      line: install tipc /bin/false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040024
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - disable_strategy
    - kernel_module_tipc_disabled
    - low_complexity
    - low_severity
    - medium_disruption
    - reboot_required

  - name: Deactivate Wireless Network Interfaces - NetworkManager Deactivate Wireless
      Network Interfaces
    ansible.builtin.command: nmcli radio wifi off
    when:
    - ( not ( ansible_virtualization_type in ["docker", "lxc", "openvz", "podman",
      "container"] ) )
    - '''NetworkManager'' in ansible_facts.packages'
    - ('NetworkManager.service' in ansible_facts.services and ansible_facts.services['NetworkManager.service'].state
      == 'running')
    tags:
    - DISA-STIG-RHEL-08-040110
    - NIST-800-171-3.1.16
    - NIST-800-53-AC-18(3)
    - NIST-800-53-AC-18(a)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - PCI-DSS-Req-1.3.3
    - PCI-DSSv4-1.3
    - PCI-DSSv4-1.3.3
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - unknown_strategy
    - wireless_disable_interfaces

  - name: Verify that All World-Writable Directories Have Sticky Bits Set - Define
      Excluded (Non-Local) File Systems and Paths
    ansible.builtin.set_fact:
      excluded_fstypes:
      - afs
      - autofs
      - ceph
      - cifs
      - smb3
      - smbfs
      - sshfs
      - ncpfs
      - ncp
      - nfs
      - nfs4
      - gfs
      - gfs2
      - glusterfs
      - gpfs
      - pvfs2
      - ocfs2
      - lustre
      - davfs
      - fuse.sshfs
      excluded_paths:
      - dev
      - proc
      - run
      - sys
      search_paths: []
    tags:
    - DISA-STIG-RHEL-08-010190
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - dir_perms_world_writable_sticky_bits
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Verify that All World-Writable Directories Have Sticky Bits Set - Find Relevant
      Root Directories Ignoring Pre-Defined Excluded Paths
    ansible.builtin.find:
      paths: /
      file_type: directory
      excludes: '{{ excluded_paths }}'
      hidden: true
      recurse: false
    register: result_relevant_root_dirs
    tags:
    - DISA-STIG-RHEL-08-010190
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - dir_perms_world_writable_sticky_bits
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Verify that All World-Writable Directories Have Sticky Bits Set - Include
      Relevant Root Directories in a List of Paths to be Searched
    ansible.builtin.set_fact:
      search_paths: '{{ search_paths | union([item.path]) }}'
    loop: '{{ result_relevant_root_dirs.files }}'
    tags:
    - DISA-STIG-RHEL-08-010190
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - dir_perms_world_writable_sticky_bits
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Verify that All World-Writable Directories Have Sticky Bits Set - Increment
      Search Paths List with Local Partitions Mount Points
    ansible.builtin.set_fact:
      search_paths: '{{ search_paths | union([item.mount]) }}'
    loop: '{{ ansible_mounts }}'
    when:
    - item.fstype not in excluded_fstypes
    - item.mount != '/'
    tags:
    - DISA-STIG-RHEL-08-010190
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - dir_perms_world_writable_sticky_bits
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Verify that All World-Writable Directories Have Sticky Bits Set - Increment
      Search Paths List with Local NFS File System Targets
    ansible.builtin.set_fact:
      search_paths: '{{ search_paths | union([item.device.split('':'')[1]]) }}'
    loop: '{{ ansible_mounts }}'
    when: item.device is search("localhost:")
    tags:
    - DISA-STIG-RHEL-08-010190
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - dir_perms_world_writable_sticky_bits
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Verify that All World-Writable Directories Have Sticky Bits Set - Define
      Rule Specific Facts
    ansible.builtin.set_fact:
      world_writable_dirs: []
    tags:
    - DISA-STIG-RHEL-08-010190
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - dir_perms_world_writable_sticky_bits
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Verify that All World-Writable Directories Have Sticky Bits Set - Find All
      Uncompliant Directories in Local File Systems
    ansible.builtin.command:
      cmd: find {{ item }} -xdev -type d ( -perm -0002 -a ! -perm -1000 )
    loop: '{{ search_paths }}'
    changed_when: false
    register: result_found_dirs
    tags:
    - DISA-STIG-RHEL-08-010190
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - dir_perms_world_writable_sticky_bits
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Verify that All World-Writable Directories Have Sticky Bits Set - Create
      List of World Writable Directories Without Sticky Bit
    ansible.builtin.set_fact:
      world_writable_dirs: '{{ world_writable_dirs | union(item.stdout_lines) | list
        }}'
    loop: '{{ result_found_dirs.results }}'
    when: result_found_dirs is not skipped and item is not skipped
    tags:
    - DISA-STIG-RHEL-08-010190
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - dir_perms_world_writable_sticky_bits
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Verify that All World-Writable Directories Have Sticky Bits Set - Ensure
      Sticky Bit is Set on Local World Writable Directories
    ansible.builtin.file:
      path: '{{ item }}'
      mode: a+t
    loop: '{{ world_writable_dirs }}'
    tags:
    - DISA-STIG-RHEL-08-010190
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - dir_perms_world_writable_sticky_bits
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Set the file_groupowner_etc_sysconfig_sshd_newgroup variable if represented
      by gid
    ansible.builtin.set_fact:
      file_groupowner_etc_sysconfig_sshd_newgroup: '0'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - configure_strategy
    - file_groupowner_etc_sysconfig_sshd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /etc/sysconfig/sshd
    ansible.builtin.stat:
      path: /etc/sysconfig/sshd
    register: file_exists
    when: '"kernel" in ansible_facts.packages'
    tags:
    - configure_strategy
    - file_groupowner_etc_sysconfig_sshd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure group owner on /etc/sysconfig/sshd
    ansible.builtin.file:
      path: /etc/sysconfig/sshd
      follow: false
      group: '{{ file_groupowner_etc_sysconfig_sshd_newgroup }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - file_exists.stat is defined and file_exists.stat.exists
    tags:
    - configure_strategy
    - file_groupowner_etc_sysconfig_sshd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set the file_owner_etc_sysconfig_sshd_newown variable if represented by
      uid
    ansible.builtin.set_fact:
      file_owner_etc_sysconfig_sshd_newown: '0'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - configure_strategy
    - file_owner_etc_sysconfig_sshd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /etc/sysconfig/sshd
    ansible.builtin.stat:
      path: /etc/sysconfig/sshd
    register: file_exists
    when: '"kernel" in ansible_facts.packages'
    tags:
    - configure_strategy
    - file_owner_etc_sysconfig_sshd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure owner on /etc/sysconfig/sshd
    ansible.builtin.file:
      path: /etc/sysconfig/sshd
      follow: false
      owner: '{{ file_owner_etc_sysconfig_sshd_newown }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - file_exists.stat is defined and file_exists.stat.exists
    tags:
    - configure_strategy
    - file_owner_etc_sysconfig_sshd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /etc/sysconfig/sshd
    ansible.builtin.stat:
      path: /etc/sysconfig/sshd
    register: file_exists
    when: '"kernel" in ansible_facts.packages'
    tags:
    - configure_strategy
    - file_permissions_etc_sysconfig_sshd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure permission u-xs,g-xws,o-xwrt on /etc/sysconfig/sshd
    ansible.builtin.file:
      path: /etc/sysconfig/sshd
      mode: u-xs,g-xws,o-xwrt
    when:
    - '"kernel" in ansible_facts.packages'
    - file_exists.stat is defined and file_exists.stat.exists
    tags:
    - configure_strategy
    - file_permissions_etc_sysconfig_sshd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Enable Kernel Parameter to Enforce DAC on Hardlinks - Set fact for sysctl
      paths
    ansible.builtin.set_fact:
      sysctl_paths:
      - /etc/sysctl.d/
      - /run/sysctl.d/
      - /usr/local/lib/sysctl.d/
      - /usr/lib/sysctl.d/
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-010374
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_fs_protected_hardlinks

  - name: Enable Kernel Parameter to Enforce DAC on Hardlinks - Find all files that
      contain fs.protected_hardlinks
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*fs.protected_hardlinks\s*=\s*.*$'
    register: find_all_values
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-010374
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_fs_protected_hardlinks

  - name: Enable Kernel Parameter to Enforce DAC on Hardlinks - Find all files that
      set fs.protected_hardlinks to correct value
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*fs.protected_hardlinks\s*=\s*1$'
    register: find_correct_value
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-010374
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_fs_protected_hardlinks

  - name: Enable Kernel Parameter to Enforce DAC on Hardlinks - Comment out any occurrences
      of fs.protected_hardlinks from config files
    ansible.builtin.replace:
      path: '{{ item | split(":") | first }}'
      regexp: ^[\s]*fs.protected_hardlinks
      replace: '#fs.protected_hardlinks'
    loop: '{{ find_all_values.stdout_lines }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
      | length > find_correct_value.stdout_lines | length
    tags:
    - DISA-STIG-RHEL-08-010374
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_fs_protected_hardlinks

  - name: Enable Kernel Parameter to Enforce DAC on Hardlinks - Comment out any occurrences
      of fs.protected_hardlinks from /etc/sysctl.conf
    ansible.builtin.replace:
      path: '{{ item }}'
      regexp: ^[\s]*fs.protected_hardlinks
      replace: '#fs.protected_hardlinks'
    with_fileglob:
    - /etc/sysctl.conf
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-010374
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_fs_protected_hardlinks

  - name: Enable Kernel Parameter to Enforce DAC on Hardlinks - Ensure sysctl fs.protected_hardlinks
      is set to 1
    ansible.posix.sysctl:
      name: fs.protected_hardlinks
      value: '1'
      sysctl_file: /etc/sysctl.d/fs_protected_hardlinks.conf
      state: present
      reload: true
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-010374
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_fs_protected_hardlinks

  - name: Enable Kernel Parameter to Enforce DAC on Symlinks - Set fact for sysctl
      paths
    ansible.builtin.set_fact:
      sysctl_paths:
      - /etc/sysctl.d/
      - /run/sysctl.d/
      - /usr/local/lib/sysctl.d/
      - /usr/lib/sysctl.d/
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-010373
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_fs_protected_symlinks

  - name: Enable Kernel Parameter to Enforce DAC on Symlinks - Find all files that
      contain fs.protected_symlinks
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*fs.protected_symlinks\s*=\s*.*$'
    register: find_all_values
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-010373
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_fs_protected_symlinks

  - name: Enable Kernel Parameter to Enforce DAC on Symlinks - Find all files that
      set fs.protected_symlinks to correct value
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*fs.protected_symlinks\s*=\s*1$'
    register: find_correct_value
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-010373
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_fs_protected_symlinks

  - name: Enable Kernel Parameter to Enforce DAC on Symlinks - Comment out any occurrences
      of fs.protected_symlinks from config files
    ansible.builtin.replace:
      path: '{{ item | split(":") | first }}'
      regexp: ^[\s]*fs.protected_symlinks
      replace: '#fs.protected_symlinks'
    loop: '{{ find_all_values.stdout_lines }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
      | length > find_correct_value.stdout_lines | length
    tags:
    - DISA-STIG-RHEL-08-010373
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_fs_protected_symlinks

  - name: Enable Kernel Parameter to Enforce DAC on Symlinks - Comment out any occurrences
      of fs.protected_symlinks from /etc/sysctl.conf
    ansible.builtin.replace:
      path: '{{ item }}'
      regexp: ^[\s]*fs.protected_symlinks
      replace: '#fs.protected_symlinks'
    with_fileglob:
    - /etc/sysctl.conf
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-010373
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_fs_protected_symlinks

  - name: Enable Kernel Parameter to Enforce DAC on Symlinks - Ensure sysctl fs.protected_symlinks
      is set to 1
    ansible.posix.sysctl:
      name: fs.protected_symlinks
      value: '1'
      sysctl_file: /etc/sysctl.d/fs_protected_symlinks.conf
      state: present
      reload: true
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-010373
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_fs_protected_symlinks

  - name: Set the file_groupowner_backup_etc_group_newgroup variable if represented
      by gid
    ansible.builtin.set_fact:
      file_groupowner_backup_etc_group_newgroup: '0'
    tags:
    - NIST-800-53-AC-6 (1)
    - PCI-DSS-Req-8.7
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_groupowner_backup_etc_group
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /etc/group-
    ansible.builtin.stat:
      path: /etc/group-
    register: file_exists
    tags:
    - NIST-800-53-AC-6 (1)
    - PCI-DSS-Req-8.7
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_groupowner_backup_etc_group
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure group owner on /etc/group-
    ansible.builtin.file:
      path: /etc/group-
      follow: false
      group: '{{ file_groupowner_backup_etc_group_newgroup }}'
    when: file_exists.stat is defined and file_exists.stat.exists
    tags:
    - NIST-800-53-AC-6 (1)
    - PCI-DSS-Req-8.7
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_groupowner_backup_etc_group
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set the file_groupowner_backup_etc_gshadow_newgroup variable if represented
      by gid
    ansible.builtin.set_fact:
      file_groupowner_backup_etc_gshadow_newgroup: '0'
    tags:
    - NIST-800-53-AC-6 (1)
    - PCI-DSS-Req-8.7
    - configure_strategy
    - file_groupowner_backup_etc_gshadow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /etc/gshadow-
    ansible.builtin.stat:
      path: /etc/gshadow-
    register: file_exists
    tags:
    - NIST-800-53-AC-6 (1)
    - PCI-DSS-Req-8.7
    - configure_strategy
    - file_groupowner_backup_etc_gshadow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure group owner on /etc/gshadow-
    ansible.builtin.file:
      path: /etc/gshadow-
      follow: false
      group: '{{ file_groupowner_backup_etc_gshadow_newgroup }}'
    when: file_exists.stat is defined and file_exists.stat.exists
    tags:
    - NIST-800-53-AC-6 (1)
    - PCI-DSS-Req-8.7
    - configure_strategy
    - file_groupowner_backup_etc_gshadow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set the file_groupowner_backup_etc_passwd_newgroup variable if represented
      by gid
    ansible.builtin.set_fact:
      file_groupowner_backup_etc_passwd_newgroup: '0'
    tags:
    - NIST-800-53-AC-6 (1)
    - PCI-DSS-Req-8.7
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_groupowner_backup_etc_passwd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /etc/passwd-
    ansible.builtin.stat:
      path: /etc/passwd-
    register: file_exists
    tags:
    - NIST-800-53-AC-6 (1)
    - PCI-DSS-Req-8.7
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_groupowner_backup_etc_passwd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure group owner on /etc/passwd-
    ansible.builtin.file:
      path: /etc/passwd-
      follow: false
      group: '{{ file_groupowner_backup_etc_passwd_newgroup }}'
    when: file_exists.stat is defined and file_exists.stat.exists
    tags:
    - NIST-800-53-AC-6 (1)
    - PCI-DSS-Req-8.7
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_groupowner_backup_etc_passwd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set the file_groupowner_backup_etc_shadow_newgroup variable if represented
      by gid
    ansible.builtin.set_fact:
      file_groupowner_backup_etc_shadow_newgroup: '0'
    tags:
    - PCI-DSS-Req-8.7
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_groupowner_backup_etc_shadow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /etc/shadow-
    ansible.builtin.stat:
      path: /etc/shadow-
    register: file_exists
    tags:
    - PCI-DSS-Req-8.7
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_groupowner_backup_etc_shadow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure group owner on /etc/shadow-
    ansible.builtin.file:
      path: /etc/shadow-
      follow: false
      group: '{{ file_groupowner_backup_etc_shadow_newgroup }}'
    when: file_exists.stat is defined and file_exists.stat.exists
    tags:
    - PCI-DSS-Req-8.7
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_groupowner_backup_etc_shadow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set the file_groupowner_etc_group_newgroup variable if represented by gid
    ansible.builtin.set_fact:
      file_groupowner_etc_group_newgroup: '0'
    tags:
    - CJIS-5.5.2.2
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-8.7.c
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_groupowner_etc_group
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /etc/group
    ansible.builtin.stat:
      path: /etc/group
    register: file_exists
    tags:
    - CJIS-5.5.2.2
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-8.7.c
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_groupowner_etc_group
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure group owner on /etc/group
    ansible.builtin.file:
      path: /etc/group
      follow: false
      group: '{{ file_groupowner_etc_group_newgroup }}'
    when: file_exists.stat is defined and file_exists.stat.exists
    tags:
    - CJIS-5.5.2.2
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-8.7.c
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_groupowner_etc_group
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set the file_groupowner_etc_gshadow_newgroup variable if represented by
      gid
    ansible.builtin.set_fact:
      file_groupowner_etc_gshadow_newgroup: '0'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - configure_strategy
    - file_groupowner_etc_gshadow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /etc/gshadow
    ansible.builtin.stat:
      path: /etc/gshadow
    register: file_exists
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - configure_strategy
    - file_groupowner_etc_gshadow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure group owner on /etc/gshadow
    ansible.builtin.file:
      path: /etc/gshadow
      follow: false
      group: '{{ file_groupowner_etc_gshadow_newgroup }}'
    when: file_exists.stat is defined and file_exists.stat.exists
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - configure_strategy
    - file_groupowner_etc_gshadow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set the file_groupowner_etc_passwd_newgroup variable if represented by gid
    ansible.builtin.set_fact:
      file_groupowner_etc_passwd_newgroup: '0'
    tags:
    - CJIS-5.5.2.2
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-8.7.c
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_groupowner_etc_passwd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /etc/passwd
    ansible.builtin.stat:
      path: /etc/passwd
    register: file_exists
    tags:
    - CJIS-5.5.2.2
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-8.7.c
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_groupowner_etc_passwd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure group owner on /etc/passwd
    ansible.builtin.file:
      path: /etc/passwd
      follow: false
      group: '{{ file_groupowner_etc_passwd_newgroup }}'
    when: file_exists.stat is defined and file_exists.stat.exists
    tags:
    - CJIS-5.5.2.2
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-8.7.c
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_groupowner_etc_passwd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set the file_groupowner_etc_security_opasswd_newgroup variable if represented
      by gid
    ansible.builtin.set_fact:
      file_groupowner_etc_security_opasswd_newgroup: '0'
    tags:
    - configure_strategy
    - file_groupowner_etc_security_opasswd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /etc/security/opasswd
    ansible.builtin.stat:
      path: /etc/security/opasswd
    register: file_exists
    tags:
    - configure_strategy
    - file_groupowner_etc_security_opasswd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure group owner on /etc/security/opasswd
    ansible.builtin.file:
      path: /etc/security/opasswd
      follow: false
      group: '{{ file_groupowner_etc_security_opasswd_newgroup }}'
    when: file_exists.stat is defined and file_exists.stat.exists
    tags:
    - configure_strategy
    - file_groupowner_etc_security_opasswd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set the file_groupowner_etc_security_opasswd_old_newgroup variable if represented
      by gid
    ansible.builtin.set_fact:
      file_groupowner_etc_security_opasswd_old_newgroup: '0'
    tags:
    - configure_strategy
    - file_groupowner_etc_security_opasswd_old
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /etc/security/opasswd.old
    ansible.builtin.stat:
      path: /etc/security/opasswd.old
    register: file_exists
    tags:
    - configure_strategy
    - file_groupowner_etc_security_opasswd_old
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure group owner on /etc/security/opasswd.old
    ansible.builtin.file:
      path: /etc/security/opasswd.old
      follow: false
      group: '{{ file_groupowner_etc_security_opasswd_old_newgroup }}'
    when: file_exists.stat is defined and file_exists.stat.exists
    tags:
    - configure_strategy
    - file_groupowner_etc_security_opasswd_old
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set the file_groupowner_etc_shadow_newgroup variable if represented by gid
    ansible.builtin.set_fact:
      file_groupowner_etc_shadow_newgroup: '0'
    tags:
    - CJIS-5.5.2.2
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-8.7.c
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_groupowner_etc_shadow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /etc/shadow
    ansible.builtin.stat:
      path: /etc/shadow
    register: file_exists
    tags:
    - CJIS-5.5.2.2
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-8.7.c
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_groupowner_etc_shadow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure group owner on /etc/shadow
    ansible.builtin.file:
      path: /etc/shadow
      follow: false
      group: '{{ file_groupowner_etc_shadow_newgroup }}'
    when: file_exists.stat is defined and file_exists.stat.exists
    tags:
    - CJIS-5.5.2.2
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-8.7.c
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_groupowner_etc_shadow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set the file_groupowner_etc_shells_newgroup variable if represented by gid
    ansible.builtin.set_fact:
      file_groupowner_etc_shells_newgroup: '0'
    tags:
    - NIST-800-53-AC-3
    - NIST-800-53-MP-2
    - configure_strategy
    - file_groupowner_etc_shells
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /etc/shells
    ansible.builtin.stat:
      path: /etc/shells
    register: file_exists
    tags:
    - NIST-800-53-AC-3
    - NIST-800-53-MP-2
    - configure_strategy
    - file_groupowner_etc_shells
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure group owner on /etc/shells
    ansible.builtin.file:
      path: /etc/shells
      follow: false
      group: '{{ file_groupowner_etc_shells_newgroup }}'
    when: file_exists.stat is defined and file_exists.stat.exists
    tags:
    - NIST-800-53-AC-3
    - NIST-800-53-MP-2
    - configure_strategy
    - file_groupowner_etc_shells
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set the file_owner_backup_etc_group_newown variable if represented by uid
    ansible.builtin.set_fact:
      file_owner_backup_etc_group_newown: '0'
    tags:
    - NIST-800-53-AC-6 (1)
    - PCI-DSS-Req-8.7.c
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_owner_backup_etc_group
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /etc/group-
    ansible.builtin.stat:
      path: /etc/group-
    register: file_exists
    tags:
    - NIST-800-53-AC-6 (1)
    - PCI-DSS-Req-8.7.c
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_owner_backup_etc_group
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure owner on /etc/group-
    ansible.builtin.file:
      path: /etc/group-
      follow: false
      owner: '{{ file_owner_backup_etc_group_newown }}'
    when: file_exists.stat is defined and file_exists.stat.exists
    tags:
    - NIST-800-53-AC-6 (1)
    - PCI-DSS-Req-8.7.c
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_owner_backup_etc_group
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set the file_owner_backup_etc_gshadow_newown variable if represented by
      uid
    ansible.builtin.set_fact:
      file_owner_backup_etc_gshadow_newown: '0'
    tags:
    - NIST-800-53-AC-6 (1)
    - PCI-DSS-Req-8.7
    - configure_strategy
    - file_owner_backup_etc_gshadow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /etc/gshadow-
    ansible.builtin.stat:
      path: /etc/gshadow-
    register: file_exists
    tags:
    - NIST-800-53-AC-6 (1)
    - PCI-DSS-Req-8.7
    - configure_strategy
    - file_owner_backup_etc_gshadow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure owner on /etc/gshadow-
    ansible.builtin.file:
      path: /etc/gshadow-
      follow: false
      owner: '{{ file_owner_backup_etc_gshadow_newown }}'
    when: file_exists.stat is defined and file_exists.stat.exists
    tags:
    - NIST-800-53-AC-6 (1)
    - PCI-DSS-Req-8.7
    - configure_strategy
    - file_owner_backup_etc_gshadow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set the file_owner_backup_etc_passwd_newown variable if represented by uid
    ansible.builtin.set_fact:
      file_owner_backup_etc_passwd_newown: '0'
    tags:
    - NIST-800-53-AC-6 (1)
    - PCI-DSS-Req-8.7.c
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_owner_backup_etc_passwd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /etc/passwd-
    ansible.builtin.stat:
      path: /etc/passwd-
    register: file_exists
    tags:
    - NIST-800-53-AC-6 (1)
    - PCI-DSS-Req-8.7.c
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_owner_backup_etc_passwd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure owner on /etc/passwd-
    ansible.builtin.file:
      path: /etc/passwd-
      follow: false
      owner: '{{ file_owner_backup_etc_passwd_newown }}'
    when: file_exists.stat is defined and file_exists.stat.exists
    tags:
    - NIST-800-53-AC-6 (1)
    - PCI-DSS-Req-8.7.c
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_owner_backup_etc_passwd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set the file_owner_backup_etc_shadow_newown variable if represented by uid
    ansible.builtin.set_fact:
      file_owner_backup_etc_shadow_newown: '0'
    tags:
    - NIST-800-53-AC-6 (1)
    - PCI-DSS-Req-8.7.c
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_owner_backup_etc_shadow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /etc/shadow-
    ansible.builtin.stat:
      path: /etc/shadow-
    register: file_exists
    tags:
    - NIST-800-53-AC-6 (1)
    - PCI-DSS-Req-8.7.c
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_owner_backup_etc_shadow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure owner on /etc/shadow-
    ansible.builtin.file:
      path: /etc/shadow-
      follow: false
      owner: '{{ file_owner_backup_etc_shadow_newown }}'
    when: file_exists.stat is defined and file_exists.stat.exists
    tags:
    - NIST-800-53-AC-6 (1)
    - PCI-DSS-Req-8.7.c
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_owner_backup_etc_shadow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set the file_owner_etc_group_newown variable if represented by uid
    ansible.builtin.set_fact:
      file_owner_etc_group_newown: '0'
    tags:
    - CJIS-5.5.2.2
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-8.7.c
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_owner_etc_group
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /etc/group
    ansible.builtin.stat:
      path: /etc/group
    register: file_exists
    tags:
    - CJIS-5.5.2.2
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-8.7.c
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_owner_etc_group
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure owner on /etc/group
    ansible.builtin.file:
      path: /etc/group
      follow: false
      owner: '{{ file_owner_etc_group_newown }}'
    when: file_exists.stat is defined and file_exists.stat.exists
    tags:
    - CJIS-5.5.2.2
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-8.7.c
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_owner_etc_group
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set the file_owner_etc_gshadow_newown variable if represented by uid
    ansible.builtin.set_fact:
      file_owner_etc_gshadow_newown: '0'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - configure_strategy
    - file_owner_etc_gshadow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /etc/gshadow
    ansible.builtin.stat:
      path: /etc/gshadow
    register: file_exists
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - configure_strategy
    - file_owner_etc_gshadow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure owner on /etc/gshadow
    ansible.builtin.file:
      path: /etc/gshadow
      follow: false
      owner: '{{ file_owner_etc_gshadow_newown }}'
    when: file_exists.stat is defined and file_exists.stat.exists
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - configure_strategy
    - file_owner_etc_gshadow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set the file_owner_etc_passwd_newown variable if represented by uid
    ansible.builtin.set_fact:
      file_owner_etc_passwd_newown: '0'
    tags:
    - CJIS-5.5.2.2
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-8.7.c
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_owner_etc_passwd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /etc/passwd
    ansible.builtin.stat:
      path: /etc/passwd
    register: file_exists
    tags:
    - CJIS-5.5.2.2
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-8.7.c
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_owner_etc_passwd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure owner on /etc/passwd
    ansible.builtin.file:
      path: /etc/passwd
      follow: false
      owner: '{{ file_owner_etc_passwd_newown }}'
    when: file_exists.stat is defined and file_exists.stat.exists
    tags:
    - CJIS-5.5.2.2
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-8.7.c
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_owner_etc_passwd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set the file_owner_etc_security_opasswd_newown variable if represented by
      uid
    ansible.builtin.set_fact:
      file_owner_etc_security_opasswd_newown: '0'
    tags:
    - configure_strategy
    - file_owner_etc_security_opasswd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /etc/security/opasswd
    ansible.builtin.stat:
      path: /etc/security/opasswd
    register: file_exists
    tags:
    - configure_strategy
    - file_owner_etc_security_opasswd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure owner on /etc/security/opasswd
    ansible.builtin.file:
      path: /etc/security/opasswd
      follow: false
      owner: '{{ file_owner_etc_security_opasswd_newown }}'
    when: file_exists.stat is defined and file_exists.stat.exists
    tags:
    - configure_strategy
    - file_owner_etc_security_opasswd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set the file_owner_etc_security_opasswd_old_newown variable if represented
      by uid
    ansible.builtin.set_fact:
      file_owner_etc_security_opasswd_old_newown: '0'
    tags:
    - configure_strategy
    - file_owner_etc_security_opasswd_old
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /etc/security/opasswd.old
    ansible.builtin.stat:
      path: /etc/security/opasswd.old
    register: file_exists
    tags:
    - configure_strategy
    - file_owner_etc_security_opasswd_old
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure owner on /etc/security/opasswd.old
    ansible.builtin.file:
      path: /etc/security/opasswd.old
      follow: false
      owner: '{{ file_owner_etc_security_opasswd_old_newown }}'
    when: file_exists.stat is defined and file_exists.stat.exists
    tags:
    - configure_strategy
    - file_owner_etc_security_opasswd_old
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set the file_owner_etc_shadow_newown variable if represented by uid
    ansible.builtin.set_fact:
      file_owner_etc_shadow_newown: '0'
    tags:
    - CJIS-5.5.2.2
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-8.7.c
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_owner_etc_shadow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /etc/shadow
    ansible.builtin.stat:
      path: /etc/shadow
    register: file_exists
    tags:
    - CJIS-5.5.2.2
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-8.7.c
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_owner_etc_shadow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure owner on /etc/shadow
    ansible.builtin.file:
      path: /etc/shadow
      follow: false
      owner: '{{ file_owner_etc_shadow_newown }}'
    when: file_exists.stat is defined and file_exists.stat.exists
    tags:
    - CJIS-5.5.2.2
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-8.7.c
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_owner_etc_shadow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set the file_owner_etc_shells_newown variable if represented by uid
    ansible.builtin.set_fact:
      file_owner_etc_shells_newown: '0'
    tags:
    - NIST-800-53-AC-3
    - NIST-800-53-MP-2
    - configure_strategy
    - file_owner_etc_shells
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /etc/shells
    ansible.builtin.stat:
      path: /etc/shells
    register: file_exists
    tags:
    - NIST-800-53-AC-3
    - NIST-800-53-MP-2
    - configure_strategy
    - file_owner_etc_shells
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure owner on /etc/shells
    ansible.builtin.file:
      path: /etc/shells
      follow: false
      owner: '{{ file_owner_etc_shells_newown }}'
    when: file_exists.stat is defined and file_exists.stat.exists
    tags:
    - NIST-800-53-AC-3
    - NIST-800-53-MP-2
    - configure_strategy
    - file_owner_etc_shells
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /etc/group-
    ansible.builtin.stat:
      path: /etc/group-
    register: file_exists
    tags:
    - NIST-800-53-AC-6 (1)
    - PCI-DSS-Req-8.7.c
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_permissions_backup_etc_group
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure permission u-xs,g-xws,o-xwt on /etc/group-
    ansible.builtin.file:
      path: /etc/group-
      mode: u-xs,g-xws,o-xwt
    when: file_exists.stat is defined and file_exists.stat.exists
    tags:
    - NIST-800-53-AC-6 (1)
    - PCI-DSS-Req-8.7.c
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_permissions_backup_etc_group
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /etc/gshadow-
    ansible.builtin.stat:
      path: /etc/gshadow-
    register: file_exists
    tags:
    - NIST-800-53-AC-6 (1)
    - configure_strategy
    - file_permissions_backup_etc_gshadow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure permission u-xwrs,g-xwrs,o-xwrt on /etc/gshadow-
    ansible.builtin.file:
      path: /etc/gshadow-
      mode: u-xwrs,g-xwrs,o-xwrt
    when: file_exists.stat is defined and file_exists.stat.exists
    tags:
    - NIST-800-53-AC-6 (1)
    - configure_strategy
    - file_permissions_backup_etc_gshadow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /etc/passwd-
    ansible.builtin.stat:
      path: /etc/passwd-
    register: file_exists
    tags:
    - NIST-800-53-AC-6 (1)
    - PCI-DSS-Req-8.7.c
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_permissions_backup_etc_passwd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure permission u-xs,g-xws,o-xwt on /etc/passwd-
    ansible.builtin.file:
      path: /etc/passwd-
      mode: u-xs,g-xws,o-xwt
    when: file_exists.stat is defined and file_exists.stat.exists
    tags:
    - NIST-800-53-AC-6 (1)
    - PCI-DSS-Req-8.7.c
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_permissions_backup_etc_passwd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /etc/shadow-
    ansible.builtin.stat:
      path: /etc/shadow-
    register: file_exists
    tags:
    - NIST-800-53-AC-6 (1)
    - PCI-DSS-Req-8.7.c
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_permissions_backup_etc_shadow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure permission u-xwrs,g-xwrs,o-xwrt on /etc/shadow-
    ansible.builtin.file:
      path: /etc/shadow-
      mode: u-xwrs,g-xwrs,o-xwrt
    when: file_exists.stat is defined and file_exists.stat.exists
    tags:
    - NIST-800-53-AC-6 (1)
    - PCI-DSS-Req-8.7.c
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_permissions_backup_etc_shadow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /etc/group
    ansible.builtin.stat:
      path: /etc/group
    register: file_exists
    tags:
    - CJIS-5.5.2.2
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-8.7.c
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_permissions_etc_group
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure permission u-xs,g-xws,o-xwt on /etc/group
    ansible.builtin.file:
      path: /etc/group
      mode: u-xs,g-xws,o-xwt
    when: file_exists.stat is defined and file_exists.stat.exists
    tags:
    - CJIS-5.5.2.2
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-8.7.c
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_permissions_etc_group
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /etc/gshadow
    ansible.builtin.stat:
      path: /etc/gshadow
    register: file_exists
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - configure_strategy
    - file_permissions_etc_gshadow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure permission u-xwrs,g-xwrs,o-xwrt on /etc/gshadow
    ansible.builtin.file:
      path: /etc/gshadow
      mode: u-xwrs,g-xwrs,o-xwrt
    when: file_exists.stat is defined and file_exists.stat.exists
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - configure_strategy
    - file_permissions_etc_gshadow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /etc/passwd
    ansible.builtin.stat:
      path: /etc/passwd
    register: file_exists
    tags:
    - CJIS-5.5.2.2
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-8.7.c
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_permissions_etc_passwd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure permission u-xs,g-xws,o-xwt on /etc/passwd
    ansible.builtin.file:
      path: /etc/passwd
      mode: u-xs,g-xws,o-xwt
    when: file_exists.stat is defined and file_exists.stat.exists
    tags:
    - CJIS-5.5.2.2
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-8.7.c
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_permissions_etc_passwd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /etc/security/opasswd
    ansible.builtin.stat:
      path: /etc/security/opasswd
    register: file_exists
    tags:
    - configure_strategy
    - file_permissions_etc_security_opasswd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure permission u-xs,g-xwrs,o-xwrt on /etc/security/opasswd
    ansible.builtin.file:
      path: /etc/security/opasswd
      mode: u-xs,g-xwrs,o-xwrt
    when: file_exists.stat is defined and file_exists.stat.exists
    tags:
    - configure_strategy
    - file_permissions_etc_security_opasswd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /etc/security/opasswd.old
    ansible.builtin.stat:
      path: /etc/security/opasswd.old
    register: file_exists
    tags:
    - configure_strategy
    - file_permissions_etc_security_opasswd_old
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure permission u-xs,g-xwrs,o-xwrt on /etc/security/opasswd.old
    ansible.builtin.file:
      path: /etc/security/opasswd.old
      mode: u-xs,g-xwrs,o-xwrt
    when: file_exists.stat is defined and file_exists.stat.exists
    tags:
    - configure_strategy
    - file_permissions_etc_security_opasswd_old
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /etc/shadow
    ansible.builtin.stat:
      path: /etc/shadow
    register: file_exists
    tags:
    - CJIS-5.5.2.2
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-8.7.c
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_permissions_etc_shadow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure permission u-xwrs,g-xwrs,o-xwrt on /etc/shadow
    ansible.builtin.file:
      path: /etc/shadow
      mode: u-xwrs,g-xwrs,o-xwrt
    when: file_exists.stat is defined and file_exists.stat.exists
    tags:
    - CJIS-5.5.2.2
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-8.7.c
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_permissions_etc_shadow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /etc/shells
    ansible.builtin.stat:
      path: /etc/shells
    register: file_exists
    tags:
    - NIST-800-53-AC-3
    - NIST-800-53-MP-2
    - configure_strategy
    - file_permissions_etc_shells
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure permission u-xs,g-xws,o-xwt on /etc/shells
    ansible.builtin.file:
      path: /etc/shells
      mode: u-xs,g-xws,o-xwt
    when: file_exists.stat is defined and file_exists.stat.exists
    tags:
    - NIST-800-53-AC-3
    - NIST-800-53-MP-2
    - configure_strategy
    - file_permissions_etc_shells
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure kernel module 'cramfs' is disabled
    ansible.builtin.lineinfile:
      create: true
      dest: /etc/modprobe.d/cramfs.conf
      regexp: install\s+cramfs
      line: install cramfs /bin/false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040025
    - NIST-800-171-3.4.6
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - disable_strategy
    - kernel_module_cramfs_disabled
    - low_complexity
    - low_severity
    - medium_disruption
    - reboot_required

  - name: Ensure kernel module 'freevxfs' is disabled
    ansible.builtin.lineinfile:
      create: true
      dest: /etc/modprobe.d/freevxfs.conf
      regexp: install\s+freevxfs
      line: install freevxfs /bin/false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-171-3.4.6
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - disable_strategy
    - kernel_module_freevxfs_disabled
    - low_complexity
    - low_severity
    - medium_disruption
    - reboot_required

  - name: Ensure kernel module 'hfs' is disabled
    ansible.builtin.lineinfile:
      create: true
      dest: /etc/modprobe.d/hfs.conf
      regexp: install\s+hfs
      line: install hfs /bin/false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-171-3.4.6
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - disable_strategy
    - kernel_module_hfs_disabled
    - low_complexity
    - low_severity
    - medium_disruption
    - reboot_required

  - name: Ensure kernel module 'hfsplus' is disabled
    ansible.builtin.lineinfile:
      create: true
      dest: /etc/modprobe.d/hfsplus.conf
      regexp: install\s+hfsplus
      line: install hfsplus /bin/false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-171-3.4.6
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - disable_strategy
    - kernel_module_hfsplus_disabled
    - low_complexity
    - low_severity
    - medium_disruption
    - reboot_required

  - name: Ensure kernel module 'jffs2' is disabled
    ansible.builtin.lineinfile:
      create: true
      dest: /etc/modprobe.d/jffs2.conf
      regexp: install\s+jffs2
      line: install jffs2 /bin/false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-171-3.4.6
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - disable_strategy
    - kernel_module_jffs2_disabled
    - low_complexity
    - low_severity
    - medium_disruption
    - reboot_required

  - name: Ensure kernel module 'overlayfs' is disabled
    ansible.builtin.lineinfile:
      create: true
      dest: /etc/modprobe.d/overlayfs.conf
      regexp: install\s+overlayfs
      line: install overlayfs /bin/false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - disable_strategy
    - kernel_module_overlayfs_disabled
    - low_complexity
    - low_severity
    - medium_disruption
    - reboot_required

  - name: Ensure kernel module 'squashfs' is disabled
    ansible.builtin.lineinfile:
      create: true
      dest: /etc/modprobe.d/squashfs.conf
      regexp: install\s+squashfs
      line: install squashfs /bin/false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-171-3.4.6
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - disable_strategy
    - kernel_module_squashfs_disabled
    - low_complexity
    - low_severity
    - medium_disruption
    - reboot_required

  - name: Ensure kernel module 'udf' is disabled
    ansible.builtin.lineinfile:
      create: true
      dest: /etc/modprobe.d/udf.conf
      regexp: install\s+udf
      line: install udf /bin/false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-171-3.4.6
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - disable_strategy
    - kernel_module_udf_disabled
    - low_complexity
    - low_severity
    - medium_disruption
    - reboot_required

  - name: Ensure kernel module 'usb-storage' is disabled
    ansible.builtin.lineinfile:
      create: true
      dest: /etc/modprobe.d/usb-storage.conf
      regexp: install\s+usb-storage
      line: install usb-storage /bin/false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040080
    - NIST-800-171-3.1.21
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - PCI-DSSv4-3.4
    - PCI-DSSv4-3.4.2
    - disable_strategy
    - kernel_module_usb-storage_disabled
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required

  - name: 'Add nodev Option to /dev/shm: Check information associated to mountpoint'
    ansible.builtin.command: findmnt  '/dev/shm'
    register: device_name
    failed_when: device_name.rc > 1
    changed_when: false
    check_mode: false
    when: ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    tags:
    - DISA-STIG-RHEL-08-040120
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_dev_shm_nodev
    - no_reboot_needed

  - name: 'Add nodev Option to /dev/shm: Create mount_info dictionary variable'
    set_fact:
      mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
    with_together:
    - '{{ device_name.stdout_lines[0].split() | map(''lower'') | list }}'
    - '{{ device_name.stdout_lines[1].split() | list }}'
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - device_name.stdout is defined and device_name.stdout_lines is defined
    - (device_name.stdout | length > 0)
    tags:
    - DISA-STIG-RHEL-08-040120
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_dev_shm_nodev
    - no_reboot_needed

  - name: 'Add nodev Option to /dev/shm: If /dev/shm not mounted, craft mount_info
      manually'
    set_fact:
      mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
    with_together:
    - - target
      - source
      - fstype
      - options
    - - /dev/shm
      - tmpfs
      - tmpfs
      - defaults
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - ("" | length == 0)
    - device_name.stdout is defined and device_name.stdout_lines is defined
    - (device_name.stdout | length == 0)
    tags:
    - DISA-STIG-RHEL-08-040120
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_dev_shm_nodev
    - no_reboot_needed

  - name: 'Add nodev Option to /dev/shm: Make sure nodev option is part of the to
      /dev/shm options'
    set_fact:
      mount_info: '{{ mount_info | combine( {''options'':''''~(mount_info.options
        | default(''''))~('','' if (mount_info.options | default('''')) else '''')~''nodev''
        }) }}'
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - mount_info is defined and "nodev" not in (mount_info.options | default(''))
    tags:
    - DISA-STIG-RHEL-08-040120
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_dev_shm_nodev
    - no_reboot_needed

  - name: 'Add nodev Option to /dev/shm: Ensure /dev/shm is mounted with nodev option'
    ansible.posix.mount:
      path: /dev/shm
      src: '{{ mount_info.source | default('''') }}'
      opts: '{{ mount_info.options | default('''') }}'
      state: mounted
      fstype: '{{ mount_info.fstype | default('''') }}'
    register: mount_result
    failed_when:
    - mount_result is failed
    - '''target is busy'' not in (mount_result.msg | default(''''))'
    - '''already mounted'' not in (mount_result.msg | default(''''))'
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - mount_info is defined
    - (device_name.stdout is defined and (device_name.stdout | length > 0)) or (""
      | length == 0)
    tags:
    - DISA-STIG-RHEL-08-040120
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_dev_shm_nodev
    - no_reboot_needed

  - name: 'Add noexec Option to /dev/shm: Check information associated to mountpoint'
    ansible.builtin.command: findmnt  '/dev/shm'
    register: device_name
    failed_when: device_name.rc > 1
    changed_when: false
    check_mode: false
    when: ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    tags:
    - DISA-STIG-RHEL-08-040122
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_dev_shm_noexec
    - no_reboot_needed

  - name: 'Add noexec Option to /dev/shm: Create mount_info dictionary variable'
    set_fact:
      mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
    with_together:
    - '{{ device_name.stdout_lines[0].split() | map(''lower'') | list }}'
    - '{{ device_name.stdout_lines[1].split() | list }}'
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - device_name.stdout is defined and device_name.stdout_lines is defined
    - (device_name.stdout | length > 0)
    tags:
    - DISA-STIG-RHEL-08-040122
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_dev_shm_noexec
    - no_reboot_needed

  - name: 'Add noexec Option to /dev/shm: If /dev/shm not mounted, craft mount_info
      manually'
    set_fact:
      mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
    with_together:
    - - target
      - source
      - fstype
      - options
    - - /dev/shm
      - tmpfs
      - tmpfs
      - defaults
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - ("" | length == 0)
    - device_name.stdout is defined and device_name.stdout_lines is defined
    - (device_name.stdout | length == 0)
    tags:
    - DISA-STIG-RHEL-08-040122
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_dev_shm_noexec
    - no_reboot_needed

  - name: 'Add noexec Option to /dev/shm: Make sure noexec option is part of the to
      /dev/shm options'
    set_fact:
      mount_info: '{{ mount_info | combine( {''options'':''''~(mount_info.options
        | default(''''))~('','' if (mount_info.options | default('''')) else '''')~''noexec''
        }) }}'
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - mount_info is defined and "noexec" not in (mount_info.options | default(''))
    tags:
    - DISA-STIG-RHEL-08-040122
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_dev_shm_noexec
    - no_reboot_needed

  - name: 'Add noexec Option to /dev/shm: Ensure /dev/shm is mounted with noexec option'
    ansible.posix.mount:
      path: /dev/shm
      src: '{{ mount_info.source | default('''') }}'
      opts: '{{ mount_info.options | default('''') }}'
      state: mounted
      fstype: '{{ mount_info.fstype | default('''') }}'
    register: mount_result
    failed_when:
    - mount_result is failed
    - '''target is busy'' not in (mount_result.msg | default(''''))'
    - '''already mounted'' not in (mount_result.msg | default(''''))'
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - mount_info is defined
    - (device_name.stdout is defined and (device_name.stdout | length > 0)) or (""
      | length == 0)
    tags:
    - DISA-STIG-RHEL-08-040122
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_dev_shm_noexec
    - no_reboot_needed

  - name: 'Add nosuid Option to /dev/shm: Check information associated to mountpoint'
    ansible.builtin.command: findmnt  '/dev/shm'
    register: device_name
    failed_when: device_name.rc > 1
    changed_when: false
    check_mode: false
    when: ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    tags:
    - DISA-STIG-RHEL-08-040121
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_dev_shm_nosuid
    - no_reboot_needed

  - name: 'Add nosuid Option to /dev/shm: Create mount_info dictionary variable'
    set_fact:
      mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
    with_together:
    - '{{ device_name.stdout_lines[0].split() | map(''lower'') | list }}'
    - '{{ device_name.stdout_lines[1].split() | list }}'
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - device_name.stdout is defined and device_name.stdout_lines is defined
    - (device_name.stdout | length > 0)
    tags:
    - DISA-STIG-RHEL-08-040121
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_dev_shm_nosuid
    - no_reboot_needed

  - name: 'Add nosuid Option to /dev/shm: If /dev/shm not mounted, craft mount_info
      manually'
    set_fact:
      mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
    with_together:
    - - target
      - source
      - fstype
      - options
    - - /dev/shm
      - tmpfs
      - tmpfs
      - defaults
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - ("" | length == 0)
    - device_name.stdout is defined and device_name.stdout_lines is defined
    - (device_name.stdout | length == 0)
    tags:
    - DISA-STIG-RHEL-08-040121
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_dev_shm_nosuid
    - no_reboot_needed

  - name: 'Add nosuid Option to /dev/shm: Make sure nosuid option is part of the to
      /dev/shm options'
    set_fact:
      mount_info: '{{ mount_info | combine( {''options'':''''~(mount_info.options
        | default(''''))~('','' if (mount_info.options | default('''')) else '''')~''nosuid''
        }) }}'
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - mount_info is defined and "nosuid" not in (mount_info.options | default(''))
    tags:
    - DISA-STIG-RHEL-08-040121
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_dev_shm_nosuid
    - no_reboot_needed

  - name: 'Add nosuid Option to /dev/shm: Ensure /dev/shm is mounted with nosuid option'
    ansible.posix.mount:
      path: /dev/shm
      src: '{{ mount_info.source | default('''') }}'
      opts: '{{ mount_info.options | default('''') }}'
      state: mounted
      fstype: '{{ mount_info.fstype | default('''') }}'
    register: mount_result
    failed_when:
    - mount_result is failed
    - '''target is busy'' not in (mount_result.msg | default(''''))'
    - '''already mounted'' not in (mount_result.msg | default(''''))'
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - mount_info is defined
    - (device_name.stdout is defined and (device_name.stdout | length > 0)) or (""
      | length == 0)
    tags:
    - DISA-STIG-RHEL-08-040121
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_dev_shm_nosuid
    - no_reboot_needed

  - name: 'Add nodev Option to /home: Check information associated to mountpoint'
    ansible.builtin.command: findmnt --fstab '/home'
    register: device_name
    failed_when: device_name.rc > 1
    changed_when: false
    check_mode: false
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/home" in ansible_mounts | map(attribute="mount") | list'
    tags:
    - configure_strategy
    - high_disruption
    - low_complexity
    - mount_option_home_nodev
    - no_reboot_needed
    - unknown_severity

  - name: 'Add nodev Option to /home: Create mount_info dictionary variable'
    set_fact:
      mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
    with_together:
    - '{{ device_name.stdout_lines[0].split() | map(''lower'') | list }}'
    - '{{ device_name.stdout_lines[1].split() | list }}'
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/home" in ansible_mounts | map(attribute="mount") | list'
    - device_name.stdout is defined and device_name.stdout_lines is defined
    - (device_name.stdout | length > 0)
    tags:
    - configure_strategy
    - high_disruption
    - low_complexity
    - mount_option_home_nodev
    - no_reboot_needed
    - unknown_severity

  - name: 'Add nodev Option to /home: If /home not mounted, craft mount_info manually'
    set_fact:
      mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
    with_together:
    - - target
      - source
      - fstype
      - options
    - - /home
      - ''
      - ''
      - defaults
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/home" in ansible_mounts | map(attribute="mount") | list'
    - ("--fstab" | length == 0)
    - device_name.stdout is defined and device_name.stdout_lines is defined
    - (device_name.stdout | length == 0)
    tags:
    - configure_strategy
    - high_disruption
    - low_complexity
    - mount_option_home_nodev
    - no_reboot_needed
    - unknown_severity

  - name: 'Add nodev Option to /home: Make sure nodev option is part of the to /home
      options'
    set_fact:
      mount_info: '{{ mount_info | combine( {''options'':''''~(mount_info.options
        | default(''''))~('','' if (mount_info.options | default('''')) else '''')~''nodev''
        }) }}'
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/home" in ansible_mounts | map(attribute="mount") | list'
    - mount_info is defined and "nodev" not in (mount_info.options | default(''))
    tags:
    - configure_strategy
    - high_disruption
    - low_complexity
    - mount_option_home_nodev
    - no_reboot_needed
    - unknown_severity

  - name: 'Add nodev Option to /home: Ensure /home is mounted with nodev option'
    ansible.posix.mount:
      path: /home
      src: '{{ mount_info.source | default('''') }}'
      opts: '{{ mount_info.options | default('''') }}'
      state: mounted
      fstype: '{{ mount_info.fstype | default('''') }}'
    register: mount_result
    failed_when:
    - mount_result is failed
    - '''target is busy'' not in (mount_result.msg | default(''''))'
    - '''already mounted'' not in (mount_result.msg | default(''''))'
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/home" in ansible_mounts | map(attribute="mount") | list'
    - mount_info is defined
    - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab"
      | length == 0)
    tags:
    - configure_strategy
    - high_disruption
    - low_complexity
    - mount_option_home_nodev
    - no_reboot_needed
    - unknown_severity

  - name: 'Add nosuid Option to /home: Check information associated to mountpoint'
    ansible.builtin.command: findmnt --fstab '/home'
    register: device_name
    failed_when: device_name.rc > 1
    changed_when: false
    check_mode: false
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/home" in ansible_mounts | map(attribute="mount") | list'
    tags:
    - DISA-STIG-RHEL-08-010570
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_home_nosuid
    - no_reboot_needed

  - name: 'Add nosuid Option to /home: Create mount_info dictionary variable'
    set_fact:
      mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
    with_together:
    - '{{ device_name.stdout_lines[0].split() | map(''lower'') | list }}'
    - '{{ device_name.stdout_lines[1].split() | list }}'
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/home" in ansible_mounts | map(attribute="mount") | list'
    - device_name.stdout is defined and device_name.stdout_lines is defined
    - (device_name.stdout | length > 0)
    tags:
    - DISA-STIG-RHEL-08-010570
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_home_nosuid
    - no_reboot_needed

  - name: 'Add nosuid Option to /home: If /home not mounted, craft mount_info manually'
    set_fact:
      mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
    with_together:
    - - target
      - source
      - fstype
      - options
    - - /home
      - ''
      - ''
      - defaults
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/home" in ansible_mounts | map(attribute="mount") | list'
    - ("--fstab" | length == 0)
    - device_name.stdout is defined and device_name.stdout_lines is defined
    - (device_name.stdout | length == 0)
    tags:
    - DISA-STIG-RHEL-08-010570
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_home_nosuid
    - no_reboot_needed

  - name: 'Add nosuid Option to /home: Make sure nosuid option is part of the to /home
      options'
    set_fact:
      mount_info: '{{ mount_info | combine( {''options'':''''~(mount_info.options
        | default(''''))~('','' if (mount_info.options | default('''')) else '''')~''nosuid''
        }) }}'
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/home" in ansible_mounts | map(attribute="mount") | list'
    - mount_info is defined and "nosuid" not in (mount_info.options | default(''))
    tags:
    - DISA-STIG-RHEL-08-010570
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_home_nosuid
    - no_reboot_needed

  - name: 'Add nosuid Option to /home: Ensure /home is mounted with nosuid option'
    ansible.posix.mount:
      path: /home
      src: '{{ mount_info.source | default('''') }}'
      opts: '{{ mount_info.options | default('''') }}'
      state: mounted
      fstype: '{{ mount_info.fstype | default('''') }}'
    register: mount_result
    failed_when:
    - mount_result is failed
    - '''target is busy'' not in (mount_result.msg | default(''''))'
    - '''already mounted'' not in (mount_result.msg | default(''''))'
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/home" in ansible_mounts | map(attribute="mount") | list'
    - mount_info is defined
    - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab"
      | length == 0)
    tags:
    - DISA-STIG-RHEL-08-010570
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_home_nosuid
    - no_reboot_needed

  - name: 'Add nodev Option to /tmp: Check information associated to mountpoint'
    ansible.builtin.command: findmnt --fstab '/tmp'
    register: device_name
    failed_when: device_name.rc > 1
    changed_when: false
    check_mode: false
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/tmp" in ansible_mounts | map(attribute="mount") | list'
    tags:
    - DISA-STIG-RHEL-08-040123
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_tmp_nodev
    - no_reboot_needed

  - name: 'Add nodev Option to /tmp: Create mount_info dictionary variable'
    set_fact:
      mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
    with_together:
    - '{{ device_name.stdout_lines[0].split() | map(''lower'') | list }}'
    - '{{ device_name.stdout_lines[1].split() | list }}'
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/tmp" in ansible_mounts | map(attribute="mount") | list'
    - device_name.stdout is defined and device_name.stdout_lines is defined
    - (device_name.stdout | length > 0)
    tags:
    - DISA-STIG-RHEL-08-040123
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_tmp_nodev
    - no_reboot_needed

  - name: 'Add nodev Option to /tmp: If /tmp not mounted, craft mount_info manually'
    set_fact:
      mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
    with_together:
    - - target
      - source
      - fstype
      - options
    - - /tmp
      - ''
      - ''
      - defaults
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/tmp" in ansible_mounts | map(attribute="mount") | list'
    - ("--fstab" | length == 0)
    - device_name.stdout is defined and device_name.stdout_lines is defined
    - (device_name.stdout | length == 0)
    tags:
    - DISA-STIG-RHEL-08-040123
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_tmp_nodev
    - no_reboot_needed

  - name: 'Add nodev Option to /tmp: Make sure nodev option is part of the to /tmp
      options'
    set_fact:
      mount_info: '{{ mount_info | combine( {''options'':''''~(mount_info.options
        | default(''''))~('','' if (mount_info.options | default('''')) else '''')~''nodev''
        }) }}'
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/tmp" in ansible_mounts | map(attribute="mount") | list'
    - mount_info is defined and "nodev" not in (mount_info.options | default(''))
    tags:
    - DISA-STIG-RHEL-08-040123
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_tmp_nodev
    - no_reboot_needed

  - name: 'Add nodev Option to /tmp: Ensure /tmp is mounted with nodev option'
    ansible.posix.mount:
      path: /tmp
      src: '{{ mount_info.source | default('''') }}'
      opts: '{{ mount_info.options | default('''') }}'
      state: mounted
      fstype: '{{ mount_info.fstype | default('''') }}'
    register: mount_result
    failed_when:
    - mount_result is failed
    - '''target is busy'' not in (mount_result.msg | default(''''))'
    - '''already mounted'' not in (mount_result.msg | default(''''))'
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/tmp" in ansible_mounts | map(attribute="mount") | list'
    - mount_info is defined
    - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab"
      | length == 0)
    tags:
    - DISA-STIG-RHEL-08-040123
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_tmp_nodev
    - no_reboot_needed

  - name: 'Add noexec Option to /tmp: Check information associated to mountpoint'
    ansible.builtin.command: findmnt --fstab '/tmp'
    register: device_name
    failed_when: device_name.rc > 1
    changed_when: false
    check_mode: false
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/tmp" in ansible_mounts | map(attribute="mount") | list'
    tags:
    - DISA-STIG-RHEL-08-040125
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_tmp_noexec
    - no_reboot_needed

  - name: 'Add noexec Option to /tmp: Create mount_info dictionary variable'
    set_fact:
      mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
    with_together:
    - '{{ device_name.stdout_lines[0].split() | map(''lower'') | list }}'
    - '{{ device_name.stdout_lines[1].split() | list }}'
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/tmp" in ansible_mounts | map(attribute="mount") | list'
    - device_name.stdout is defined and device_name.stdout_lines is defined
    - (device_name.stdout | length > 0)
    tags:
    - DISA-STIG-RHEL-08-040125
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_tmp_noexec
    - no_reboot_needed

  - name: 'Add noexec Option to /tmp: If /tmp not mounted, craft mount_info manually'
    set_fact:
      mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
    with_together:
    - - target
      - source
      - fstype
      - options
    - - /tmp
      - ''
      - ''
      - defaults
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/tmp" in ansible_mounts | map(attribute="mount") | list'
    - ("--fstab" | length == 0)
    - device_name.stdout is defined and device_name.stdout_lines is defined
    - (device_name.stdout | length == 0)
    tags:
    - DISA-STIG-RHEL-08-040125
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_tmp_noexec
    - no_reboot_needed

  - name: 'Add noexec Option to /tmp: Make sure noexec option is part of the to /tmp
      options'
    set_fact:
      mount_info: '{{ mount_info | combine( {''options'':''''~(mount_info.options
        | default(''''))~('','' if (mount_info.options | default('''')) else '''')~''noexec''
        }) }}'
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/tmp" in ansible_mounts | map(attribute="mount") | list'
    - mount_info is defined and "noexec" not in (mount_info.options | default(''))
    tags:
    - DISA-STIG-RHEL-08-040125
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_tmp_noexec
    - no_reboot_needed

  - name: 'Add noexec Option to /tmp: Ensure /tmp is mounted with noexec option'
    ansible.posix.mount:
      path: /tmp
      src: '{{ mount_info.source | default('''') }}'
      opts: '{{ mount_info.options | default('''') }}'
      state: mounted
      fstype: '{{ mount_info.fstype | default('''') }}'
    register: mount_result
    failed_when:
    - mount_result is failed
    - '''target is busy'' not in (mount_result.msg | default(''''))'
    - '''already mounted'' not in (mount_result.msg | default(''''))'
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/tmp" in ansible_mounts | map(attribute="mount") | list'
    - mount_info is defined
    - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab"
      | length == 0)
    tags:
    - DISA-STIG-RHEL-08-040125
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_tmp_noexec
    - no_reboot_needed

  - name: 'Add nosuid Option to /tmp: Check information associated to mountpoint'
    ansible.builtin.command: findmnt --fstab '/tmp'
    register: device_name
    failed_when: device_name.rc > 1
    changed_when: false
    check_mode: false
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/tmp" in ansible_mounts | map(attribute="mount") | list'
    tags:
    - DISA-STIG-RHEL-08-040124
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_tmp_nosuid
    - no_reboot_needed

  - name: 'Add nosuid Option to /tmp: Create mount_info dictionary variable'
    set_fact:
      mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
    with_together:
    - '{{ device_name.stdout_lines[0].split() | map(''lower'') | list }}'
    - '{{ device_name.stdout_lines[1].split() | list }}'
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/tmp" in ansible_mounts | map(attribute="mount") | list'
    - device_name.stdout is defined and device_name.stdout_lines is defined
    - (device_name.stdout | length > 0)
    tags:
    - DISA-STIG-RHEL-08-040124
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_tmp_nosuid
    - no_reboot_needed

  - name: 'Add nosuid Option to /tmp: If /tmp not mounted, craft mount_info manually'
    set_fact:
      mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
    with_together:
    - - target
      - source
      - fstype
      - options
    - - /tmp
      - ''
      - ''
      - defaults
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/tmp" in ansible_mounts | map(attribute="mount") | list'
    - ("--fstab" | length == 0)
    - device_name.stdout is defined and device_name.stdout_lines is defined
    - (device_name.stdout | length == 0)
    tags:
    - DISA-STIG-RHEL-08-040124
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_tmp_nosuid
    - no_reboot_needed

  - name: 'Add nosuid Option to /tmp: Make sure nosuid option is part of the to /tmp
      options'
    set_fact:
      mount_info: '{{ mount_info | combine( {''options'':''''~(mount_info.options
        | default(''''))~('','' if (mount_info.options | default('''')) else '''')~''nosuid''
        }) }}'
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/tmp" in ansible_mounts | map(attribute="mount") | list'
    - mount_info is defined and "nosuid" not in (mount_info.options | default(''))
    tags:
    - DISA-STIG-RHEL-08-040124
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_tmp_nosuid
    - no_reboot_needed

  - name: 'Add nosuid Option to /tmp: Ensure /tmp is mounted with nosuid option'
    ansible.posix.mount:
      path: /tmp
      src: '{{ mount_info.source | default('''') }}'
      opts: '{{ mount_info.options | default('''') }}'
      state: mounted
      fstype: '{{ mount_info.fstype | default('''') }}'
    register: mount_result
    failed_when:
    - mount_result is failed
    - '''target is busy'' not in (mount_result.msg | default(''''))'
    - '''already mounted'' not in (mount_result.msg | default(''''))'
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/tmp" in ansible_mounts | map(attribute="mount") | list'
    - mount_info is defined
    - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab"
      | length == 0)
    tags:
    - DISA-STIG-RHEL-08-040124
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_tmp_nosuid
    - no_reboot_needed

  - name: 'Add nodev Option to /var/log/audit: Check information associated to mountpoint'
    ansible.builtin.command: findmnt --fstab '/var/log/audit'
    register: device_name
    failed_when: device_name.rc > 1
    changed_when: false
    check_mode: false
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/var/log/audit" in ansible_mounts | map(attribute="mount") | list'
    tags:
    - DISA-STIG-RHEL-08-040129
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_var_log_audit_nodev
    - no_reboot_needed

  - name: 'Add nodev Option to /var/log/audit: Create mount_info dictionary variable'
    set_fact:
      mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
    with_together:
    - '{{ device_name.stdout_lines[0].split() | map(''lower'') | list }}'
    - '{{ device_name.stdout_lines[1].split() | list }}'
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/var/log/audit" in ansible_mounts | map(attribute="mount") | list'
    - device_name.stdout is defined and device_name.stdout_lines is defined
    - (device_name.stdout | length > 0)
    tags:
    - DISA-STIG-RHEL-08-040129
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_var_log_audit_nodev
    - no_reboot_needed

  - name: 'Add nodev Option to /var/log/audit: If /var/log/audit not mounted, craft
      mount_info manually'
    set_fact:
      mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
    with_together:
    - - target
      - source
      - fstype
      - options
    - - /var/log/audit
      - ''
      - ''
      - defaults
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/var/log/audit" in ansible_mounts | map(attribute="mount") | list'
    - ("--fstab" | length == 0)
    - device_name.stdout is defined and device_name.stdout_lines is defined
    - (device_name.stdout | length == 0)
    tags:
    - DISA-STIG-RHEL-08-040129
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_var_log_audit_nodev
    - no_reboot_needed

  - name: 'Add nodev Option to /var/log/audit: Make sure nodev option is part of the
      to /var/log/audit options'
    set_fact:
      mount_info: '{{ mount_info | combine( {''options'':''''~(mount_info.options
        | default(''''))~('','' if (mount_info.options | default('''')) else '''')~''nodev''
        }) }}'
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/var/log/audit" in ansible_mounts | map(attribute="mount") | list'
    - mount_info is defined and "nodev" not in (mount_info.options | default(''))
    tags:
    - DISA-STIG-RHEL-08-040129
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_var_log_audit_nodev
    - no_reboot_needed

  - name: 'Add nodev Option to /var/log/audit: Ensure /var/log/audit is mounted with
      nodev option'
    ansible.posix.mount:
      path: /var/log/audit
      src: '{{ mount_info.source | default('''') }}'
      opts: '{{ mount_info.options | default('''') }}'
      state: mounted
      fstype: '{{ mount_info.fstype | default('''') }}'
    register: mount_result
    failed_when:
    - mount_result is failed
    - '''target is busy'' not in (mount_result.msg | default(''''))'
    - '''already mounted'' not in (mount_result.msg | default(''''))'
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/var/log/audit" in ansible_mounts | map(attribute="mount") | list'
    - mount_info is defined
    - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab"
      | length == 0)
    tags:
    - DISA-STIG-RHEL-08-040129
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_var_log_audit_nodev
    - no_reboot_needed

  - name: 'Add noexec Option to /var/log/audit: Check information associated to mountpoint'
    ansible.builtin.command: findmnt --fstab '/var/log/audit'
    register: device_name
    failed_when: device_name.rc > 1
    changed_when: false
    check_mode: false
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/var/log/audit" in ansible_mounts | map(attribute="mount") | list'
    tags:
    - DISA-STIG-RHEL-08-040131
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_var_log_audit_noexec
    - no_reboot_needed

  - name: 'Add noexec Option to /var/log/audit: Create mount_info dictionary variable'
    set_fact:
      mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
    with_together:
    - '{{ device_name.stdout_lines[0].split() | map(''lower'') | list }}'
    - '{{ device_name.stdout_lines[1].split() | list }}'
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/var/log/audit" in ansible_mounts | map(attribute="mount") | list'
    - device_name.stdout is defined and device_name.stdout_lines is defined
    - (device_name.stdout | length > 0)
    tags:
    - DISA-STIG-RHEL-08-040131
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_var_log_audit_noexec
    - no_reboot_needed

  - name: 'Add noexec Option to /var/log/audit: If /var/log/audit not mounted, craft
      mount_info manually'
    set_fact:
      mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
    with_together:
    - - target
      - source
      - fstype
      - options
    - - /var/log/audit
      - ''
      - ''
      - defaults
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/var/log/audit" in ansible_mounts | map(attribute="mount") | list'
    - ("--fstab" | length == 0)
    - device_name.stdout is defined and device_name.stdout_lines is defined
    - (device_name.stdout | length == 0)
    tags:
    - DISA-STIG-RHEL-08-040131
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_var_log_audit_noexec
    - no_reboot_needed

  - name: 'Add noexec Option to /var/log/audit: Make sure noexec option is part of
      the to /var/log/audit options'
    set_fact:
      mount_info: '{{ mount_info | combine( {''options'':''''~(mount_info.options
        | default(''''))~('','' if (mount_info.options | default('''')) else '''')~''noexec''
        }) }}'
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/var/log/audit" in ansible_mounts | map(attribute="mount") | list'
    - mount_info is defined and "noexec" not in (mount_info.options | default(''))
    tags:
    - DISA-STIG-RHEL-08-040131
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_var_log_audit_noexec
    - no_reboot_needed

  - name: 'Add noexec Option to /var/log/audit: Ensure /var/log/audit is mounted with
      noexec option'
    ansible.posix.mount:
      path: /var/log/audit
      src: '{{ mount_info.source | default('''') }}'
      opts: '{{ mount_info.options | default('''') }}'
      state: mounted
      fstype: '{{ mount_info.fstype | default('''') }}'
    register: mount_result
    failed_when:
    - mount_result is failed
    - '''target is busy'' not in (mount_result.msg | default(''''))'
    - '''already mounted'' not in (mount_result.msg | default(''''))'
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/var/log/audit" in ansible_mounts | map(attribute="mount") | list'
    - mount_info is defined
    - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab"
      | length == 0)
    tags:
    - DISA-STIG-RHEL-08-040131
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_var_log_audit_noexec
    - no_reboot_needed

  - name: 'Add nosuid Option to /var/log/audit: Check information associated to mountpoint'
    ansible.builtin.command: findmnt --fstab '/var/log/audit'
    register: device_name
    failed_when: device_name.rc > 1
    changed_when: false
    check_mode: false
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/var/log/audit" in ansible_mounts | map(attribute="mount") | list'
    tags:
    - DISA-STIG-RHEL-08-040130
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_var_log_audit_nosuid
    - no_reboot_needed

  - name: 'Add nosuid Option to /var/log/audit: Create mount_info dictionary variable'
    set_fact:
      mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
    with_together:
    - '{{ device_name.stdout_lines[0].split() | map(''lower'') | list }}'
    - '{{ device_name.stdout_lines[1].split() | list }}'
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/var/log/audit" in ansible_mounts | map(attribute="mount") | list'
    - device_name.stdout is defined and device_name.stdout_lines is defined
    - (device_name.stdout | length > 0)
    tags:
    - DISA-STIG-RHEL-08-040130
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_var_log_audit_nosuid
    - no_reboot_needed

  - name: 'Add nosuid Option to /var/log/audit: If /var/log/audit not mounted, craft
      mount_info manually'
    set_fact:
      mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
    with_together:
    - - target
      - source
      - fstype
      - options
    - - /var/log/audit
      - ''
      - ''
      - defaults
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/var/log/audit" in ansible_mounts | map(attribute="mount") | list'
    - ("--fstab" | length == 0)
    - device_name.stdout is defined and device_name.stdout_lines is defined
    - (device_name.stdout | length == 0)
    tags:
    - DISA-STIG-RHEL-08-040130
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_var_log_audit_nosuid
    - no_reboot_needed

  - name: 'Add nosuid Option to /var/log/audit: Make sure nosuid option is part of
      the to /var/log/audit options'
    set_fact:
      mount_info: '{{ mount_info | combine( {''options'':''''~(mount_info.options
        | default(''''))~('','' if (mount_info.options | default('''')) else '''')~''nosuid''
        }) }}'
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/var/log/audit" in ansible_mounts | map(attribute="mount") | list'
    - mount_info is defined and "nosuid" not in (mount_info.options | default(''))
    tags:
    - DISA-STIG-RHEL-08-040130
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_var_log_audit_nosuid
    - no_reboot_needed

  - name: 'Add nosuid Option to /var/log/audit: Ensure /var/log/audit is mounted with
      nosuid option'
    ansible.posix.mount:
      path: /var/log/audit
      src: '{{ mount_info.source | default('''') }}'
      opts: '{{ mount_info.options | default('''') }}'
      state: mounted
      fstype: '{{ mount_info.fstype | default('''') }}'
    register: mount_result
    failed_when:
    - mount_result is failed
    - '''target is busy'' not in (mount_result.msg | default(''''))'
    - '''already mounted'' not in (mount_result.msg | default(''''))'
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/var/log/audit" in ansible_mounts | map(attribute="mount") | list'
    - mount_info is defined
    - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab"
      | length == 0)
    tags:
    - DISA-STIG-RHEL-08-040130
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_var_log_audit_nosuid
    - no_reboot_needed

  - name: 'Add nodev Option to /var/log: Check information associated to mountpoint'
    ansible.builtin.command: findmnt --fstab '/var/log'
    register: device_name
    failed_when: device_name.rc > 1
    changed_when: false
    check_mode: false
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/var/log" in ansible_mounts | map(attribute="mount") | list'
    tags:
    - DISA-STIG-RHEL-08-040126
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_var_log_nodev
    - no_reboot_needed

  - name: 'Add nodev Option to /var/log: Create mount_info dictionary variable'
    set_fact:
      mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
    with_together:
    - '{{ device_name.stdout_lines[0].split() | map(''lower'') | list }}'
    - '{{ device_name.stdout_lines[1].split() | list }}'
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/var/log" in ansible_mounts | map(attribute="mount") | list'
    - device_name.stdout is defined and device_name.stdout_lines is defined
    - (device_name.stdout | length > 0)
    tags:
    - DISA-STIG-RHEL-08-040126
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_var_log_nodev
    - no_reboot_needed

  - name: 'Add nodev Option to /var/log: If /var/log not mounted, craft mount_info
      manually'
    set_fact:
      mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
    with_together:
    - - target
      - source
      - fstype
      - options
    - - /var/log
      - ''
      - ''
      - defaults
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/var/log" in ansible_mounts | map(attribute="mount") | list'
    - ("--fstab" | length == 0)
    - device_name.stdout is defined and device_name.stdout_lines is defined
    - (device_name.stdout | length == 0)
    tags:
    - DISA-STIG-RHEL-08-040126
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_var_log_nodev
    - no_reboot_needed

  - name: 'Add nodev Option to /var/log: Make sure nodev option is part of the to
      /var/log options'
    set_fact:
      mount_info: '{{ mount_info | combine( {''options'':''''~(mount_info.options
        | default(''''))~('','' if (mount_info.options | default('''')) else '''')~''nodev''
        }) }}'
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/var/log" in ansible_mounts | map(attribute="mount") | list'
    - mount_info is defined and "nodev" not in (mount_info.options | default(''))
    tags:
    - DISA-STIG-RHEL-08-040126
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_var_log_nodev
    - no_reboot_needed

  - name: 'Add nodev Option to /var/log: Ensure /var/log is mounted with nodev option'
    ansible.posix.mount:
      path: /var/log
      src: '{{ mount_info.source | default('''') }}'
      opts: '{{ mount_info.options | default('''') }}'
      state: mounted
      fstype: '{{ mount_info.fstype | default('''') }}'
    register: mount_result
    failed_when:
    - mount_result is failed
    - '''target is busy'' not in (mount_result.msg | default(''''))'
    - '''already mounted'' not in (mount_result.msg | default(''''))'
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/var/log" in ansible_mounts | map(attribute="mount") | list'
    - mount_info is defined
    - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab"
      | length == 0)
    tags:
    - DISA-STIG-RHEL-08-040126
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_var_log_nodev
    - no_reboot_needed

  - name: 'Add noexec Option to /var/log: Check information associated to mountpoint'
    ansible.builtin.command: findmnt --fstab '/var/log'
    register: device_name
    failed_when: device_name.rc > 1
    changed_when: false
    check_mode: false
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/var/log" in ansible_mounts | map(attribute="mount") | list'
    tags:
    - DISA-STIG-RHEL-08-040128
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_var_log_noexec
    - no_reboot_needed

  - name: 'Add noexec Option to /var/log: Create mount_info dictionary variable'
    set_fact:
      mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
    with_together:
    - '{{ device_name.stdout_lines[0].split() | map(''lower'') | list }}'
    - '{{ device_name.stdout_lines[1].split() | list }}'
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/var/log" in ansible_mounts | map(attribute="mount") | list'
    - device_name.stdout is defined and device_name.stdout_lines is defined
    - (device_name.stdout | length > 0)
    tags:
    - DISA-STIG-RHEL-08-040128
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_var_log_noexec
    - no_reboot_needed

  - name: 'Add noexec Option to /var/log: If /var/log not mounted, craft mount_info
      manually'
    set_fact:
      mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
    with_together:
    - - target
      - source
      - fstype
      - options
    - - /var/log
      - ''
      - ''
      - defaults
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/var/log" in ansible_mounts | map(attribute="mount") | list'
    - ("--fstab" | length == 0)
    - device_name.stdout is defined and device_name.stdout_lines is defined
    - (device_name.stdout | length == 0)
    tags:
    - DISA-STIG-RHEL-08-040128
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_var_log_noexec
    - no_reboot_needed

  - name: 'Add noexec Option to /var/log: Make sure noexec option is part of the to
      /var/log options'
    set_fact:
      mount_info: '{{ mount_info | combine( {''options'':''''~(mount_info.options
        | default(''''))~('','' if (mount_info.options | default('''')) else '''')~''noexec''
        }) }}'
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/var/log" in ansible_mounts | map(attribute="mount") | list'
    - mount_info is defined and "noexec" not in (mount_info.options | default(''))
    tags:
    - DISA-STIG-RHEL-08-040128
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_var_log_noexec
    - no_reboot_needed

  - name: 'Add noexec Option to /var/log: Ensure /var/log is mounted with noexec option'
    ansible.posix.mount:
      path: /var/log
      src: '{{ mount_info.source | default('''') }}'
      opts: '{{ mount_info.options | default('''') }}'
      state: mounted
      fstype: '{{ mount_info.fstype | default('''') }}'
    register: mount_result
    failed_when:
    - mount_result is failed
    - '''target is busy'' not in (mount_result.msg | default(''''))'
    - '''already mounted'' not in (mount_result.msg | default(''''))'
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/var/log" in ansible_mounts | map(attribute="mount") | list'
    - mount_info is defined
    - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab"
      | length == 0)
    tags:
    - DISA-STIG-RHEL-08-040128
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_var_log_noexec
    - no_reboot_needed

  - name: 'Add nosuid Option to /var/log: Check information associated to mountpoint'
    ansible.builtin.command: findmnt --fstab '/var/log'
    register: device_name
    failed_when: device_name.rc > 1
    changed_when: false
    check_mode: false
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/var/log" in ansible_mounts | map(attribute="mount") | list'
    tags:
    - DISA-STIG-RHEL-08-040127
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_var_log_nosuid
    - no_reboot_needed

  - name: 'Add nosuid Option to /var/log: Create mount_info dictionary variable'
    set_fact:
      mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
    with_together:
    - '{{ device_name.stdout_lines[0].split() | map(''lower'') | list }}'
    - '{{ device_name.stdout_lines[1].split() | list }}'
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/var/log" in ansible_mounts | map(attribute="mount") | list'
    - device_name.stdout is defined and device_name.stdout_lines is defined
    - (device_name.stdout | length > 0)
    tags:
    - DISA-STIG-RHEL-08-040127
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_var_log_nosuid
    - no_reboot_needed

  - name: 'Add nosuid Option to /var/log: If /var/log not mounted, craft mount_info
      manually'
    set_fact:
      mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
    with_together:
    - - target
      - source
      - fstype
      - options
    - - /var/log
      - ''
      - ''
      - defaults
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/var/log" in ansible_mounts | map(attribute="mount") | list'
    - ("--fstab" | length == 0)
    - device_name.stdout is defined and device_name.stdout_lines is defined
    - (device_name.stdout | length == 0)
    tags:
    - DISA-STIG-RHEL-08-040127
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_var_log_nosuid
    - no_reboot_needed

  - name: 'Add nosuid Option to /var/log: Make sure nosuid option is part of the to
      /var/log options'
    set_fact:
      mount_info: '{{ mount_info | combine( {''options'':''''~(mount_info.options
        | default(''''))~('','' if (mount_info.options | default('''')) else '''')~''nosuid''
        }) }}'
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/var/log" in ansible_mounts | map(attribute="mount") | list'
    - mount_info is defined and "nosuid" not in (mount_info.options | default(''))
    tags:
    - DISA-STIG-RHEL-08-040127
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_var_log_nosuid
    - no_reboot_needed

  - name: 'Add nosuid Option to /var/log: Ensure /var/log is mounted with nosuid option'
    ansible.posix.mount:
      path: /var/log
      src: '{{ mount_info.source | default('''') }}'
      opts: '{{ mount_info.options | default('''') }}'
      state: mounted
      fstype: '{{ mount_info.fstype | default('''') }}'
    register: mount_result
    failed_when:
    - mount_result is failed
    - '''target is busy'' not in (mount_result.msg | default(''''))'
    - '''already mounted'' not in (mount_result.msg | default(''''))'
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/var/log" in ansible_mounts | map(attribute="mount") | list'
    - mount_info is defined
    - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab"
      | length == 0)
    tags:
    - DISA-STIG-RHEL-08-040127
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_var_log_nosuid
    - no_reboot_needed

  - name: 'Add nodev Option to /var: Check information associated to mountpoint'
    ansible.builtin.command: findmnt --fstab '/var'
    register: device_name
    failed_when: device_name.rc > 1
    changed_when: false
    check_mode: false
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/var" in ansible_mounts | map(attribute="mount") | list'
    tags:
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_var_nodev
    - no_reboot_needed

  - name: 'Add nodev Option to /var: Create mount_info dictionary variable'
    set_fact:
      mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
    with_together:
    - '{{ device_name.stdout_lines[0].split() | map(''lower'') | list }}'
    - '{{ device_name.stdout_lines[1].split() | list }}'
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/var" in ansible_mounts | map(attribute="mount") | list'
    - device_name.stdout is defined and device_name.stdout_lines is defined
    - (device_name.stdout | length > 0)
    tags:
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_var_nodev
    - no_reboot_needed

  - name: 'Add nodev Option to /var: If /var not mounted, craft mount_info manually'
    set_fact:
      mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
    with_together:
    - - target
      - source
      - fstype
      - options
    - - /var
      - ''
      - ''
      - defaults
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/var" in ansible_mounts | map(attribute="mount") | list'
    - ("--fstab" | length == 0)
    - device_name.stdout is defined and device_name.stdout_lines is defined
    - (device_name.stdout | length == 0)
    tags:
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_var_nodev
    - no_reboot_needed

  - name: 'Add nodev Option to /var: Make sure nodev option is part of the to /var
      options'
    set_fact:
      mount_info: '{{ mount_info | combine( {''options'':''''~(mount_info.options
        | default(''''))~('','' if (mount_info.options | default('''')) else '''')~''nodev''
        }) }}'
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/var" in ansible_mounts | map(attribute="mount") | list'
    - mount_info is defined and "nodev" not in (mount_info.options | default(''))
    tags:
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_var_nodev
    - no_reboot_needed

  - name: 'Add nodev Option to /var: Ensure /var is mounted with nodev option'
    ansible.posix.mount:
      path: /var
      src: '{{ mount_info.source | default('''') }}'
      opts: '{{ mount_info.options | default('''') }}'
      state: mounted
      fstype: '{{ mount_info.fstype | default('''') }}'
    register: mount_result
    failed_when:
    - mount_result is failed
    - '''target is busy'' not in (mount_result.msg | default(''''))'
    - '''already mounted'' not in (mount_result.msg | default(''''))'
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/var" in ansible_mounts | map(attribute="mount") | list'
    - mount_info is defined
    - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab"
      | length == 0)
    tags:
    - NIST-800-53-AC-6
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-MP-7
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_var_nodev
    - no_reboot_needed

  - name: 'Add nosuid Option to /var: Check information associated to mountpoint'
    ansible.builtin.command: findmnt --fstab '/var'
    register: device_name
    failed_when: device_name.rc > 1
    changed_when: false
    check_mode: false
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/var" in ansible_mounts | map(attribute="mount") | list'
    tags:
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_var_nosuid
    - no_reboot_needed

  - name: 'Add nosuid Option to /var: Create mount_info dictionary variable'
    set_fact:
      mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
    with_together:
    - '{{ device_name.stdout_lines[0].split() | map(''lower'') | list }}'
    - '{{ device_name.stdout_lines[1].split() | list }}'
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/var" in ansible_mounts | map(attribute="mount") | list'
    - device_name.stdout is defined and device_name.stdout_lines is defined
    - (device_name.stdout | length > 0)
    tags:
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_var_nosuid
    - no_reboot_needed

  - name: 'Add nosuid Option to /var: If /var not mounted, craft mount_info manually'
    set_fact:
      mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
    with_together:
    - - target
      - source
      - fstype
      - options
    - - /var
      - ''
      - ''
      - defaults
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/var" in ansible_mounts | map(attribute="mount") | list'
    - ("--fstab" | length == 0)
    - device_name.stdout is defined and device_name.stdout_lines is defined
    - (device_name.stdout | length == 0)
    tags:
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_var_nosuid
    - no_reboot_needed

  - name: 'Add nosuid Option to /var: Make sure nosuid option is part of the to /var
      options'
    set_fact:
      mount_info: '{{ mount_info | combine( {''options'':''''~(mount_info.options
        | default(''''))~('','' if (mount_info.options | default('''')) else '''')~''nosuid''
        }) }}'
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/var" in ansible_mounts | map(attribute="mount") | list'
    - mount_info is defined and "nosuid" not in (mount_info.options | default(''))
    tags:
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_var_nosuid
    - no_reboot_needed

  - name: 'Add nosuid Option to /var: Ensure /var is mounted with nosuid option'
    ansible.posix.mount:
      path: /var
      src: '{{ mount_info.source | default('''') }}'
      opts: '{{ mount_info.options | default('''') }}'
      state: mounted
      fstype: '{{ mount_info.fstype | default('''') }}'
    register: mount_result
    failed_when:
    - mount_result is failed
    - '''target is busy'' not in (mount_result.msg | default(''''))'
    - '''already mounted'' not in (mount_result.msg | default(''''))'
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/var" in ansible_mounts | map(attribute="mount") | list'
    - mount_info is defined
    - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab"
      | length == 0)
    tags:
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_var_nosuid
    - no_reboot_needed

  - name: 'Add nodev Option to /var/tmp: Check information associated to mountpoint'
    ansible.builtin.command: findmnt --fstab '/var/tmp'
    register: device_name
    failed_when: device_name.rc > 1
    changed_when: false
    check_mode: false
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/var/tmp" in ansible_mounts | map(attribute="mount") | list'
    tags:
    - DISA-STIG-RHEL-08-040132
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_var_tmp_nodev
    - no_reboot_needed

  - name: 'Add nodev Option to /var/tmp: Create mount_info dictionary variable'
    set_fact:
      mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
    with_together:
    - '{{ device_name.stdout_lines[0].split() | map(''lower'') | list }}'
    - '{{ device_name.stdout_lines[1].split() | list }}'
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/var/tmp" in ansible_mounts | map(attribute="mount") | list'
    - device_name.stdout is defined and device_name.stdout_lines is defined
    - (device_name.stdout | length > 0)
    tags:
    - DISA-STIG-RHEL-08-040132
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_var_tmp_nodev
    - no_reboot_needed

  - name: 'Add nodev Option to /var/tmp: If /var/tmp not mounted, craft mount_info
      manually'
    set_fact:
      mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
    with_together:
    - - target
      - source
      - fstype
      - options
    - - /var/tmp
      - ''
      - ''
      - defaults
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/var/tmp" in ansible_mounts | map(attribute="mount") | list'
    - ("--fstab" | length == 0)
    - device_name.stdout is defined and device_name.stdout_lines is defined
    - (device_name.stdout | length == 0)
    tags:
    - DISA-STIG-RHEL-08-040132
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_var_tmp_nodev
    - no_reboot_needed

  - name: 'Add nodev Option to /var/tmp: Make sure nodev option is part of the to
      /var/tmp options'
    set_fact:
      mount_info: '{{ mount_info | combine( {''options'':''''~(mount_info.options
        | default(''''))~('','' if (mount_info.options | default('''')) else '''')~''nodev''
        }) }}'
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/var/tmp" in ansible_mounts | map(attribute="mount") | list'
    - mount_info is defined and "nodev" not in (mount_info.options | default(''))
    tags:
    - DISA-STIG-RHEL-08-040132
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_var_tmp_nodev
    - no_reboot_needed

  - name: 'Add nodev Option to /var/tmp: Ensure /var/tmp is mounted with nodev option'
    ansible.posix.mount:
      path: /var/tmp
      src: '{{ mount_info.source | default('''') }}'
      opts: '{{ mount_info.options | default('''') }}'
      state: mounted
      fstype: '{{ mount_info.fstype | default('''') }}'
    register: mount_result
    failed_when:
    - mount_result is failed
    - '''target is busy'' not in (mount_result.msg | default(''''))'
    - '''already mounted'' not in (mount_result.msg | default(''''))'
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/var/tmp" in ansible_mounts | map(attribute="mount") | list'
    - mount_info is defined
    - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab"
      | length == 0)
    tags:
    - DISA-STIG-RHEL-08-040132
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_var_tmp_nodev
    - no_reboot_needed

  - name: 'Add noexec Option to /var/tmp: Check information associated to mountpoint'
    ansible.builtin.command: findmnt --fstab '/var/tmp'
    register: device_name
    failed_when: device_name.rc > 1
    changed_when: false
    check_mode: false
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/var/tmp" in ansible_mounts | map(attribute="mount") | list'
    tags:
    - DISA-STIG-RHEL-08-040134
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_var_tmp_noexec
    - no_reboot_needed

  - name: 'Add noexec Option to /var/tmp: Create mount_info dictionary variable'
    set_fact:
      mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
    with_together:
    - '{{ device_name.stdout_lines[0].split() | map(''lower'') | list }}'
    - '{{ device_name.stdout_lines[1].split() | list }}'
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/var/tmp" in ansible_mounts | map(attribute="mount") | list'
    - device_name.stdout is defined and device_name.stdout_lines is defined
    - (device_name.stdout | length > 0)
    tags:
    - DISA-STIG-RHEL-08-040134
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_var_tmp_noexec
    - no_reboot_needed

  - name: 'Add noexec Option to /var/tmp: If /var/tmp not mounted, craft mount_info
      manually'
    set_fact:
      mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
    with_together:
    - - target
      - source
      - fstype
      - options
    - - /var/tmp
      - ''
      - ''
      - defaults
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/var/tmp" in ansible_mounts | map(attribute="mount") | list'
    - ("--fstab" | length == 0)
    - device_name.stdout is defined and device_name.stdout_lines is defined
    - (device_name.stdout | length == 0)
    tags:
    - DISA-STIG-RHEL-08-040134
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_var_tmp_noexec
    - no_reboot_needed

  - name: 'Add noexec Option to /var/tmp: Make sure noexec option is part of the to
      /var/tmp options'
    set_fact:
      mount_info: '{{ mount_info | combine( {''options'':''''~(mount_info.options
        | default(''''))~('','' if (mount_info.options | default('''')) else '''')~''noexec''
        }) }}'
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/var/tmp" in ansible_mounts | map(attribute="mount") | list'
    - mount_info is defined and "noexec" not in (mount_info.options | default(''))
    tags:
    - DISA-STIG-RHEL-08-040134
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_var_tmp_noexec
    - no_reboot_needed

  - name: 'Add noexec Option to /var/tmp: Ensure /var/tmp is mounted with noexec option'
    ansible.posix.mount:
      path: /var/tmp
      src: '{{ mount_info.source | default('''') }}'
      opts: '{{ mount_info.options | default('''') }}'
      state: mounted
      fstype: '{{ mount_info.fstype | default('''') }}'
    register: mount_result
    failed_when:
    - mount_result is failed
    - '''target is busy'' not in (mount_result.msg | default(''''))'
    - '''already mounted'' not in (mount_result.msg | default(''''))'
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/var/tmp" in ansible_mounts | map(attribute="mount") | list'
    - mount_info is defined
    - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab"
      | length == 0)
    tags:
    - DISA-STIG-RHEL-08-040134
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_var_tmp_noexec
    - no_reboot_needed

  - name: 'Add nosuid Option to /var/tmp: Check information associated to mountpoint'
    ansible.builtin.command: findmnt --fstab '/var/tmp'
    register: device_name
    failed_when: device_name.rc > 1
    changed_when: false
    check_mode: false
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/var/tmp" in ansible_mounts | map(attribute="mount") | list'
    tags:
    - DISA-STIG-RHEL-08-040133
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_var_tmp_nosuid
    - no_reboot_needed

  - name: 'Add nosuid Option to /var/tmp: Create mount_info dictionary variable'
    set_fact:
      mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
    with_together:
    - '{{ device_name.stdout_lines[0].split() | map(''lower'') | list }}'
    - '{{ device_name.stdout_lines[1].split() | list }}'
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/var/tmp" in ansible_mounts | map(attribute="mount") | list'
    - device_name.stdout is defined and device_name.stdout_lines is defined
    - (device_name.stdout | length > 0)
    tags:
    - DISA-STIG-RHEL-08-040133
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_var_tmp_nosuid
    - no_reboot_needed

  - name: 'Add nosuid Option to /var/tmp: If /var/tmp not mounted, craft mount_info
      manually'
    set_fact:
      mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
    with_together:
    - - target
      - source
      - fstype
      - options
    - - /var/tmp
      - ''
      - ''
      - defaults
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/var/tmp" in ansible_mounts | map(attribute="mount") | list'
    - ("--fstab" | length == 0)
    - device_name.stdout is defined and device_name.stdout_lines is defined
    - (device_name.stdout | length == 0)
    tags:
    - DISA-STIG-RHEL-08-040133
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_var_tmp_nosuid
    - no_reboot_needed

  - name: 'Add nosuid Option to /var/tmp: Make sure nosuid option is part of the to
      /var/tmp options'
    set_fact:
      mount_info: '{{ mount_info | combine( {''options'':''''~(mount_info.options
        | default(''''))~('','' if (mount_info.options | default('''')) else '''')~''nosuid''
        }) }}'
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/var/tmp" in ansible_mounts | map(attribute="mount") | list'
    - mount_info is defined and "nosuid" not in (mount_info.options | default(''))
    tags:
    - DISA-STIG-RHEL-08-040133
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_var_tmp_nosuid
    - no_reboot_needed

  - name: 'Add nosuid Option to /var/tmp: Ensure /var/tmp is mounted with nosuid option'
    ansible.posix.mount:
      path: /var/tmp
      src: '{{ mount_info.source | default('''') }}'
      opts: '{{ mount_info.options | default('''') }}'
      state: mounted
      fstype: '{{ mount_info.fstype | default('''') }}'
    register: mount_result
    failed_when:
    - mount_result is failed
    - '''target is busy'' not in (mount_result.msg | default(''''))'
    - '''already mounted'' not in (mount_result.msg | default(''''))'
    when:
    - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
      and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
      and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type
      in ["docker", "lxc", "openvz", "podman", "container"] ) )
    - '"/var/tmp" in ansible_mounts | map(attribute="mount") | list'
    - mount_info is defined
    - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab"
      | length == 0)
    tags:
    - DISA-STIG-RHEL-08-040133
    - configure_strategy
    - high_disruption
    - low_complexity
    - medium_severity
    - mount_option_var_tmp_nosuid
    - no_reboot_needed

  - name: Restrict Access to Kernel Message Buffer - Set fact for sysctl paths
    ansible.builtin.set_fact:
      sysctl_paths:
      - /etc/sysctl.d/
      - /run/sysctl.d/
      - /usr/local/lib/sysctl.d/
      - /usr/lib/sysctl.d/
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-010375
    - NIST-800-171-3.1.5
    - NIST-800-53-SI-11(a)
    - NIST-800-53-SI-11(b)
    - disable_strategy
    - low_complexity
    - low_severity
    - medium_disruption
    - reboot_required
    - sysctl_kernel_dmesg_restrict

  - name: Restrict Access to Kernel Message Buffer - Find all files that contain kernel.dmesg_restrict
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*kernel.dmesg_restrict\s*=\s*.*$'
    register: find_all_values
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-010375
    - NIST-800-171-3.1.5
    - NIST-800-53-SI-11(a)
    - NIST-800-53-SI-11(b)
    - disable_strategy
    - low_complexity
    - low_severity
    - medium_disruption
    - reboot_required
    - sysctl_kernel_dmesg_restrict

  - name: Restrict Access to Kernel Message Buffer - Find all files that set kernel.dmesg_restrict
      to correct value
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*kernel.dmesg_restrict\s*=\s*1$'
    register: find_correct_value
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-010375
    - NIST-800-171-3.1.5
    - NIST-800-53-SI-11(a)
    - NIST-800-53-SI-11(b)
    - disable_strategy
    - low_complexity
    - low_severity
    - medium_disruption
    - reboot_required
    - sysctl_kernel_dmesg_restrict

  - name: Restrict Access to Kernel Message Buffer - Comment out any occurrences of
      kernel.dmesg_restrict from config files
    ansible.builtin.replace:
      path: '{{ item | split(":") | first }}'
      regexp: ^[\s]*kernel.dmesg_restrict
      replace: '#kernel.dmesg_restrict'
    loop: '{{ find_all_values.stdout_lines }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
      | length > find_correct_value.stdout_lines | length
    tags:
    - DISA-STIG-RHEL-08-010375
    - NIST-800-171-3.1.5
    - NIST-800-53-SI-11(a)
    - NIST-800-53-SI-11(b)
    - disable_strategy
    - low_complexity
    - low_severity
    - medium_disruption
    - reboot_required
    - sysctl_kernel_dmesg_restrict

  - name: Restrict Access to Kernel Message Buffer - Comment out any occurrences of
      kernel.dmesg_restrict from /etc/sysctl.conf
    ansible.builtin.replace:
      path: '{{ item }}'
      regexp: ^[\s]*kernel.dmesg_restrict
      replace: '#kernel.dmesg_restrict'
    with_fileglob:
    - /etc/sysctl.conf
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-010375
    - NIST-800-171-3.1.5
    - NIST-800-53-SI-11(a)
    - NIST-800-53-SI-11(b)
    - disable_strategy
    - low_complexity
    - low_severity
    - medium_disruption
    - reboot_required
    - sysctl_kernel_dmesg_restrict

  - name: Restrict Access to Kernel Message Buffer - Ensure sysctl kernel.dmesg_restrict
      is set to 1
    ansible.posix.sysctl:
      name: kernel.dmesg_restrict
      value: '1'
      sysctl_file: /etc/sysctl.d/kernel_dmesg_restrict.conf
      state: present
      reload: true
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-010375
    - NIST-800-171-3.1.5
    - NIST-800-53-SI-11(a)
    - NIST-800-53-SI-11(b)
    - disable_strategy
    - low_complexity
    - low_severity
    - medium_disruption
    - reboot_required
    - sysctl_kernel_dmesg_restrict

  - name: Restrict usage of ptrace to descendant processes - Set fact for sysctl paths
    ansible.builtin.set_fact:
      sysctl_paths:
      - /etc/sysctl.d/
      - /run/sysctl.d/
      - /usr/local/lib/sysctl.d/
      - /usr/lib/sysctl.d/
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040282
    - NIST-800-53-SC-7(10)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_kernel_yama_ptrace_scope

  - name: Restrict usage of ptrace to descendant processes - Find all files that contain
      kernel.yama.ptrace_scope
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*kernel.yama.ptrace_scope\s*=\s*.*$'
    register: find_all_values
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040282
    - NIST-800-53-SC-7(10)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_kernel_yama_ptrace_scope

  - name: Restrict usage of ptrace to descendant processes - Find all files that set
      kernel.yama.ptrace_scope to correct value
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*kernel.yama.ptrace_scope\s*=\s*1$'
    register: find_correct_value
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040282
    - NIST-800-53-SC-7(10)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_kernel_yama_ptrace_scope

  - name: Restrict usage of ptrace to descendant processes - Comment out any occurrences
      of kernel.yama.ptrace_scope from config files
    ansible.builtin.replace:
      path: '{{ item | split(":") | first }}'
      regexp: ^[\s]*kernel.yama.ptrace_scope
      replace: '#kernel.yama.ptrace_scope'
    loop: '{{ find_all_values.stdout_lines }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
      | length > find_correct_value.stdout_lines | length
    tags:
    - DISA-STIG-RHEL-08-040282
    - NIST-800-53-SC-7(10)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_kernel_yama_ptrace_scope

  - name: Restrict usage of ptrace to descendant processes - Comment out any occurrences
      of kernel.yama.ptrace_scope from /etc/sysctl.conf
    ansible.builtin.replace:
      path: '{{ item }}'
      regexp: ^[\s]*kernel.yama.ptrace_scope
      replace: '#kernel.yama.ptrace_scope'
    with_fileglob:
    - /etc/sysctl.conf
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040282
    - NIST-800-53-SC-7(10)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_kernel_yama_ptrace_scope

  - name: Restrict usage of ptrace to descendant processes - Ensure sysctl kernel.yama.ptrace_scope
      is set to 1
    ansible.posix.sysctl:
      name: kernel.yama.ptrace_scope
      value: '1'
      sysctl_file: /etc/sysctl.d/kernel_yama_ptrace_scope.conf
      state: present
      reload: true
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040282
    - NIST-800-53-SC-7(10)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_kernel_yama_ptrace_scope

  - name: Disable core dump backtraces - Search for a section in files
    ansible.builtin.find:
      paths: '{{item.path}}'
      patterns: '{{item.pattern}}'
      contains: ^\s*\[Coredump\]
      read_whole_file: true
      use_regex: true
    register: systemd_dropin_files_with_section
    loop:
    - path: '{{ ''/etc/systemd/coredump.conf'' | dirname }}'
      pattern: '{{ ''/etc/systemd/coredump.conf'' | basename | regex_escape }}'
    - path: /etc/systemd/coredump.conf.d
      pattern: .*\.conf
    when:
    - '"kernel" in ansible_facts.packages'
    - '"systemd" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-010675
    - NIST-800-53-CM-6
    - PCI-DSS-Req-3.2
    - PCI-DSSv4-3.3
    - PCI-DSSv4-3.3.1
    - PCI-DSSv4-3.3.1.1
    - coredump_disable_backtraces
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Disable core dump backtraces - Count number of files which contain the correct
      section
    ansible.builtin.set_fact:
      count_of_systemd_dropin_files_with_section: '{{systemd_dropin_files_with_section.results
        | map(attribute=''matched'') | list | map(''int'') | sum}}'
    when:
    - '"kernel" in ansible_facts.packages'
    - '"systemd" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-010675
    - NIST-800-53-CM-6
    - PCI-DSS-Req-3.2
    - PCI-DSSv4-3.3
    - PCI-DSSv4-3.3.1
    - PCI-DSSv4-3.3.1.1
    - coredump_disable_backtraces
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Disable core dump backtraces - Add missing configuration to correct section
    community.general.ini_file:
      path: '{{item}}'
      section: Coredump
      option: ProcessSizeMax
      value: '0'
      state: present
      no_extra_spaces: true
    when:
    - '"kernel" in ansible_facts.packages'
    - '"systemd" in ansible_facts.packages'
    - count_of_systemd_dropin_files_with_section | int > 0
    loop: '{{systemd_dropin_files_with_section.results | sum(attribute=''files'',
      start=[]) | map(attribute=''path'') | list }}'
    tags:
    - DISA-STIG-RHEL-08-010675
    - NIST-800-53-CM-6
    - PCI-DSS-Req-3.2
    - PCI-DSSv4-3.3
    - PCI-DSSv4-3.3.1
    - PCI-DSSv4-3.3.1.1
    - coredump_disable_backtraces
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Disable core dump backtraces - Add configuration to new remediation file
    community.general.ini_file:
      path: /etc/systemd/coredump.conf.d/complianceascode_hardening.conf
      section: Coredump
      option: ProcessSizeMax
      value: '0'
      state: present
      no_extra_spaces: true
      create: true
    when:
    - '"kernel" in ansible_facts.packages'
    - '"systemd" in ansible_facts.packages'
    - count_of_systemd_dropin_files_with_section | int == 0
    tags:
    - DISA-STIG-RHEL-08-010675
    - NIST-800-53-CM-6
    - PCI-DSS-Req-3.2
    - PCI-DSSv4-3.3
    - PCI-DSSv4-3.3.1
    - PCI-DSSv4-3.3.1.1
    - coredump_disable_backtraces
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Disable storing core dump - Search for a section in files
    ansible.builtin.find:
      paths: '{{item.path}}'
      patterns: '{{item.pattern}}'
      contains: ^\s*\[Coredump\]
      read_whole_file: true
      use_regex: true
    register: systemd_dropin_files_with_section
    loop:
    - path: '{{ ''/etc/systemd/coredump.conf'' | dirname }}'
      pattern: '{{ ''/etc/systemd/coredump.conf'' | basename | regex_escape }}'
    - path: /etc/systemd/coredump.conf.d
      pattern: .*\.conf
    when:
    - '"kernel" in ansible_facts.packages'
    - '"systemd" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-010674
    - NIST-800-53-CM-6
    - PCI-DSS-Req-3.2
    - PCI-DSSv4-3.3
    - PCI-DSSv4-3.3.1
    - PCI-DSSv4-3.3.1.1
    - coredump_disable_storage
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Disable storing core dump - Count number of files which contain the correct
      section
    ansible.builtin.set_fact:
      count_of_systemd_dropin_files_with_section: '{{systemd_dropin_files_with_section.results
        | map(attribute=''matched'') | list | map(''int'') | sum}}'
    when:
    - '"kernel" in ansible_facts.packages'
    - '"systemd" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-010674
    - NIST-800-53-CM-6
    - PCI-DSS-Req-3.2
    - PCI-DSSv4-3.3
    - PCI-DSSv4-3.3.1
    - PCI-DSSv4-3.3.1.1
    - coredump_disable_storage
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Disable storing core dump - Add missing configuration to correct section
    community.general.ini_file:
      path: '{{item}}'
      section: Coredump
      option: Storage
      value: none
      state: present
      no_extra_spaces: true
    when:
    - '"kernel" in ansible_facts.packages'
    - '"systemd" in ansible_facts.packages'
    - count_of_systemd_dropin_files_with_section | int > 0
    loop: '{{systemd_dropin_files_with_section.results | sum(attribute=''files'',
      start=[]) | map(attribute=''path'') | list }}'
    tags:
    - DISA-STIG-RHEL-08-010674
    - NIST-800-53-CM-6
    - PCI-DSS-Req-3.2
    - PCI-DSSv4-3.3
    - PCI-DSSv4-3.3.1
    - PCI-DSSv4-3.3.1.1
    - coredump_disable_storage
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Disable storing core dump - Add configuration to new remediation file
    community.general.ini_file:
      path: /etc/systemd/coredump.conf.d/complianceascode_hardening.conf
      section: Coredump
      option: Storage
      value: none
      state: present
      no_extra_spaces: true
      create: true
    when:
    - '"kernel" in ansible_facts.packages'
    - '"systemd" in ansible_facts.packages'
    - count_of_systemd_dropin_files_with_section | int == 0
    tags:
    - DISA-STIG-RHEL-08-010674
    - NIST-800-53-CM-6
    - PCI-DSS-Req-3.2
    - PCI-DSSv4-3.3
    - PCI-DSSv4-3.3.1
    - PCI-DSSv4-3.3.1.1
    - coredump_disable_storage
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Disable Core Dumps for All Users - Set dirs, files and regex variables
    ansible.builtin.set_fact:
      limits_dropin_dir: /etc/security/limits.d
      limits_dropin_file: /etc/security/limits.d/10-ssg-hardening.conf
      limits_main_file: /etc/security/limits.conf
      limits_correct_regex: ^\s*\*\s+hard\s+core\s+0\s*$
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-010673
    - NIST-800-53-CM-6
    - NIST-800-53-SC-7(10)
    - PCI-DSSv4-3.3
    - PCI-DSSv4-3.3.1
    - PCI-DSSv4-3.3.1.1
    - disable_users_coredumps
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Disable Core Dumps for All Users - Find valid drop-ins for core limit
    ansible.builtin.find:
      paths: '{{ limits_dropin_dir }}'
      patterns: '*.conf'
      contains: '{{ limits_correct_regex }}'
      file_type: file
    register: valid_dropins
    failed_when: false
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-010673
    - NIST-800-53-CM-6
    - NIST-800-53-SC-7(10)
    - PCI-DSSv4-3.3
    - PCI-DSSv4-3.3.1
    - PCI-DSSv4-3.3.1.1
    - disable_users_coredumps
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Disable Core Dumps for All Users - Find all drop-ins with any core limit
    ansible.builtin.find:
      paths: '{{ limits_dropin_dir }}'
      patterns: '*.conf'
      contains: ^\s*\*\s+hard\s+core\s+
      file_type: file
    register: all_dropins
    failed_when: false
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-010673
    - NIST-800-53-CM-6
    - NIST-800-53-SC-7(10)
    - PCI-DSSv4-3.3
    - PCI-DSSv4-3.3.1
    - PCI-DSSv4-3.3.1.1
    - disable_users_coredumps
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Disable Core Dumps for All Users - Get invalid drop-ins
    ansible.builtin.set_fact:
      invalid_dropins: '{{ all_dropins.files | rejectattr(''path'', ''in'', valid_dropins.files
        | map(attribute=''path'') | list) | map(attribute=''path'') | list }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-010673
    - NIST-800-53-CM-6
    - NIST-800-53-SC-7(10)
    - PCI-DSSv4-3.3
    - PCI-DSSv4-3.3.1
    - PCI-DSSv4-3.3.1.1
    - disable_users_coredumps
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Disable Core Dumps for All Users - Comment invalid * hard core lines in
      drop-ins
    ansible.builtin.replace:
      path: '{{ item }}'
      regexp: (^\s*\*\s+hard\s+core\s+.*$)
      replace: '#\1'
    loop: '{{ invalid_dropins }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    - invalid_dropins | length > 0
    tags:
    - DISA-STIG-RHEL-08-010673
    - NIST-800-53-CM-6
    - NIST-800-53-SC-7(10)
    - PCI-DSSv4-3.3
    - PCI-DSSv4-3.3.1
    - PCI-DSSv4-3.3.1.1
    - disable_users_coredumps
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Disable Core Dumps for All Users - Check if main limits.conf contains correct
      core limit
    ansible.builtin.find:
      paths: /etc/security
      patterns: limits.conf
      contains: '{{ limits_correct_regex }}'
      file_type: file
    register: main_valid
    failed_when: false
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    - not (valid_dropins.matched | default(0) > 0)
    tags:
    - DISA-STIG-RHEL-08-010673
    - NIST-800-53-CM-6
    - NIST-800-53-SC-7(10)
    - PCI-DSSv4-3.3
    - PCI-DSSv4-3.3.1
    - PCI-DSSv4-3.3.1.1
    - disable_users_coredumps
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Disable Core Dumps for All Users - Set fact if configuration is valid
    ansible.builtin.set_fact:
      core_limit_valid: '{{ (valid_dropins.matched | default(0)) > 0 or (main_valid.matched
        | default(0)) > 0 }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-010673
    - NIST-800-53-CM-6
    - NIST-800-53-SC-7(10)
    - PCI-DSSv4-3.3
    - PCI-DSSv4-3.3.1
    - PCI-DSSv4-3.3.1.1
    - disable_users_coredumps
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Disable Core Dumps for All Users - Ensure drop-in directory exists
    ansible.builtin.file:
      path: '{{ limits_dropin_dir }}'
      state: directory
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    - not core_limit_valid
    tags:
    - DISA-STIG-RHEL-08-010673
    - NIST-800-53-CM-6
    - NIST-800-53-SC-7(10)
    - PCI-DSSv4-3.3
    - PCI-DSSv4-3.3.1
    - PCI-DSSv4-3.3.1.1
    - disable_users_coredumps
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Disable Core Dumps for All Users - Deploy 10-ssg-hardening.conf drop-in
      with correct core limit
    ansible.builtin.copy:
      dest: '{{ limits_dropin_file }}'
      content: |
        *     hard   core    0
    when:
    - '"kernel" in ansible_facts.packages'
    - '"pam" in ansible_facts.packages'
    - not core_limit_valid
    tags:
    - DISA-STIG-RHEL-08-010673
    - NIST-800-53-CM-6
    - NIST-800-53-SC-7(10)
    - PCI-DSSv4-3.3
    - PCI-DSSv4-3.3.1
    - PCI-DSSv4-3.3.1.1
    - disable_users_coredumps
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Disable Core Dumps for SUID programs - Set fact for sysctl paths
    ansible.builtin.set_fact:
      sysctl_paths:
      - /etc/sysctl.d/
      - /run/sysctl.d/
      - /usr/local/lib/sysctl.d/
      - /usr/lib/sysctl.d/
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-SI-11(a)
    - NIST-800-53-SI-11(b)
    - PCI-DSSv4-3.3
    - PCI-DSSv4-3.3.1
    - PCI-DSSv4-3.3.1.1
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_fs_suid_dumpable

  - name: Disable Core Dumps for SUID programs - Find all files that contain fs.suid_dumpable
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*fs.suid_dumpable\s*=\s*.*$'
    register: find_all_values
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-SI-11(a)
    - NIST-800-53-SI-11(b)
    - PCI-DSSv4-3.3
    - PCI-DSSv4-3.3.1
    - PCI-DSSv4-3.3.1.1
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_fs_suid_dumpable

  - name: Disable Core Dumps for SUID programs - Find all files that set fs.suid_dumpable
      to correct value
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*fs.suid_dumpable\s*=\s*0$'
    register: find_correct_value
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-SI-11(a)
    - NIST-800-53-SI-11(b)
    - PCI-DSSv4-3.3
    - PCI-DSSv4-3.3.1
    - PCI-DSSv4-3.3.1.1
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_fs_suid_dumpable

  - name: Disable Core Dumps for SUID programs - Comment out any occurrences of fs.suid_dumpable
      from config files
    ansible.builtin.replace:
      path: '{{ item | split(":") | first }}'
      regexp: ^[\s]*fs.suid_dumpable
      replace: '#fs.suid_dumpable'
    loop: '{{ find_all_values.stdout_lines }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
      | length > find_correct_value.stdout_lines | length
    tags:
    - NIST-800-53-SI-11(a)
    - NIST-800-53-SI-11(b)
    - PCI-DSSv4-3.3
    - PCI-DSSv4-3.3.1
    - PCI-DSSv4-3.3.1.1
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_fs_suid_dumpable

  - name: Disable Core Dumps for SUID programs - Comment out any occurrences of fs.suid_dumpable
      from /etc/sysctl.conf
    ansible.builtin.replace:
      path: '{{ item }}'
      regexp: ^[\s]*fs.suid_dumpable
      replace: '#fs.suid_dumpable'
    with_fileglob:
    - /etc/sysctl.conf
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-SI-11(a)
    - NIST-800-53-SI-11(b)
    - PCI-DSSv4-3.3
    - PCI-DSSv4-3.3.1
    - PCI-DSSv4-3.3.1.1
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_fs_suid_dumpable

  - name: Disable Core Dumps for SUID programs - Ensure sysctl fs.suid_dumpable is
      set to 0
    ansible.posix.sysctl:
      name: fs.suid_dumpable
      value: '0'
      sysctl_file: /etc/sysctl.d/fs_suid_dumpable.conf
      state: present
      reload: true
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-SI-11(a)
    - NIST-800-53-SI-11(b)
    - PCI-DSSv4-3.3
    - PCI-DSSv4-3.3.1
    - PCI-DSSv4-3.3.1.1
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_fs_suid_dumpable

  - name: Restrict Exposed Kernel Pointer Addresses Access - Set fact for sysctl paths
    ansible.builtin.set_fact:
      sysctl_paths:
      - /etc/sysctl.d/
      - /run/sysctl.d/
      - /usr/local/lib/sysctl.d/
      - /usr/lib/sysctl.d/
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040283
    - NIST-800-53-CM-6(a)
    - NIST-800-53-SC-30
    - NIST-800-53-SC-30(2)
    - NIST-800-53-SC-30(5)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_kernel_kptr_restrict

  - name: Restrict Exposed Kernel Pointer Addresses Access - Find all files that contain
      kernel.kptr_restrict
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*kernel.kptr_restrict\s*=\s*.*$'
    register: find_all_values
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040283
    - NIST-800-53-CM-6(a)
    - NIST-800-53-SC-30
    - NIST-800-53-SC-30(2)
    - NIST-800-53-SC-30(5)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_kernel_kptr_restrict

  - name: Restrict Exposed Kernel Pointer Addresses Access - Find all files that set
      kernel.kptr_restrict to correct value
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*kernel.kptr_restrict\s*=\s*1$'
    register: find_correct_value
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040283
    - NIST-800-53-CM-6(a)
    - NIST-800-53-SC-30
    - NIST-800-53-SC-30(2)
    - NIST-800-53-SC-30(5)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_kernel_kptr_restrict

  - name: Restrict Exposed Kernel Pointer Addresses Access - Comment out any occurrences
      of kernel.kptr_restrict from config files
    ansible.builtin.replace:
      path: '{{ item | split(":") | first }}'
      regexp: ^[\s]*kernel.kptr_restrict
      replace: '#kernel.kptr_restrict'
    loop: '{{ find_all_values.stdout_lines }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
      | length > find_correct_value.stdout_lines | length
    tags:
    - DISA-STIG-RHEL-08-040283
    - NIST-800-53-CM-6(a)
    - NIST-800-53-SC-30
    - NIST-800-53-SC-30(2)
    - NIST-800-53-SC-30(5)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_kernel_kptr_restrict

  - name: Restrict Exposed Kernel Pointer Addresses Access - Comment out any occurrences
      of kernel.kptr_restrict from /etc/sysctl.conf
    ansible.builtin.replace:
      path: '{{ item }}'
      regexp: ^[\s]*kernel.kptr_restrict
      replace: '#kernel.kptr_restrict'
    with_fileglob:
    - /etc/sysctl.conf
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040283
    - NIST-800-53-CM-6(a)
    - NIST-800-53-SC-30
    - NIST-800-53-SC-30(2)
    - NIST-800-53-SC-30(5)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_kernel_kptr_restrict

  - name: Restrict Exposed Kernel Pointer Addresses Access - Ensure sysctl kernel.kptr_restrict
      is set to 1
    ansible.posix.sysctl:
      name: kernel.kptr_restrict
      value: '1'
      sysctl_file: /etc/sysctl.d/kernel_kptr_restrict.conf
      state: present
      reload: true
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-040283
    - NIST-800-53-CM-6(a)
    - NIST-800-53-SC-30
    - NIST-800-53-SC-30(2)
    - NIST-800-53-SC-30(5)
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_kernel_kptr_restrict

  - name: Enable Randomized Layout of Virtual Address Space - Set fact for sysctl
      paths
    ansible.builtin.set_fact:
      sysctl_paths:
      - /etc/sysctl.d/
      - /run/sysctl.d/
      - /usr/local/lib/sysctl.d/
      - /usr/lib/sysctl.d/
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-010430
    - NIST-800-171-3.1.7
    - NIST-800-53-CM-6(a)
    - NIST-800-53-SC-30
    - NIST-800-53-SC-30(2)
    - PCI-DSS-Req-2.2.1
    - PCI-DSSv4-3.3
    - PCI-DSSv4-3.3.1
    - PCI-DSSv4-3.3.1.1
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_kernel_randomize_va_space

  - name: Enable Randomized Layout of Virtual Address Space - Find all files that
      contain kernel.randomize_va_space
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*kernel.randomize_va_space\s*=\s*.*$'
    register: find_all_values
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-010430
    - NIST-800-171-3.1.7
    - NIST-800-53-CM-6(a)
    - NIST-800-53-SC-30
    - NIST-800-53-SC-30(2)
    - PCI-DSS-Req-2.2.1
    - PCI-DSSv4-3.3
    - PCI-DSSv4-3.3.1
    - PCI-DSSv4-3.3.1.1
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_kernel_randomize_va_space

  - name: Enable Randomized Layout of Virtual Address Space - Find all files that
      set kernel.randomize_va_space to correct value
    ansible.builtin.shell:
      cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
        -HP '^\s*kernel.randomize_va_space\s*=\s*2$'
    register: find_correct_value
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-010430
    - NIST-800-171-3.1.7
    - NIST-800-53-CM-6(a)
    - NIST-800-53-SC-30
    - NIST-800-53-SC-30(2)
    - PCI-DSS-Req-2.2.1
    - PCI-DSSv4-3.3
    - PCI-DSSv4-3.3.1
    - PCI-DSSv4-3.3.1.1
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_kernel_randomize_va_space

  - name: Enable Randomized Layout of Virtual Address Space - Comment out any occurrences
      of kernel.randomize_va_space from config files
    ansible.builtin.replace:
      path: '{{ item | split(":") | first }}'
      regexp: ^[\s]*kernel.randomize_va_space
      replace: '#kernel.randomize_va_space'
    loop: '{{ find_all_values.stdout_lines }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
      | length > find_correct_value.stdout_lines | length
    tags:
    - DISA-STIG-RHEL-08-010430
    - NIST-800-171-3.1.7
    - NIST-800-53-CM-6(a)
    - NIST-800-53-SC-30
    - NIST-800-53-SC-30(2)
    - PCI-DSS-Req-2.2.1
    - PCI-DSSv4-3.3
    - PCI-DSSv4-3.3.1
    - PCI-DSSv4-3.3.1.1
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_kernel_randomize_va_space

  - name: Enable Randomized Layout of Virtual Address Space - Comment out any occurrences
      of kernel.randomize_va_space from /etc/sysctl.conf
    ansible.builtin.replace:
      path: '{{ item }}'
      regexp: ^[\s]*kernel.randomize_va_space
      replace: '#kernel.randomize_va_space'
    with_fileglob:
    - /etc/sysctl.conf
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-010430
    - NIST-800-171-3.1.7
    - NIST-800-53-CM-6(a)
    - NIST-800-53-SC-30
    - NIST-800-53-SC-30(2)
    - PCI-DSS-Req-2.2.1
    - PCI-DSSv4-3.3
    - PCI-DSSv4-3.3.1
    - PCI-DSSv4-3.3.1.1
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_kernel_randomize_va_space

  - name: Enable Randomized Layout of Virtual Address Space - Ensure sysctl kernel.randomize_va_space
      is set to 2
    ansible.posix.sysctl:
      name: kernel.randomize_va_space
      value: '2'
      sysctl_file: /etc/sysctl.d/kernel_randomize_va_space.conf
      state: present
      reload: true
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-010430
    - NIST-800-171-3.1.7
    - NIST-800-53-CM-6(a)
    - NIST-800-53-SC-30
    - NIST-800-53-SC-30(2)
    - PCI-DSS-Req-2.2.1
    - PCI-DSSv4-3.3
    - PCI-DSSv4-3.3.1
    - PCI-DSSv4-3.3.1.1
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required
    - sysctl_kernel_randomize_va_space

  - name: Ensure SELinux Not Disabled in /etc/default/grub - Find /etc/grub.d/ files
    ansible.builtin.find:
      paths:
      - /etc/grub.d/
      follow: true
    register: result_grub_d
    when:
    - '"kernel" in ansible_facts.packages'
    - '"grub2-common" in ansible_facts.packages'
    tags:
    - NIST-800-171-3.1.2
    - NIST-800-171-3.7.2
    - NIST-800-53-AC-3
    - NIST-800-53-AC-3(3)(a)
    - PCI-DSSv4-1.2
    - PCI-DSSv4-1.2.6
    - grub2_enable_selinux
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure SELinux Not Disabled in /etc/default/grub - Ensure SELinux Not Disabled
      in /etc/grub.d/ files
    ansible.builtin.replace:
      dest: '{{ item.path }}'
      regexp: (selinux|enforcing)=0
    with_items:
    - '{{ result_grub_d.files }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - '"grub2-common" in ansible_facts.packages'
    tags:
    - NIST-800-171-3.1.2
    - NIST-800-171-3.7.2
    - NIST-800-53-AC-3
    - NIST-800-53-AC-3(3)(a)
    - PCI-DSSv4-1.2
    - PCI-DSSv4-1.2.6
    - grub2_enable_selinux
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure SELinux Not Disabled in /etc/default/grub - Check if /etc/grub2.cfg
      exists
    ansible.builtin.stat:
      path: /etc/grub2.cfg
    register: result_grub2_cfg_present
    when:
    - '"kernel" in ansible_facts.packages'
    - '"grub2-common" in ansible_facts.packages'
    tags:
    - NIST-800-171-3.1.2
    - NIST-800-171-3.7.2
    - NIST-800-53-AC-3
    - NIST-800-53-AC-3(3)(a)
    - PCI-DSSv4-1.2
    - PCI-DSSv4-1.2.6
    - grub2_enable_selinux
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure SELinux Not Disabled in /etc/default/grub - Check if /etc/default/grub
      exists
    ansible.builtin.stat:
      path: /etc/default/grub
    register: result_default_grub_present
    when:
    - '"kernel" in ansible_facts.packages'
    - '"grub2-common" in ansible_facts.packages'
    tags:
    - NIST-800-171-3.1.2
    - NIST-800-171-3.7.2
    - NIST-800-53-AC-3
    - NIST-800-53-AC-3(3)(a)
    - PCI-DSSv4-1.2
    - PCI-DSSv4-1.2.6
    - grub2_enable_selinux
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure SELinux Not Disabled in /etc/default/grub - Ensure SELinux Not Disabled
      in /etc/grub2.cfg
    ansible.builtin.replace:
      dest: /etc/grub2.cfg
      regexp: (selinux|enforcing)=0
    when:
    - '"kernel" in ansible_facts.packages'
    - '"grub2-common" in ansible_facts.packages'
    - result_grub2_cfg_present.stat.exists
    tags:
    - NIST-800-171-3.1.2
    - NIST-800-171-3.7.2
    - NIST-800-53-AC-3
    - NIST-800-53-AC-3(3)(a)
    - PCI-DSSv4-1.2
    - PCI-DSSv4-1.2.6
    - grub2_enable_selinux
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure SELinux Not Disabled in /etc/default/grub - Ensure SELinux Not Disabled
      in /etc/default/grub
    ansible.builtin.replace:
      dest: /etc/default/grub
      regexp: (selinux|enforcing)=0
    when:
    - '"kernel" in ansible_facts.packages'
    - '"grub2-common" in ansible_facts.packages'
    - result_default_grub_present.stat.exists
    tags:
    - NIST-800-171-3.1.2
    - NIST-800-171-3.7.2
    - NIST-800-53-AC-3
    - NIST-800-53-AC-3(3)(a)
    - PCI-DSSv4-1.2
    - PCI-DSSv4-1.2.6
    - grub2_enable_selinux
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure SELinux is Not Disabled - Check current SELinux configuration
    ansible.builtin.command:
      cmd: grep -oP '^\s*SELINUX=\K(enforcing|permissive|disabled)' /etc/selinux/config
    register: selinux_config_state
    check_mode: false
    changed_when: false
    failed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - high_severity
    - low_complexity
    - low_disruption
    - reboot_required
    - restrict_strategy
    - selinux_not_disabled

  - name: Ensure SELinux is Not Disabled - Set SELinux state to permissive if disabled
      or not configured
    block:

    - name: Ensure SELinux is Not Disabled
      block:

      - name: Check for duplicate values
        ansible.builtin.lineinfile:
          path: /etc/selinux/config
          create: true
          regexp: (?i)^SELINUX=
          state: absent
        check_mode: true
        changed_when: false
        register: dupes

      - name: Deduplicate values from /etc/selinux/config
        ansible.builtin.lineinfile:
          path: /etc/selinux/config
          create: true
          regexp: (?i)^SELINUX=
          state: absent
        when: dupes.found is defined and dupes.found > 1

      - name: Insert correct line to /etc/selinux/config
        ansible.builtin.lineinfile:
          path: /etc/selinux/config
          create: true
          regexp: (?i)^SELINUX=
          line: SELINUX=permissive
          state: present

    - name: Ensure SELinux is Not Disabled - Mark system to relabel SELinux on next
        boot
      ansible.builtin.file:
        path: /.autorelabel
        state: touch
        access_time: preserve
        modification_time: preserve
    when:
    - '"kernel" in ansible_facts.packages'
    - selinux_config_state.stdout not in ['enforcing', 'permissive']
    tags:
    - high_severity
    - low_complexity
    - low_disruption
    - reboot_required
    - restrict_strategy
    - selinux_not_disabled

  - name: Configure SELinux Policy
    block:

    - name: Check for duplicate values
      ansible.builtin.lineinfile:
        path: /etc/selinux/config
        create: true
        regexp: (?i)^SELINUXTYPE=
        state: absent
      check_mode: true
      changed_when: false
      register: dupes

    - name: Deduplicate values from /etc/selinux/config
      ansible.builtin.lineinfile:
        path: /etc/selinux/config
        create: true
        regexp: (?i)^SELINUXTYPE=
        state: absent
      when: dupes.found is defined and dupes.found > 1

    - name: Insert correct line to /etc/selinux/config
      ansible.builtin.lineinfile:
        path: /etc/selinux/config
        create: true
        regexp: (?i)^SELINUXTYPE=
        line: SELINUXTYPE={{ var_selinux_policy_name }}
        state: present
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-010450
    - NIST-800-171-3.1.2
    - NIST-800-171-3.7.2
    - NIST-800-53-AC-3
    - NIST-800-53-AC-3(3)(a)
    - NIST-800-53-AU-9
    - NIST-800-53-SC-7(21)
    - PCI-DSSv4-1.2
    - PCI-DSSv4-1.2.6
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - selinux_policytype

  - name: Ensure SELinux State is Enforcing - Check current SELinux state
    ansible.builtin.command:
      cmd: getenforce
    register: current_selinux_state
    check_mode: false
    changed_when: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-010170
    - NIST-800-171-3.1.2
    - NIST-800-171-3.7.2
    - NIST-800-53-AC-3
    - NIST-800-53-AC-3(3)(a)
    - NIST-800-53-AU-9
    - NIST-800-53-SC-7(21)
    - PCI-DSSv4-1.2
    - PCI-DSSv4-1.2.6
    - high_severity
    - low_complexity
    - low_disruption
    - no_reboot_needed
    - restrict_strategy
    - selinux_state

  - name: Ensure SELinux State is Enforcing
    block:

    - name: Check for duplicate values
      ansible.builtin.lineinfile:
        path: /etc/selinux/config
        create: true
        regexp: (?i)^SELINUX=
        state: absent
      check_mode: true
      changed_when: false
      register: dupes

    - name: Deduplicate values from /etc/selinux/config
      ansible.builtin.lineinfile:
        path: /etc/selinux/config
        create: true
        regexp: (?i)^SELINUX=
        state: absent
      when: dupes.found is defined and dupes.found > 1

    - name: Insert correct line to /etc/selinux/config
      ansible.builtin.lineinfile:
        path: /etc/selinux/config
        create: true
        regexp: (?i)^SELINUX=
        line: SELINUX={{ var_selinux_state }}
        state: present
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-010170
    - NIST-800-171-3.1.2
    - NIST-800-171-3.7.2
    - NIST-800-53-AC-3
    - NIST-800-53-AC-3(3)(a)
    - NIST-800-53-AU-9
    - NIST-800-53-SC-7(21)
    - PCI-DSSv4-1.2
    - PCI-DSSv4-1.2.6
    - high_severity
    - low_complexity
    - low_disruption
    - no_reboot_needed
    - restrict_strategy
    - selinux_state

  - name: Ensure SELinux State is Enforcing - Mark system to relabel SELinux on next
      boot
    ansible.builtin.file:
      path: /.autorelabel
      state: touch
      access_time: preserve
      modification_time: preserve
    when:
    - '"kernel" in ansible_facts.packages'
    - current_selinux_state.stdout | lower != var_selinux_state
    tags:
    - DISA-STIG-RHEL-08-010170
    - NIST-800-171-3.1.2
    - NIST-800-171-3.7.2
    - NIST-800-53-AC-3
    - NIST-800-53-AC-3(3)(a)
    - NIST-800-53-AU-9
    - NIST-800-53-SC-7(21)
    - PCI-DSSv4-1.2
    - PCI-DSSv4-1.2.6
    - high_severity
    - low_complexity
    - low_disruption
    - no_reboot_needed
    - restrict_strategy
    - selinux_state

  - name: Set the file_groupowner_cron_d_newgroup variable if represented by gid
    ansible.builtin.set_fact:
      file_groupowner_cron_d_newgroup: '0'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_groupowner_cron_d
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure group owner on /etc/cron.d/
    ansible.builtin.file:
      path: /etc/cron.d/
      follow: false
      state: directory
      group: '{{ file_groupowner_cron_d_newgroup }}'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_groupowner_cron_d
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set the file_groupowner_cron_daily_newgroup variable if represented by gid
    ansible.builtin.set_fact:
      file_groupowner_cron_daily_newgroup: '0'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_groupowner_cron_daily
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure group owner on /etc/cron.daily/
    ansible.builtin.file:
      path: /etc/cron.daily/
      follow: false
      state: directory
      group: '{{ file_groupowner_cron_daily_newgroup }}'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_groupowner_cron_daily
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set the file_groupowner_cron_hourly_newgroup variable if represented by
      gid
    ansible.builtin.set_fact:
      file_groupowner_cron_hourly_newgroup: '0'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_groupowner_cron_hourly
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure group owner on /etc/cron.hourly/
    ansible.builtin.file:
      path: /etc/cron.hourly/
      follow: false
      state: directory
      group: '{{ file_groupowner_cron_hourly_newgroup }}'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_groupowner_cron_hourly
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set the file_groupowner_cron_monthly_newgroup variable if represented by
      gid
    ansible.builtin.set_fact:
      file_groupowner_cron_monthly_newgroup: '0'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_groupowner_cron_monthly
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure group owner on /etc/cron.monthly/
    ansible.builtin.file:
      path: /etc/cron.monthly/
      follow: false
      state: directory
      group: '{{ file_groupowner_cron_monthly_newgroup }}'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_groupowner_cron_monthly
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set the file_groupowner_cron_weekly_newgroup variable if represented by
      gid
    ansible.builtin.set_fact:
      file_groupowner_cron_weekly_newgroup: '0'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_groupowner_cron_weekly
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure group owner on /etc/cron.weekly/
    ansible.builtin.file:
      path: /etc/cron.weekly/
      follow: false
      state: directory
      group: '{{ file_groupowner_cron_weekly_newgroup }}'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_groupowner_cron_weekly
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set the file_groupowner_cron_yearly_newgroup variable if represented by
      gid
    ansible.builtin.set_fact:
      file_groupowner_cron_yearly_newgroup: '0'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - configure_strategy
    - file_groupowner_cron_yearly
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure group owner on /etc/cron.yearly/
    ansible.builtin.file:
      path: /etc/cron.yearly/
      follow: false
      state: directory
      group: '{{ file_groupowner_cron_yearly_newgroup }}'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - configure_strategy
    - file_groupowner_cron_yearly
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set the file_groupowner_crontab_newgroup variable if represented by gid
    ansible.builtin.set_fact:
      file_groupowner_crontab_newgroup: '0'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_groupowner_crontab
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /etc/crontab
    ansible.builtin.stat:
      path: /etc/crontab
    register: file_exists
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_groupowner_crontab
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure group owner on /etc/crontab
    ansible.builtin.file:
      path: /etc/crontab
      follow: false
      group: '{{ file_groupowner_crontab_newgroup }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - file_exists.stat is defined and file_exists.stat.exists
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_groupowner_crontab
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set the file_owner_cron_d_newown variable if represented by uid
    ansible.builtin.set_fact:
      file_owner_cron_d_newown: '0'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_owner_cron_d
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure owner on directory /etc/cron.d/
    ansible.builtin.file:
      path: /etc/cron.d/
      follow: false
      state: directory
      owner: '{{ file_owner_cron_d_newown }}'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_owner_cron_d
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set the file_owner_cron_daily_newown variable if represented by uid
    ansible.builtin.set_fact:
      file_owner_cron_daily_newown: '0'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_owner_cron_daily
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure owner on directory /etc/cron.daily/
    ansible.builtin.file:
      path: /etc/cron.daily/
      follow: false
      state: directory
      owner: '{{ file_owner_cron_daily_newown }}'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_owner_cron_daily
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set the file_owner_cron_hourly_newown variable if represented by uid
    ansible.builtin.set_fact:
      file_owner_cron_hourly_newown: '0'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_owner_cron_hourly
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure owner on directory /etc/cron.hourly/
    ansible.builtin.file:
      path: /etc/cron.hourly/
      follow: false
      state: directory
      owner: '{{ file_owner_cron_hourly_newown }}'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_owner_cron_hourly
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set the file_owner_cron_monthly_newown variable if represented by uid
    ansible.builtin.set_fact:
      file_owner_cron_monthly_newown: '0'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_owner_cron_monthly
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure owner on directory /etc/cron.monthly/
    ansible.builtin.file:
      path: /etc/cron.monthly/
      follow: false
      state: directory
      owner: '{{ file_owner_cron_monthly_newown }}'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_owner_cron_monthly
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set the file_owner_cron_weekly_newown variable if represented by uid
    ansible.builtin.set_fact:
      file_owner_cron_weekly_newown: '0'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_owner_cron_weekly
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure owner on directory /etc/cron.weekly/
    ansible.builtin.file:
      path: /etc/cron.weekly/
      follow: false
      state: directory
      owner: '{{ file_owner_cron_weekly_newown }}'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_owner_cron_weekly
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set the file_owner_cron_yearly_newown variable if represented by uid
    ansible.builtin.set_fact:
      file_owner_cron_yearly_newown: '0'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - configure_strategy
    - file_owner_cron_yearly
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure owner on directory /etc/cron.yearly/
    ansible.builtin.file:
      path: /etc/cron.yearly/
      follow: false
      state: directory
      owner: '{{ file_owner_cron_yearly_newown }}'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - configure_strategy
    - file_owner_cron_yearly
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set the file_owner_crontab_newown variable if represented by uid
    ansible.builtin.set_fact:
      file_owner_crontab_newown: '0'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_owner_crontab
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /etc/crontab
    ansible.builtin.stat:
      path: /etc/crontab
    register: file_exists
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_owner_crontab
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure owner on /etc/crontab
    ansible.builtin.file:
      path: /etc/crontab
      follow: false
      owner: '{{ file_owner_crontab_newown }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - file_exists.stat is defined and file_exists.stat.exists
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_owner_crontab
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Find /etc/cron.d/ file(s)
    ansible.builtin.command: 'find -P /etc/cron.d/ -maxdepth 0 -perm /u+s,g+xwrs,o+xwrt  -type
      d '
    register: files_found
    changed_when: false
    failed_when: false
    check_mode: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_permissions_cron_d
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set permissions for /etc/cron.d/ file(s)
    ansible.builtin.file:
      path: '{{ item }}'
      mode: u-s,g-xwrs,o-xwrt
      state: directory
    with_items:
    - '{{ files_found.stdout_lines }}'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_permissions_cron_d
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Find /etc/cron.daily/ file(s)
    ansible.builtin.command: 'find -P /etc/cron.daily/ -maxdepth 0 -perm /u+s,g+xwrs,o+xwrt  -type
      d '
    register: files_found
    changed_when: false
    failed_when: false
    check_mode: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_permissions_cron_daily
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set permissions for /etc/cron.daily/ file(s)
    ansible.builtin.file:
      path: '{{ item }}'
      mode: u-s,g-xwrs,o-xwrt
      state: directory
    with_items:
    - '{{ files_found.stdout_lines }}'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_permissions_cron_daily
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Find /etc/cron.hourly/ file(s)
    ansible.builtin.command: 'find -P /etc/cron.hourly/ -maxdepth 0 -perm /u+s,g+xwrs,o+xwrt  -type
      d '
    register: files_found
    changed_when: false
    failed_when: false
    check_mode: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_permissions_cron_hourly
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set permissions for /etc/cron.hourly/ file(s)
    ansible.builtin.file:
      path: '{{ item }}'
      mode: u-s,g-xwrs,o-xwrt
      state: directory
    with_items:
    - '{{ files_found.stdout_lines }}'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_permissions_cron_hourly
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Find /etc/cron.monthly/ file(s)
    ansible.builtin.command: 'find -P /etc/cron.monthly/ -maxdepth 0 -perm /u+s,g+xwrs,o+xwrt  -type
      d '
    register: files_found
    changed_when: false
    failed_when: false
    check_mode: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_permissions_cron_monthly
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set permissions for /etc/cron.monthly/ file(s)
    ansible.builtin.file:
      path: '{{ item }}'
      mode: u-s,g-xwrs,o-xwrt
      state: directory
    with_items:
    - '{{ files_found.stdout_lines }}'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_permissions_cron_monthly
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Find /etc/cron.weekly/ file(s)
    ansible.builtin.command: 'find -P /etc/cron.weekly/ -maxdepth 0 -perm /u+s,g+xwrs,o+xwrt  -type
      d '
    register: files_found
    changed_when: false
    failed_when: false
    check_mode: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_permissions_cron_weekly
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set permissions for /etc/cron.weekly/ file(s)
    ansible.builtin.file:
      path: '{{ item }}'
      mode: u-s,g-xwrs,o-xwrt
      state: directory
    with_items:
    - '{{ files_found.stdout_lines }}'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_permissions_cron_weekly
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Find /etc/cron.yearly/ file(s)
    ansible.builtin.command: 'find -P /etc/cron.yearly/ -maxdepth 0 -perm /u+s,g+xwrs,o+xwrt  -type
      d '
    register: files_found
    changed_when: false
    failed_when: false
    check_mode: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - configure_strategy
    - file_permissions_cron_yearly
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set permissions for /etc/cron.yearly/ file(s)
    ansible.builtin.file:
      path: '{{ item }}'
      mode: u-s,g-xwrs,o-xwrt
      state: directory
    with_items:
    - '{{ files_found.stdout_lines }}'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - configure_strategy
    - file_permissions_cron_yearly
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /etc/crontab
    ansible.builtin.stat:
      path: /etc/crontab
    register: file_exists
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_permissions_crontab
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure permission u-xs,g-xwrs,o-xwrt on /etc/crontab
    ansible.builtin.file:
      path: /etc/crontab
      mode: u-xs,g-xwrs,o-xwrt
    when:
    - '"kernel" in ansible_facts.packages'
    - file_exists.stat is defined and file_exists.stat.exists
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_permissions_crontab
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure that /etc/at.allow exists - Add empty /etc/at.allow
    ansible.builtin.file:
      path: /etc/at.allow
      state: touch
      owner: '0'
      mode: '0640'
      modification_time: preserve
      access_time: preserve
    when: '"kernel" in ansible_facts.packages'
    tags:
    - disable_strategy
    - file_at_allow_exists
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure that /etc/at.deny does not exist - Remove /etc/at.deny
    ansible.builtin.file:
      path: /etc/at.deny
      state: absent
    when: '"kernel" in ansible_facts.packages'
    tags:
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - disable_strategy
    - file_at_deny_not_exist
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure that /etc/cron.allow exists - Add empty /etc/cron.allow
    ansible.builtin.file:
      path: /etc/cron.allow
      state: touch
      owner: '0'
      mode: '0640'
      modification_time: preserve
      access_time: preserve
    when: '"kernel" in ansible_facts.packages'
    tags:
    - disable_strategy
    - file_cron_allow_exists
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure that /etc/cron.deny does not exist - Remove /etc/cron.deny
    ansible.builtin.file:
      path: /etc/cron.deny
      state: absent
    when: '"kernel" in ansible_facts.packages'
    tags:
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - disable_strategy
    - file_cron_deny_not_exist
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set the file_groupowner_at_allow_newgroup variable if represented by gid
    ansible.builtin.set_fact:
      file_groupowner_at_allow_newgroup: '0'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_groupowner_at_allow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /etc/at.allow
    ansible.builtin.stat:
      path: /etc/at.allow
    register: file_exists
    when: '"kernel" in ansible_facts.packages'
    tags:
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_groupowner_at_allow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure group owner on /etc/at.allow
    ansible.builtin.file:
      path: /etc/at.allow
      follow: false
      group: '{{ file_groupowner_at_allow_newgroup }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - file_exists.stat is defined and file_exists.stat.exists
    tags:
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_groupowner_at_allow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set the file_groupowner_cron_allow_newgroup variable if represented by gid
    ansible.builtin.set_fact:
      file_groupowner_cron_allow_newgroup: '0'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_groupowner_cron_allow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /etc/cron.allow
    ansible.builtin.stat:
      path: /etc/cron.allow
    register: file_exists
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_groupowner_cron_allow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure group owner on /etc/cron.allow
    ansible.builtin.file:
      path: /etc/cron.allow
      follow: false
      group: '{{ file_groupowner_cron_allow_newgroup }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - file_exists.stat is defined and file_exists.stat.exists
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_groupowner_cron_allow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set the file_owner_at_allow_newown variable if represented by uid
    ansible.builtin.set_fact:
      file_owner_at_allow_newown: '0'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_owner_at_allow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /etc/at.allow
    ansible.builtin.stat:
      path: /etc/at.allow
    register: file_exists
    when: '"kernel" in ansible_facts.packages'
    tags:
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_owner_at_allow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure owner on /etc/at.allow
    ansible.builtin.file:
      path: /etc/at.allow
      follow: false
      owner: '{{ file_owner_at_allow_newown }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - file_exists.stat is defined and file_exists.stat.exists
    tags:
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_owner_at_allow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set the file_owner_cron_allow_newown variable if represented by uid
    ansible.builtin.set_fact:
      file_owner_cron_allow_newown: '0'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_owner_cron_allow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /etc/cron.allow
    ansible.builtin.stat:
      path: /etc/cron.allow
    register: file_exists
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_owner_cron_allow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure owner on /etc/cron.allow
    ansible.builtin.file:
      path: /etc/cron.allow
      follow: false
      owner: '{{ file_owner_cron_allow_newown }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - file_exists.stat is defined and file_exists.stat.exists
    tags:
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_owner_cron_allow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /etc/at.allow
    ansible.builtin.stat:
      path: /etc/at.allow
    register: file_exists
    when: '"kernel" in ansible_facts.packages'
    tags:
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_permissions_at_allow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure permission u-xs,g-xws,o-xwrt on /etc/at.allow
    ansible.builtin.file:
      path: /etc/at.allow
      mode: u-xs,g-xws,o-xwrt
    when:
    - '"kernel" in ansible_facts.packages'
    - file_exists.stat is defined and file_exists.stat.exists
    tags:
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_permissions_at_allow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /etc/cron.allow
    ansible.builtin.stat:
      path: /etc/cron.allow
    register: file_exists
    when: '"kernel" in ansible_facts.packages'
    tags:
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_permissions_cron_allow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure permission u-xs,g-xws,o-xwrt on /etc/cron.allow
    ansible.builtin.file:
      path: /etc/cron.allow
      mode: u-xs,g-xws,o-xwrt
    when:
    - '"kernel" in ansible_facts.packages'
    - file_exists.stat is defined and file_exists.stat.exists
    tags:
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_permissions_cron_allow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Make changes to Postfix configuration file
    block:

    - name: Check for duplicate values
      ansible.builtin.lineinfile:
        path: /etc/postfix/main.cf
        create: false
        regexp: (?i)^inet_interfaces\s*=\s*.*$
        state: absent
      check_mode: true
      changed_when: false
      register: dupes

    - name: Deduplicate values from /etc/postfix/main.cf
      ansible.builtin.lineinfile:
        path: /etc/postfix/main.cf
        create: false
        regexp: (?i)^inet_interfaces\s*=\s*.*$
        state: absent
      when: dupes.found is defined and dupes.found > 1

    - name: Insert correct line to /etc/postfix/main.cf
      ansible.builtin.lineinfile:
        path: /etc/postfix/main.cf
        create: false
        regexp: (?i)^inet_interfaces\s*=\s*.*$
        line: inet_interfaces = {{ var_postfix_inet_interfaces }}
        state: present
    when:
    - '"kernel" in ansible_facts.packages'
    - '"postfix" in ansible_facts.packages'
    tags:
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - PCI-DSSv4-1.4
    - PCI-DSSv4-1.4.2
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - postfix_network_listening_disabled
    - restrict_strategy

  - name: Check if chrony main config has active server/pool entries
    ansible.builtin.command:
      cmd: grep -q '^[[:space:]]*\(server\|pool\)[[:space:]]\+[[:graph:]]\+' /etc/chrony.conf
    register: chrony_conf_has_servers
    changed_when: false
    failed_when: false
    when:
    - '"kernel" in ansible_facts.packages'
    - '"chrony" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-030740
    - NIST-800-53-AU-8(1)(a)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.4.3
    - PCI-DSSv4-10.6
    - PCI-DSSv4-10.6.2
    - chronyd_specify_remote_server
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Extract sourcedir paths from chrony configuration
    ansible.builtin.shell:
      cmd: grep '^[[:space:]]*sourcedir[[:space:]]\+' /etc/chrony.conf | awk '{print
        $2}'
    register: chrony_sourcedir_paths
    changed_when: false
    failed_when: false
    when:
    - '"kernel" in ansible_facts.packages'
    - '"chrony" in ansible_facts.packages'
    - chrony_conf_has_servers.rc != 0
    tags:
    - DISA-STIG-RHEL-08-030740
    - NIST-800-53-AU-8(1)(a)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.4.3
    - PCI-DSSv4-10.6
    - PCI-DSSv4-10.6.2
    - chronyd_specify_remote_server
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Check for server/pool entries in sourcedir .sources files
    ansible.builtin.shell:
      cmd: |
        for dir in {{ chrony_sourcedir_paths.stdout_lines | join(' ') }}; do
          if [ -d "$dir" ]; then
            grep -q '^[[:space:]]*\(server\|pool\)[[:space:]]\+[[:graph:]]\+' "$dir"/*.sources 2>/dev/null && exit 0
          fi
        done
        exit 1
    register: chrony_sourcedir_has_servers
    changed_when: false
    failed_when: false
    when:
    - '"kernel" in ansible_facts.packages'
    - '"chrony" in ansible_facts.packages'
    - chrony_conf_has_servers.rc != 0
    - chrony_sourcedir_paths.stdout_lines | length > 0
    tags:
    - DISA-STIG-RHEL-08-030740
    - NIST-800-53-AU-8(1)(a)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.4.3
    - PCI-DSSv4-10.6
    - PCI-DSSv4-10.6.2
    - chronyd_specify_remote_server
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Extract confdir paths from chrony configuration
    ansible.builtin.shell:
      cmd: grep '^[[:space:]]*confdir[[:space:]]\+' /etc/chrony.conf | awk '{print
        $2}'
    register: chrony_confdir_paths
    changed_when: false
    failed_when: false
    when:
    - '"kernel" in ansible_facts.packages'
    - '"chrony" in ansible_facts.packages'
    - chrony_conf_has_servers.rc != 0
    - (chrony_sourcedir_paths.stdout_lines | default([]) | length == 0 or chrony_sourcedir_has_servers.rc
      != 0)
    tags:
    - DISA-STIG-RHEL-08-030740
    - NIST-800-53-AU-8(1)(a)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.4.3
    - PCI-DSSv4-10.6
    - PCI-DSSv4-10.6.2
    - chronyd_specify_remote_server
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Check for server/pool entries in confdir .conf files
    ansible.builtin.shell:
      cmd: |
        for dir in {{ chrony_confdir_paths.stdout_lines | join(' ') }}; do
          if [ -d "$dir" ]; then
            grep -q '^[[:space:]]*\(server\|pool\)[[:space:]]\+[[:graph:]]\+' "$dir"/*.conf 2>/dev/null && exit 0
          fi
        done
        exit 1
    register: chrony_confdir_has_servers
    changed_when: false
    failed_when: false
    when:
    - '"kernel" in ansible_facts.packages'
    - '"chrony" in ansible_facts.packages'
    - chrony_conf_has_servers.rc != 0
    - chrony_confdir_paths.stdout_lines | default([]) | length > 0
    - (chrony_sourcedir_paths.stdout_lines | default([]) | length == 0 or chrony_sourcedir_has_servers.rc
      != 0)
    tags:
    - DISA-STIG-RHEL-08-030740
    - NIST-800-53-AU-8(1)(a)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.4.3
    - PCI-DSSv4-10.6
    - PCI-DSSv4-10.6.2
    - chronyd_specify_remote_server
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Create sourcedir directory if needed
    ansible.builtin.file:
      path: '{{ chrony_sourcedir_paths.stdout_lines[0] }}'
      state: directory
      mode: '0755'
    when:
    - '"kernel" in ansible_facts.packages'
    - '"chrony" in ansible_facts.packages'
    - chrony_conf_has_servers.rc != 0
    - chrony_sourcedir_paths.stdout_lines | default([]) | length > 0
    - chrony_sourcedir_has_servers.rc != 0
    tags:
    - DISA-STIG-RHEL-08-030740
    - NIST-800-53-AU-8(1)(a)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.4.3
    - PCI-DSSv4-10.6
    - PCI-DSSv4-10.6.2
    - chronyd_specify_remote_server
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Add remote time servers to sourcedir .sources file
    ansible.builtin.lineinfile:
      path: '{{ chrony_sourcedir_paths.stdout_lines[0] }}/ntp-servers.sources'
      line: server {{ item }}
      state: present
      create: true
      mode: '0644'
    loop: '{{ var_multiple_time_servers.split(",") }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - '"chrony" in ansible_facts.packages'
    - chrony_conf_has_servers.rc != 0
    - chrony_sourcedir_paths.stdout_lines | default([]) | length > 0
    - chrony_sourcedir_has_servers.rc != 0
    tags:
    - DISA-STIG-RHEL-08-030740
    - NIST-800-53-AU-8(1)(a)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.4.3
    - PCI-DSSv4-10.6
    - PCI-DSSv4-10.6.2
    - chronyd_specify_remote_server
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Create confdir directory if needed
    ansible.builtin.file:
      path: '{{ chrony_confdir_paths.stdout_lines[0] }}'
      state: directory
      mode: '0755'
    when:
    - '"kernel" in ansible_facts.packages'
    - '"chrony" in ansible_facts.packages'
    - chrony_conf_has_servers.rc != 0
    - (chrony_sourcedir_paths.stdout_lines | default([]) | length == 0 or chrony_sourcedir_has_servers.rc
      != 0)
    - chrony_confdir_paths.stdout_lines | default([]) | length > 0
    - chrony_confdir_has_servers.rc != 0
    tags:
    - DISA-STIG-RHEL-08-030740
    - NIST-800-53-AU-8(1)(a)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.4.3
    - PCI-DSSv4-10.6
    - PCI-DSSv4-10.6.2
    - chronyd_specify_remote_server
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Add remote time servers to confdir .conf file
    ansible.builtin.lineinfile:
      path: '{{ chrony_confdir_paths.stdout_lines[0] }}/ntp-servers.conf'
      line: server {{ item }}
      state: present
      create: true
      mode: '0644'
    loop: '{{ var_multiple_time_servers.split(",") }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - '"chrony" in ansible_facts.packages'
    - chrony_conf_has_servers.rc != 0
    - (chrony_sourcedir_paths.stdout_lines | default([]) | length == 0 or chrony_sourcedir_has_servers.rc
      != 0)
    - chrony_confdir_paths.stdout_lines | default([]) | length > 0
    - chrony_confdir_has_servers.rc != 0
    tags:
    - DISA-STIG-RHEL-08-030740
    - NIST-800-53-AU-8(1)(a)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.4.3
    - PCI-DSSv4-10.6
    - PCI-DSSv4-10.6.2
    - chronyd_specify_remote_server
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Add remote time servers to main chrony configuration
    ansible.builtin.lineinfile:
      path: /etc/chrony.conf
      line: server {{ item }}
      state: present
      create: true
    loop: '{{ var_multiple_time_servers.split(",") }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - '"chrony" in ansible_facts.packages'
    - chrony_conf_has_servers.rc != 0
    - (chrony_sourcedir_paths.stdout_lines | default([]) | length == 0 or chrony_sourcedir_has_servers.rc
      != 0)
    - (chrony_confdir_paths.stdout_lines | default([]) | length == 0 or chrony_confdir_has_servers.rc
      != 0)
    tags:
    - DISA-STIG-RHEL-08-030740
    - NIST-800-53-AU-8(1)(a)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.4.3
    - PCI-DSSv4-10.6
    - PCI-DSSv4-10.6.2
    - chronyd_specify_remote_server
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Detect if file /etc/sysconfig/chronyd is not empty or missing
    ansible.builtin.find:
      path: /etc/sysconfig/
      patterns: chronyd
      contains: ^([\s]*OPTIONS=["]?[^"]*)("?)
    register: chronyd_file
    when:
    - '"kernel" in ansible_facts.packages'
    - '"chrony" in ansible_facts.packages'
    tags:
    - PCI-DSSv4-10.6
    - PCI-DSSv4-10.6.3
    - chronyd_run_as_chrony_user
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Remove any previous configuration of user used to run chronyd process
    ansible.builtin.replace:
      path: /etc/sysconfig/chronyd
      regexp: \s*-u\s*\w+\s*
      replace: ' '
    when:
    - '"kernel" in ansible_facts.packages'
    - '"chrony" in ansible_facts.packages'
    - chronyd_file is defined and chronyd_file.matched > 0
    tags:
    - PCI-DSSv4-10.6
    - PCI-DSSv4-10.6.3
    - chronyd_run_as_chrony_user
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Correct existing line in /etc/sysconfig/chronyd to run chronyd as chrony
      user
    ansible.builtin.lineinfile:
      path: /etc/sysconfig/chronyd
      regexp: ^([\s]*OPTIONS=["]?[^"]*)("?)
      line: \1 -u chrony\2
      state: present
      backrefs: true
    when:
    - '"kernel" in ansible_facts.packages'
    - '"chrony" in ansible_facts.packages'
    - chronyd_file is defined and chronyd_file.matched > 0
    tags:
    - PCI-DSSv4-10.6
    - PCI-DSSv4-10.6.3
    - chronyd_run_as_chrony_user
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Insert correct line into /etc/sysconfig/chronyd ensuring chronyd runs as
      chrony user
    ansible.builtin.lineinfile:
      path: /etc/sysconfig/chronyd
      line: OPTIONS="-u chrony"
      state: present
      create: true
    when:
    - '"kernel" in ansible_facts.packages'
    - '"chrony" in ansible_facts.packages'
    - chronyd_file is defined and chronyd_file.matched == 0
    tags:
    - PCI-DSSv4-10.6
    - PCI-DSSv4-10.6.3
    - chronyd_run_as_chrony_user
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set the file_groupowner_sshd_config_newgroup variable if represented by
      gid
    ansible.builtin.set_fact:
      file_groupowner_sshd_config_newgroup: '0'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-17(a)
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - configure_strategy
    - file_groupowner_sshd_config
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /etc/ssh/sshd_config
    ansible.builtin.stat:
      path: /etc/ssh/sshd_config
    register: file_exists
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-17(a)
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - configure_strategy
    - file_groupowner_sshd_config
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure group owner on /etc/ssh/sshd_config
    ansible.builtin.file:
      path: /etc/ssh/sshd_config
      follow: false
      group: '{{ file_groupowner_sshd_config_newgroup }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - file_exists.stat is defined and file_exists.stat.exists
    tags:
    - NIST-800-53-AC-17(a)
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - configure_strategy
    - file_groupowner_sshd_config
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Check that the ssh_keys group is defined
    ansible.builtin.getent:
      database: group
      key: ssh_keys
    ignore_errors: true
    when:
    - '"kernel" in ansible_facts.packages'
    - file_groupownership_sshd_private_key_newgroup is undefined
    tags:
    - configure_strategy
    - file_groupownership_sshd_private_key
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set the file_groupownership_sshd_private_key_newgroup variable if ssh_keys
      found
    ansible.builtin.set_fact:
      file_groupownership_sshd_private_key_newgroup: ssh_keys
    when:
    - '"kernel" in ansible_facts.packages'
    - ansible_facts.getent_group["ssh_keys"] is defined
    tags:
    - configure_strategy
    - file_groupownership_sshd_private_key
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Find /etc/ssh/ file(s) matching ^.*_key$
    ansible.builtin.command: find -P /etc/ssh/ -maxdepth 1 -type f  ! -group ssh_keys
      -regextype posix-extended -regex "^.*_key$"
    register: files_found
    changed_when: false
    failed_when: false
    check_mode: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - configure_strategy
    - file_groupownership_sshd_private_key
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure group owner on /etc/ssh/ file(s) matching ^.*_key$
    ansible.builtin.file:
      path: '{{ item }}'
      follow: false
      group: '{{ file_groupownership_sshd_private_key_newgroup }}'
      state: file
    with_items:
    - '{{ files_found.stdout_lines }}'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - configure_strategy
    - file_groupownership_sshd_private_key
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set the file_groupownership_sshd_pub_key_newgroup variable if represented
      by gid
    ansible.builtin.set_fact:
      file_groupownership_sshd_pub_key_newgroup: '0'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - configure_strategy
    - file_groupownership_sshd_pub_key
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Find /etc/ssh/ file(s) matching ^.*\.pub$
    ansible.builtin.command: find -P /etc/ssh/ -maxdepth 1 -type f  ! -group 0 -regextype
      posix-extended -regex "^.*\.pub$"
    register: files_found
    changed_when: false
    failed_when: false
    check_mode: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - configure_strategy
    - file_groupownership_sshd_pub_key
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure group owner on /etc/ssh/ file(s) matching ^.*\.pub$
    ansible.builtin.file:
      path: '{{ item }}'
      follow: false
      group: '{{ file_groupownership_sshd_pub_key_newgroup }}'
      state: file
    with_items:
    - '{{ files_found.stdout_lines }}'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - configure_strategy
    - file_groupownership_sshd_pub_key
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set the file_owner_sshd_config_newown variable if represented by uid
    ansible.builtin.set_fact:
      file_owner_sshd_config_newown: '0'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-17(a)
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - configure_strategy
    - file_owner_sshd_config
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /etc/ssh/sshd_config
    ansible.builtin.stat:
      path: /etc/ssh/sshd_config
    register: file_exists
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-17(a)
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - configure_strategy
    - file_owner_sshd_config
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure owner on /etc/ssh/sshd_config
    ansible.builtin.file:
      path: /etc/ssh/sshd_config
      follow: false
      owner: '{{ file_owner_sshd_config_newown }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - file_exists.stat is defined and file_exists.stat.exists
    tags:
    - NIST-800-53-AC-17(a)
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - configure_strategy
    - file_owner_sshd_config
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set the file_ownership_sshd_private_key_newown variable if represented by
      uid
    ansible.builtin.set_fact:
      file_ownership_sshd_private_key_newown: '0'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - configure_strategy
    - file_ownership_sshd_private_key
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Find /etc/ssh/ file(s) matching ^.*_key$
    ansible.builtin.command: find -P /etc/ssh/ -maxdepth 1 -type f  ! -user 0 -regextype
      posix-extended -regex "^.*_key$"
    register: files_found
    changed_when: false
    failed_when: false
    check_mode: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - configure_strategy
    - file_ownership_sshd_private_key
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure owner on /etc/ssh/ file(s) matching ^.*_key$
    ansible.builtin.file:
      path: '{{ item }}'
      follow: false
      owner: '{{ file_ownership_sshd_private_key_newown }}'
      state: file
    with_items:
    - '{{ files_found.stdout_lines }}'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - configure_strategy
    - file_ownership_sshd_private_key
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set the file_ownership_sshd_pub_key_newown variable if represented by uid
    ansible.builtin.set_fact:
      file_ownership_sshd_pub_key_newown: '0'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - configure_strategy
    - file_ownership_sshd_pub_key
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Find /etc/ssh/ file(s) matching ^.*\.pub$
    ansible.builtin.command: find -P /etc/ssh/ -maxdepth 1 -type f  ! -user 0 -regextype
      posix-extended -regex "^.*\.pub$"
    register: files_found
    changed_when: false
    failed_when: false
    check_mode: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - configure_strategy
    - file_ownership_sshd_pub_key
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure owner on /etc/ssh/ file(s) matching ^.*\.pub$
    ansible.builtin.file:
      path: '{{ item }}'
      follow: false
      owner: '{{ file_ownership_sshd_pub_key_newown }}'
      state: file
    with_items:
    - '{{ files_found.stdout_lines }}'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - configure_strategy
    - file_ownership_sshd_pub_key
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /etc/ssh/sshd_config
    ansible.builtin.stat:
      path: /etc/ssh/sshd_config
    register: file_exists
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-17(a)
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_permissions_sshd_config
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure permission u-xs,g-xwrs,o-xwrt on /etc/ssh/sshd_config
    ansible.builtin.file:
      path: /etc/ssh/sshd_config
      mode: u-xs,g-xwrs,o-xwrt
    when:
    - '"kernel" in ansible_facts.packages'
    - file_exists.stat is defined and file_exists.stat.exists
    tags:
    - NIST-800-53-AC-17(a)
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_permissions_sshd_config
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Find root:root-owned keys
    ansible.builtin.command: find -H /etc/ssh/ -maxdepth 1 -user root -regex ".*_key$"
      -type f -group root -perm /u+xs,g+xwrs,o+xwrt
    register: root_owned_keys
    changed_when: false
    failed_when: false
    check_mode: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-010490
    - NIST-800-171-3.1.13
    - NIST-800-171-3.13.10
    - NIST-800-53-AC-17(a)
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-2.2.4
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_permissions_sshd_private_key
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set permissions for root:root-owned keys
    ansible.builtin.file:
      path: '{{ item }}'
      mode: u-xs,g-xwrs,o-xwrt
      state: file
    with_items:
    - '{{ root_owned_keys.stdout_lines }}'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-010490
    - NIST-800-171-3.1.13
    - NIST-800-171-3.13.10
    - NIST-800-53-AC-17(a)
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-2.2.4
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_permissions_sshd_private_key
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Find root:ssh_keys-owned keys
    ansible.builtin.command: find -H /etc/ssh/ -maxdepth 1 -user root -regex ".*_key$"
      -type f -group ssh_keys -perm /u+xs,g+xws,o+xwrt
    register: dedicated_group_owned_keys
    changed_when: false
    failed_when: false
    check_mode: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-010490
    - NIST-800-171-3.1.13
    - NIST-800-171-3.13.10
    - NIST-800-53-AC-17(a)
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-2.2.4
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_permissions_sshd_private_key
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set permissions for root:ssh_keys-owned keys
    ansible.builtin.file:
      path: '{{ item }}'
      mode: u-xs,g-xws,o-xwrt
      state: file
    with_items:
    - '{{ dedicated_group_owned_keys.stdout_lines }}'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-010490
    - NIST-800-171-3.1.13
    - NIST-800-171-3.13.10
    - NIST-800-53-AC-17(a)
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-2.2.4
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_permissions_sshd_private_key
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Find /etc/ssh/ file(s)
    ansible.builtin.command: find -P /etc/ssh/ -maxdepth 1 -perm /u+xs,g+xws,o+xwt  -type
      f -regextype posix-extended -regex "^.*\.pub$"
    register: files_found
    changed_when: false
    failed_when: false
    check_mode: false
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-010480
    - NIST-800-171-3.1.13
    - NIST-800-171-3.13.10
    - NIST-800-53-AC-17(a)
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-2.2.4
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_permissions_sshd_pub_key
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set permissions for /etc/ssh/ file(s)
    ansible.builtin.file:
      path: '{{ item }}'
      mode: u-xs,g-xws,o-xwt
      state: file
    with_items:
    - '{{ files_found.stdout_lines }}'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-010480
    - NIST-800-171-3.1.13
    - NIST-800-171-3.13.10
    - NIST-800-53-AC-17(a)
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-2.2.4
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - configure_strategy
    - file_permissions_sshd_pub_key
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set SSH Client Alive Count Max
    block:

    - name: Check for duplicate values
      ansible.builtin.lineinfile:
        path: /etc/ssh/sshd_config
        create: true
        regexp: (?i)(?i)^\s*ClientAliveCountMax\s+
        state: absent
      check_mode: true
      changed_when: false
      register: dupes

    - name: Deduplicate values from /etc/ssh/sshd_config
      ansible.builtin.lineinfile:
        path: /etc/ssh/sshd_config
        create: true
        regexp: (?i)(?i)^\s*ClientAliveCountMax\s+
        state: absent
      when: dupes.found is defined and dupes.found > 1

    - name: Insert correct line to /etc/ssh/sshd_config
      ansible.builtin.lineinfile:
        path: /etc/ssh/sshd_config
        create: true
        regexp: (?i)(?i)^\s*ClientAliveCountMax\s+
        line: ClientAliveCountMax {{ var_sshd_set_keepalive }}
        state: present
        insertbefore: BOF
        validate: /usr/sbin/sshd -t -f %s
    when: '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.5.6
    - DISA-STIG-RHEL-08-010200
    - NIST-800-171-3.1.11
    - NIST-800-53-AC-12
    - NIST-800-53-AC-17(a)
    - NIST-800-53-AC-2(5)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-SC-10
    - PCI-DSS-Req-8.1.8
    - PCI-DSSv4-8.2
    - PCI-DSSv4-8.2.8
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy
    - sshd_set_keepalive

  - name: Set SSH Client Alive Interval
    block:

    - name: Check for duplicate values
      ansible.builtin.lineinfile:
        path: /etc/ssh/sshd_config
        create: true
        regexp: (?i)(?i)^\s*ClientAliveInterval\s+
        state: absent
      check_mode: true
      changed_when: false
      register: dupes

    - name: Deduplicate values from /etc/ssh/sshd_config
      ansible.builtin.lineinfile:
        path: /etc/ssh/sshd_config
        create: true
        regexp: (?i)(?i)^\s*ClientAliveInterval\s+
        state: absent
      when: dupes.found is defined and dupes.found > 1

    - name: Insert correct line to /etc/ssh/sshd_config
      ansible.builtin.lineinfile:
        path: /etc/ssh/sshd_config
        create: true
        regexp: (?i)(?i)^\s*ClientAliveInterval\s+
        line: ClientAliveInterval {{ sshd_idle_timeout_value }}
        state: present
        insertbefore: BOF
        validate: /usr/sbin/sshd -t -f %s
    when: '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.5.6
    - DISA-STIG-RHEL-08-010201
    - NIST-800-171-3.1.11
    - NIST-800-53-AC-12
    - NIST-800-53-AC-17(a)
    - NIST-800-53-AC-17(a)
    - NIST-800-53-AC-2(5)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-SC-10
    - PCI-DSS-Req-8.1.8
    - PCI-DSSv4-8.2
    - PCI-DSSv4-8.2.8
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy
    - sshd_set_idle_timeout

  - name: Disable Host-Based Authentication
    block:

    - name: Check for duplicate values
      ansible.builtin.lineinfile:
        path: /etc/ssh/sshd_config
        create: true
        regexp: (?i)(?i)^\s*HostbasedAuthentication\s+
        state: absent
      check_mode: true
      changed_when: false
      register: dupes

    - name: Deduplicate values from /etc/ssh/sshd_config
      ansible.builtin.lineinfile:
        path: /etc/ssh/sshd_config
        create: true
        regexp: (?i)(?i)^\s*HostbasedAuthentication\s+
        state: absent
      when: dupes.found is defined and dupes.found > 1

    - name: Insert correct line to /etc/ssh/sshd_config
      ansible.builtin.lineinfile:
        path: /etc/ssh/sshd_config
        create: true
        regexp: (?i)(?i)^\s*HostbasedAuthentication\s+
        line: HostbasedAuthentication no
        state: present
        insertbefore: BOF
        validate: /usr/sbin/sshd -t -f %s
    when: '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.5.6
    - NIST-800-171-3.1.12
    - NIST-800-53-AC-17(a)
    - NIST-800-53-AC-3
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - PCI-DSSv4-8.3
    - PCI-DSSv4-8.3.1
    - disable_host_auth
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Disable SSH Access via Empty Passwords
    block:

    - name: Check for duplicate values
      ansible.builtin.lineinfile:
        path: /etc/ssh/sshd_config
        create: true
        regexp: (?i)(?i)^\s*PermitEmptyPasswords\s+
        state: absent
      check_mode: true
      changed_when: false
      register: dupes

    - name: Deduplicate values from /etc/ssh/sshd_config
      ansible.builtin.lineinfile:
        path: /etc/ssh/sshd_config
        create: true
        regexp: (?i)(?i)^\s*PermitEmptyPasswords\s+
        state: absent
      when: dupes.found is defined and dupes.found > 1

    - name: Insert correct line to /etc/ssh/sshd_config
      ansible.builtin.lineinfile:
        path: /etc/ssh/sshd_config
        create: true
        regexp: (?i)(?i)^\s*PermitEmptyPasswords\s+
        line: PermitEmptyPasswords no
        state: present
        insertbefore: BOF
        validate: /usr/sbin/sshd -t -f %s
    when: '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.5.6
    - DISA-STIG-RHEL-08-020330
    - NIST-800-171-3.1.1
    - NIST-800-171-3.1.5
    - NIST-800-53-AC-17(a)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - PCI-DSS-Req-2.2.4
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - high_severity
    - low_complexity
    - low_disruption
    - no_reboot_needed
    - restrict_strategy
    - sshd_disable_empty_passwords

  - name: Disable SSH Forwarding
    block:

    - name: Check for duplicate values
      ansible.builtin.lineinfile:
        path: /etc/ssh/sshd_config
        create: true
        regexp: (?i)(?i)^\s*DisableForwarding\s+
        state: absent
      check_mode: true
      changed_when: false
      register: dupes

    - name: Deduplicate values from /etc/ssh/sshd_config
      ansible.builtin.lineinfile:
        path: /etc/ssh/sshd_config
        create: true
        regexp: (?i)(?i)^\s*DisableForwarding\s+
        state: absent
      when: dupes.found is defined and dupes.found > 1

    - name: Insert correct line to /etc/ssh/sshd_config
      ansible.builtin.lineinfile:
        path: /etc/ssh/sshd_config
        create: true
        regexp: (?i)(?i)^\s*DisableForwarding\s+
        line: DisableForwarding yes
        state: present
        insertbefore: BOF
        validate: /usr/sbin/sshd -t -f %s
    when: '"kernel" in ansible_facts.packages'
    tags:
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy
    - sshd_disable_forwarding

  - name: Disable GSSAPI Authentication
    block:

    - name: Check for duplicate values
      ansible.builtin.lineinfile:
        path: /etc/ssh/sshd_config
        create: true
        regexp: (?i)(?i)^\s*GSSAPIAuthentication\s+
        state: absent
      check_mode: true
      changed_when: false
      register: dupes

    - name: Deduplicate values from /etc/ssh/sshd_config
      ansible.builtin.lineinfile:
        path: /etc/ssh/sshd_config
        create: true
        regexp: (?i)(?i)^\s*GSSAPIAuthentication\s+
        state: absent
      when: dupes.found is defined and dupes.found > 1

    - name: Insert correct line to /etc/ssh/sshd_config
      ansible.builtin.lineinfile:
        path: /etc/ssh/sshd_config
        create: true
        regexp: (?i)(?i)^\s*GSSAPIAuthentication\s+
        line: GSSAPIAuthentication no
        state: present
        insertbefore: BOF
        validate: /usr/sbin/sshd -t -f %s
    when: '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-010522
    - NIST-800-171-3.1.12
    - NIST-800-53-AC-17(a)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy
    - sshd_disable_gssapi_auth

  - name: Disable SSH Support for .rhosts Files
    block:

    - name: Check for duplicate values
      ansible.builtin.lineinfile:
        path: /etc/ssh/sshd_config
        create: true
        regexp: (?i)(?i)^\s*IgnoreRhosts\s+
        state: absent
      check_mode: true
      changed_when: false
      register: dupes

    - name: Deduplicate values from /etc/ssh/sshd_config
      ansible.builtin.lineinfile:
        path: /etc/ssh/sshd_config
        create: true
        regexp: (?i)(?i)^\s*IgnoreRhosts\s+
        state: absent
      when: dupes.found is defined and dupes.found > 1

    - name: Insert correct line to /etc/ssh/sshd_config
      ansible.builtin.lineinfile:
        path: /etc/ssh/sshd_config
        create: true
        regexp: (?i)(?i)^\s*IgnoreRhosts\s+
        line: IgnoreRhosts yes
        state: present
        insertbefore: BOF
        validate: /usr/sbin/sshd -t -f %s
    when: '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.5.6
    - NIST-800-171-3.1.12
    - NIST-800-53-AC-17(a)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy
    - sshd_disable_rhosts

  - name: Disable SSH Root Login
    block:

    - name: Check for duplicate values
      ansible.builtin.lineinfile:
        path: /etc/ssh/sshd_config
        create: true
        regexp: (?i)(?i)^\s*PermitRootLogin\s+
        state: absent
      check_mode: true
      changed_when: false
      register: dupes

    - name: Deduplicate values from /etc/ssh/sshd_config
      ansible.builtin.lineinfile:
        path: /etc/ssh/sshd_config
        create: true
        regexp: (?i)(?i)^\s*PermitRootLogin\s+
        state: absent
      when: dupes.found is defined and dupes.found > 1

    - name: Insert correct line to /etc/ssh/sshd_config
      ansible.builtin.lineinfile:
        path: /etc/ssh/sshd_config
        create: true
        regexp: (?i)(?i)^\s*PermitRootLogin\s+
        line: PermitRootLogin no
        state: present
        insertbefore: BOF
        validate: /usr/sbin/sshd -t -f %s
    when: '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.5.6
    - DISA-STIG-RHEL-08-010550
    - NIST-800-171-3.1.1
    - NIST-800-171-3.1.5
    - NIST-800-53-AC-17(a)
    - NIST-800-53-AC-6(2)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - NIST-800-53-IA-2
    - NIST-800-53-IA-2(5)
    - PCI-DSS-Req-2.2.4
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy
    - sshd_disable_root_login

  - name: Do Not Allow SSH Environment Options
    block:

    - name: Check for duplicate values
      ansible.builtin.lineinfile:
        path: /etc/ssh/sshd_config
        create: true
        regexp: (?i)(?i)^\s*PermitUserEnvironment\s+
        state: absent
      check_mode: true
      changed_when: false
      register: dupes

    - name: Deduplicate values from /etc/ssh/sshd_config
      ansible.builtin.lineinfile:
        path: /etc/ssh/sshd_config
        create: true
        regexp: (?i)(?i)^\s*PermitUserEnvironment\s+
        state: absent
      when: dupes.found is defined and dupes.found > 1

    - name: Insert correct line to /etc/ssh/sshd_config
      ansible.builtin.lineinfile:
        path: /etc/ssh/sshd_config
        create: true
        regexp: (?i)(?i)^\s*PermitUserEnvironment\s+
        line: PermitUserEnvironment no
        state: present
        insertbefore: BOF
        validate: /usr/sbin/sshd -t -f %s
    when: '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.5.6
    - DISA-STIG-RHEL-08-010830
    - NIST-800-171-3.1.12
    - NIST-800-53-AC-17(a)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-7(a)
    - NIST-800-53-CM-7(b)
    - PCI-DSS-Req-2.2.4
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy
    - sshd_do_not_permit_user_env

  - name: Enable PAM
    block:

    - name: Check for duplicate values
      ansible.builtin.lineinfile:
        path: /etc/ssh/sshd_config
        create: true
        regexp: (?i)(?i)^\s*UsePAM\s+
        state: absent
      check_mode: true
      changed_when: false
      register: dupes

    - name: Deduplicate values from /etc/ssh/sshd_config
      ansible.builtin.lineinfile:
        path: /etc/ssh/sshd_config
        create: true
        regexp: (?i)(?i)^\s*UsePAM\s+
        state: absent
      when: dupes.found is defined and dupes.found > 1

    - name: Insert correct line to /etc/ssh/sshd_config
      ansible.builtin.lineinfile:
        path: /etc/ssh/sshd_config
        create: true
        regexp: (?i)(?i)^\s*UsePAM\s+
        line: UsePAM yes
        state: present
        insertbefore: BOF
        validate: /usr/sbin/sshd -t -f %s
    when: '"kernel" in ansible_facts.packages'
    tags:
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy
    - sshd_enable_pam

  - name: Enable SSH Warning Banner
    block:

    - name: Check for duplicate values
      ansible.builtin.lineinfile:
        path: /etc/ssh/sshd_config
        create: true
        regexp: (?i)(?i)^\s*Banner\s+
        state: absent
      check_mode: true
      changed_when: false
      register: dupes

    - name: Deduplicate values from /etc/ssh/sshd_config
      ansible.builtin.lineinfile:
        path: /etc/ssh/sshd_config
        create: true
        regexp: (?i)(?i)^\s*Banner\s+
        state: absent
      when: dupes.found is defined and dupes.found > 1

    - name: Insert correct line to /etc/ssh/sshd_config
      ansible.builtin.lineinfile:
        path: /etc/ssh/sshd_config
        create: true
        regexp: (?i)(?i)^\s*Banner\s+
        line: Banner /etc/issue.net
        state: present
        insertbefore: BOF
        validate: /usr/sbin/sshd -t -f %s
    when: '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.5.6
    - NIST-800-171-3.1.9
    - NIST-800-53-AC-17(a)
    - NIST-800-53-AC-8(a)
    - NIST-800-53-AC-8(c)
    - NIST-800-53-CM-6(a)
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy
    - sshd_enable_warning_banner_net

  - name: Ensure SSH LoginGraceTime is configured
    block:

    - name: Check for duplicate values
      ansible.builtin.lineinfile:
        path: /etc/ssh/sshd_config
        create: true
        regexp: (?i)(?i)^\s*LoginGraceTime\s+
        state: absent
      check_mode: true
      changed_when: false
      register: dupes

    - name: Deduplicate values from /etc/ssh/sshd_config
      ansible.builtin.lineinfile:
        path: /etc/ssh/sshd_config
        create: true
        regexp: (?i)(?i)^\s*LoginGraceTime\s+
        state: absent
      when: dupes.found is defined and dupes.found > 1

    - name: Insert correct line to /etc/ssh/sshd_config
      ansible.builtin.lineinfile:
        path: /etc/ssh/sshd_config
        create: true
        regexp: (?i)(?i)^\s*LoginGraceTime\s+
        line: LoginGraceTime {{ var_sshd_set_login_grace_time }}
        state: present
        insertbefore: BOF
        validate: /usr/sbin/sshd -t -f %s
    when: '"kernel" in ansible_facts.packages'
    tags:
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy
    - sshd_set_login_grace_time

  - name: Set SSH Daemon LogLevel to VERBOSE
    block:

    - name: Check for duplicate values
      ansible.builtin.lineinfile:
        path: /etc/ssh/sshd_config
        create: true
        regexp: (?i)(?i)^\s*LogLevel\s+
        state: absent
      check_mode: true
      changed_when: false
      register: dupes

    - name: Deduplicate values from /etc/ssh/sshd_config
      ansible.builtin.lineinfile:
        path: /etc/ssh/sshd_config
        create: true
        regexp: (?i)(?i)^\s*LogLevel\s+
        state: absent
      when: dupes.found is defined and dupes.found > 1

    - name: Insert correct line to /etc/ssh/sshd_config
      ansible.builtin.lineinfile:
        path: /etc/ssh/sshd_config
        create: true
        regexp: (?i)(?i)^\s*LogLevel\s+
        line: LogLevel VERBOSE
        state: present
        insertbefore: BOF
        validate: /usr/sbin/sshd -t -f %s
    when: '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AC-17(1)
    - NIST-800-53-AC-17(a)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-2.2.4
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy
    - sshd_set_loglevel_verbose

  - name: Set SSH authentication attempt limit
    block:

    - name: Check for duplicate values
      ansible.builtin.lineinfile:
        path: /etc/ssh/sshd_config
        create: true
        regexp: (?i)(?i)^\s*MaxAuthTries\s+
        state: absent
      check_mode: true
      changed_when: false
      register: dupes

    - name: Deduplicate values from /etc/ssh/sshd_config
      ansible.builtin.lineinfile:
        path: /etc/ssh/sshd_config
        create: true
        regexp: (?i)(?i)^\s*MaxAuthTries\s+
        state: absent
      when: dupes.found is defined and dupes.found > 1

    - name: Insert correct line to /etc/ssh/sshd_config
      ansible.builtin.lineinfile:
        path: /etc/ssh/sshd_config
        create: true
        regexp: (?i)(?i)^\s*MaxAuthTries\s+
        line: MaxAuthTries {{ sshd_max_auth_tries_value }}
        state: present
        insertbefore: BOF
        validate: /usr/sbin/sshd -t -f %s
    when: '"kernel" in ansible_facts.packages'
    tags:
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy
    - sshd_set_max_auth_tries

  - name: Set SSH MaxSessions limit
    block:

    - name: Check for duplicate values
      ansible.builtin.lineinfile:
        path: /etc/ssh/sshd_config
        create: true
        regexp: (?i)(?i)^\s*MaxSessions\s+
        state: absent
      check_mode: true
      changed_when: false
      register: dupes

    - name: Deduplicate values from /etc/ssh/sshd_config
      ansible.builtin.lineinfile:
        path: /etc/ssh/sshd_config
        create: true
        regexp: (?i)(?i)^\s*MaxSessions\s+
        state: absent
      when: dupes.found is defined and dupes.found > 1

    - name: Insert correct line to /etc/ssh/sshd_config
      ansible.builtin.lineinfile:
        path: /etc/ssh/sshd_config
        create: true
        regexp: (?i)(?i)^\s*MaxSessions\s+
        line: MaxSessions {{ var_sshd_max_sessions }}
        state: present
        insertbefore: BOF
        validate: /usr/sbin/sshd -t -f %s
    when: '"kernel" in ansible_facts.packages'
    tags:
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy
    - sshd_set_max_sessions

  - name: Ensure SSH MaxStartups is configured
    block:

    - name: Check for duplicate values
      ansible.builtin.lineinfile:
        path: /etc/ssh/sshd_config
        create: true
        regexp: (?i)(?i)^\s*MaxStartups\s+
        state: absent
      check_mode: true
      changed_when: false
      register: dupes

    - name: Deduplicate values from /etc/ssh/sshd_config
      ansible.builtin.lineinfile:
        path: /etc/ssh/sshd_config
        create: true
        regexp: (?i)(?i)^\s*MaxStartups\s+
        state: absent
      when: dupes.found is defined and dupes.found > 1

    - name: Insert correct line to /etc/ssh/sshd_config
      ansible.builtin.lineinfile:
        path: /etc/ssh/sshd_config
        create: true
        regexp: (?i)(?i)^\s*MaxStartups\s+
        line: MaxStartups {{ var_sshd_set_maxstartups }}
        state: present
        insertbefore: BOF
        validate: /usr/sbin/sshd -t -f %s
    when: '"kernel" in ansible_facts.packages'
    tags:
    - PCI-DSSv4-2.2
    - PCI-DSSv4-2.2.6
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy
    - sshd_set_maxstartups

  - name: Check if audit argument is already present in /etc/default/grub
    ansible.builtin.slurp:
      src: /etc/default/grub
    register: etc_default_grub
    when:
    - '"kernel" in ansible_facts.packages'
    - '"grub2-common" in ansible_facts.packages'
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030601
    - NIST-800-171-3.3.1
    - NIST-800-53-AC-17(1)
    - NIST-800-53-AU-10
    - NIST-800-53-AU-14(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-IR-5(1)
    - PCI-DSS-Req-10.3
    - PCI-DSSv4-10.7
    - PCI-DSSv4-10.7.2
    - grub2_audit_argument
    - low_disruption
    - low_severity
    - medium_complexity
    - reboot_required
    - restrict_strategy

  - name: Check if audit argument is already present
    ansible.builtin.command: /sbin/grubby --info=ALL
    register: grubby_info
    check_mode: false
    changed_when: false
    failed_when: false
    when:
    - '"kernel" in ansible_facts.packages'
    - '"grub2-common" in ansible_facts.packages'
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030601
    - NIST-800-171-3.3.1
    - NIST-800-53-AC-17(1)
    - NIST-800-53-AU-10
    - NIST-800-53-AU-14(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-IR-5(1)
    - PCI-DSS-Req-10.3
    - PCI-DSSv4-10.7
    - PCI-DSSv4-10.7.2
    - grub2_audit_argument
    - low_disruption
    - low_severity
    - medium_complexity
    - reboot_required
    - restrict_strategy

  - name: Update grub defaults and the bootloader menu
    ansible.builtin.command: /sbin/grubby --update-kernel=ALL --args="audit=1"
    when:
    - '"kernel" in ansible_facts.packages'
    - '"grub2-common" in ansible_facts.packages'
    - (grubby_info.stdout is not search('audit=1')) or ((etc_default_grub['content']
      | b64decode) is not search('audit=1'))
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030601
    - NIST-800-171-3.3.1
    - NIST-800-53-AC-17(1)
    - NIST-800-53-AU-10
    - NIST-800-53-AU-14(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-IR-5(1)
    - PCI-DSS-Req-10.3
    - PCI-DSSv4-10.7
    - PCI-DSSv4-10.7.2
    - grub2_audit_argument
    - low_disruption
    - low_severity
    - medium_complexity
    - reboot_required
    - restrict_strategy

  - name: Check if audit_backlog_limit argument is already present in /etc/default/grub
    ansible.builtin.slurp:
      src: /etc/default/grub
    register: etc_default_grub
    when:
    - '"kernel" in ansible_facts.packages'
    - '"grub2-common" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-030602
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-10.7
    - PCI-DSSv4-10.7.2
    - grub2_audit_backlog_limit_argument
    - low_disruption
    - low_severity
    - medium_complexity
    - reboot_required
    - restrict_strategy

  - name: Check if audit_backlog_limit argument is already present
    ansible.builtin.command: /sbin/grubby --info=ALL
    register: grubby_info
    check_mode: false
    changed_when: false
    failed_when: false
    when:
    - '"kernel" in ansible_facts.packages'
    - '"grub2-common" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-030602
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-10.7
    - PCI-DSSv4-10.7.2
    - grub2_audit_backlog_limit_argument
    - low_disruption
    - low_severity
    - medium_complexity
    - reboot_required
    - restrict_strategy

  - name: Update grub defaults and the bootloader menu
    ansible.builtin.command: /sbin/grubby --update-kernel=ALL --args="audit_backlog_limit={{
      var_audit_backlog_limit }}"
    when:
    - '"kernel" in ansible_facts.packages'
    - '"grub2-common" in ansible_facts.packages'
    - (grubby_info.stdout is not search('audit_backlog_limit=' ~ var_audit_backlog_limit))
      or ((etc_default_grub['content'] | b64decode) is not search('audit_backlog_limit='
      ~ var_audit_backlog_limit))
    tags:
    - DISA-STIG-RHEL-08-030602
    - NIST-800-53-CM-6(a)
    - PCI-DSSv4-10.7
    - PCI-DSSv4-10.7.2
    - grub2_audit_backlog_limit_argument
    - low_disruption
    - low_severity
    - medium_complexity
    - reboot_required
    - restrict_strategy

  - name: Ensure the Audit Configuration is Loaded Regardless of Errors - Collect
      all files from /etc/audit/rules.d with .rules extension
    ansible.builtin.find:
      paths: /etc/audit/rules.d/
      patterns: '*.rules'
    register: find_rules_d
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - audit_rules_continue_loading
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Ensure the Audit Configuration is Loaded Regardless of Errors - Check if
      target files exist and get their content
    ansible.builtin.stat:
      path: '{{ item }}'
    register: audit_files_stat
    loop:
    - /etc/audit/audit.rules
    - /etc/audit/rules.d/01-initialize.rules
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - audit_rules_continue_loading
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Ensure the Audit Configuration is Loaded Regardless of Errors - Read content
      of existing audit files
    ansible.builtin.slurp:
      src: '{{ item.item }}'
    register: audit_files_content
    loop: '{{ audit_files_stat.results }}'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - item.stat.exists
    tags:
    - audit_rules_continue_loading
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Ensure the Audit Configuration is Loaded Regardless of Errors - Check if
      -c is already correctly set in target files
    ansible.builtin.set_fact:
      continue_loading_correctly_set: |-
        {{
          audit_files_content.results
          | selectattr('content', 'defined')
          | map(attribute='content')
          | map('b64decode')
          | select('search', '^-c$', multiline=True)
          | list
          | length == 2
        }}
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - audit_rules_continue_loading
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Ensure the Audit Configuration is Loaded Regardless of Errors - Remove any
      existing -c option from all Audit config files
    ansible.builtin.lineinfile:
      path: '{{ item }}'
      regexp: ^\s*-c\s*.*$
      state: absent
    loop: '{{ find_rules_d.files | map(attribute=''path'') | list + [''/etc/audit/audit.rules'']
      }}'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - not continue_loading_correctly_set
    tags:
    - audit_rules_continue_loading
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Ensure the Audit Configuration is Loaded Regardless of Errors - Ensure target
      directories exist
    ansible.builtin.file:
      path: '{{ item | dirname }}'
      state: directory
      mode: '0750'
    loop:
    - /etc/audit/audit.rules
    - /etc/audit/rules.d/01-initialize.rules
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - not continue_loading_correctly_set
    tags:
    - audit_rules_continue_loading
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Ensure the Audit Configuration is Loaded Regardless of Errors - Add Audit
      -c option to make rules continue loading
    ansible.builtin.lineinfile:
      path: '{{ item }}'
      create: true
      line: -c
      regexp: ^\s*-c\s*.*$
      insertbefore: BOF
      mode: g-rwx,o-rwx
    loop:
    - /etc/audit/audit.rules
    - /etc/audit/rules.d/01-initialize.rules
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - not continue_loading_correctly_set
    tags:
    - audit_rules_continue_loading
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Make the auditd Configuration Immutable - Collect all files from /etc/audit/rules.d
      with .rules extension
    ansible.builtin.find:
      paths: /etc/audit/rules.d/
      patterns: '*.rules'
    register: find_rules_d
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030121
    - NIST-800-171-3.3.1
    - NIST-800-171-3.4.3
    - NIST-800-53-AC-6(9)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.2
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.2
    - audit_rules_immutable
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Make the auditd Configuration Immutable - Check if target files exist and
      get their content
    ansible.builtin.stat:
      path: '{{ item }}'
    register: audit_files_stat
    loop:
    - /etc/audit/audit.rules
    - /etc/audit/rules.d/immutable.rules
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030121
    - NIST-800-171-3.3.1
    - NIST-800-171-3.4.3
    - NIST-800-53-AC-6(9)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.2
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.2
    - audit_rules_immutable
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Make the auditd Configuration Immutable - Read content of existing audit
      files
    ansible.builtin.slurp:
      src: '{{ item.item }}'
    register: audit_files_content
    loop: '{{ audit_files_stat.results }}'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - item.stat.exists
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030121
    - NIST-800-171-3.3.1
    - NIST-800-171-3.4.3
    - NIST-800-53-AC-6(9)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.2
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.2
    - audit_rules_immutable
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Make the auditd Configuration Immutable - Check if -e 2 is already correctly
      set in target files
    ansible.builtin.set_fact:
      immutable_correctly_set: |-
        {{
          audit_files_content.results
          | selectattr('content', 'defined')
          | map(attribute='content')
          | map('b64decode')
          | select('search', '^-e 2$', multiline=True)
          | list
          | length == 2
        }}
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030121
    - NIST-800-171-3.3.1
    - NIST-800-171-3.4.3
    - NIST-800-53-AC-6(9)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.2
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.2
    - audit_rules_immutable
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Make the auditd Configuration Immutable - Remove any existing -e option
      from all Audit config files
    ansible.builtin.lineinfile:
      path: '{{ item }}'
      regexp: ^\s*-e\s+.*$
      state: absent
    loop: '{{ find_rules_d.files | map(attribute=''path'') | list + [''/etc/audit/audit.rules'']
      }}'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - not immutable_correctly_set
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030121
    - NIST-800-171-3.3.1
    - NIST-800-171-3.4.3
    - NIST-800-53-AC-6(9)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.2
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.2
    - audit_rules_immutable
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Make the auditd Configuration Immutable - Ensure target directories exist
    ansible.builtin.file:
      path: '{{ item | dirname }}'
      state: directory
      mode: '0750'
    loop:
    - /etc/audit/audit.rules
    - /etc/audit/rules.d/immutable.rules
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - not immutable_correctly_set
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030121
    - NIST-800-171-3.3.1
    - NIST-800-171-3.4.3
    - NIST-800-53-AC-6(9)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.2
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.2
    - audit_rules_immutable
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Make the auditd Configuration Immutable - Add Audit -e 2 option to make
      rules immutable
    ansible.builtin.lineinfile:
      path: '{{ item }}'
      create: true
      line: -e 2
      regexp: ^\s*-e\s+.*$
      mode: g-rwx,o-rwx
    loop:
    - /etc/audit/audit.rules
    - /etc/audit/rules.d/immutable.rules
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - not immutable_correctly_set
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030121
    - NIST-800-171-3.3.1
    - NIST-800-171-3.4.3
    - NIST-800-53-AC-6(9)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.2
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.2
    - audit_rules_immutable
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Record Events that Modify the System's Mandatory Access Controls - Check
      if watch rule for /etc/selinux/ already exists in /etc/audit/rules.d/
    ansible.builtin.find:
      paths: /etc/audit/rules.d
      contains: ^\s*-w\s+/etc/selinux/\s+-p\s+wa(\s|$)+
      patterns: '*.rules'
    register: find_existing_watch_rules_d
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.8
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_mac_modification
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Record Events that Modify the System's Mandatory Access Controls - Search
      /etc/audit/rules.d for other rules with specified key MAC-policy
    ansible.builtin.find:
      paths: /etc/audit/rules.d
      contains: ^.*(?:-F key=|-k\s+)MAC-policy$
      patterns: '*.rules'
    register: find_watch_key
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
      == 0
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.8
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_mac_modification
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Record Events that Modify the System's Mandatory Access Controls - Use /etc/audit/rules.d/MAC-policy.rules
      as the recipient for the rule
    ansible.builtin.set_fact:
      all_files:
      - /etc/audit/rules.d/MAC-policy.rules
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_watch_key.matched is defined and find_watch_key.matched == 0 and find_existing_watch_rules_d.matched
      is defined and find_existing_watch_rules_d.matched == 0
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.8
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_mac_modification
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Record Events that Modify the System's Mandatory Access Controls - Use matched
      file as the recipient for the rule
    ansible.builtin.set_fact:
      all_files:
      - '{{ find_watch_key.files | map(attribute=''path'') | list | first }}'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_watch_key.matched is defined and find_watch_key.matched > 0 and find_existing_watch_rules_d.matched
      is defined and find_existing_watch_rules_d.matched == 0
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.8
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_mac_modification
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Record Events that Modify the System's Mandatory Access Controls - Add watch
      rule for /etc/selinux/ in /etc/audit/rules.d/
    ansible.builtin.lineinfile:
      path: '{{ all_files[0] }}'
      line: -w /etc/selinux/ -p wa -k MAC-policy
      create: true
      mode: '0600'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
      == 0
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.8
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_mac_modification
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Record Events that Modify the System's Mandatory Access Controls - Check
      if watch rule for /etc/selinux/ already exists in /etc/audit/audit.rules
    ansible.builtin.find:
      paths: /etc/audit/
      contains: ^\s*-w\s+/etc/selinux/\s+-p\s+wa(\s|$)+
      patterns: audit.rules
    register: find_existing_watch_audit_rules
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.8
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_mac_modification
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Record Events that Modify the System's Mandatory Access Controls - Add watch
      rule for /etc/selinux/ in /etc/audit/audit.rules
    ansible.builtin.lineinfile:
      line: -w /etc/selinux/ -p wa -k MAC-policy
      state: present
      dest: /etc/audit/audit.rules
      create: true
      mode: '0600'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched
      == 0
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.8
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_mac_modification
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Record Events that Modify the System's Mandatory Access Controls in usr/share
      - Check if watch rule for /usr/share/selinux/ already exists in /etc/audit/rules.d/
    ansible.builtin.find:
      paths: /etc/audit/rules.d
      contains: ^\s*-w\s+/usr/share/selinux/\s+-p\s+wa(\s|$)+
      patterns: '*.rules'
    register: find_existing_watch_rules_d
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-171-3.1.8
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - audit_rules_mac_modification_usr_share
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify the System's Mandatory Access Controls in usr/share
      - Search /etc/audit/rules.d for other rules with specified key MAC-policy
    ansible.builtin.find:
      paths: /etc/audit/rules.d
      contains: ^.*(?:-F key=|-k\s+)MAC-policy$
      patterns: '*.rules'
    register: find_watch_key
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
      == 0
    tags:
    - NIST-800-171-3.1.8
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - audit_rules_mac_modification_usr_share
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify the System's Mandatory Access Controls in usr/share
      - Use /etc/audit/rules.d/MAC-policy.rules as the recipient for the rule
    ansible.builtin.set_fact:
      all_files:
      - /etc/audit/rules.d/MAC-policy.rules
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_watch_key.matched is defined and find_watch_key.matched == 0 and find_existing_watch_rules_d.matched
      is defined and find_existing_watch_rules_d.matched == 0
    tags:
    - NIST-800-171-3.1.8
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - audit_rules_mac_modification_usr_share
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify the System's Mandatory Access Controls in usr/share
      - Use matched file as the recipient for the rule
    ansible.builtin.set_fact:
      all_files:
      - '{{ find_watch_key.files | map(attribute=''path'') | list | first }}'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_watch_key.matched is defined and find_watch_key.matched > 0 and find_existing_watch_rules_d.matched
      is defined and find_existing_watch_rules_d.matched == 0
    tags:
    - NIST-800-171-3.1.8
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - audit_rules_mac_modification_usr_share
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify the System's Mandatory Access Controls in usr/share
      - Add watch rule for /usr/share/selinux/ in /etc/audit/rules.d/
    ansible.builtin.lineinfile:
      path: '{{ all_files[0] }}'
      line: -w /usr/share/selinux/ -p wa -k MAC-policy
      create: true
      mode: '0600'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
      == 0
    tags:
    - NIST-800-171-3.1.8
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - audit_rules_mac_modification_usr_share
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify the System's Mandatory Access Controls in usr/share
      - Check if watch rule for /usr/share/selinux/ already exists in /etc/audit/audit.rules
    ansible.builtin.find:
      paths: /etc/audit/
      contains: ^\s*-w\s+/usr/share/selinux/\s+-p\s+wa(\s|$)+
      patterns: audit.rules
    register: find_existing_watch_audit_rules
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-171-3.1.8
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - audit_rules_mac_modification_usr_share
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify the System's Mandatory Access Controls in usr/share
      - Add watch rule for /usr/share/selinux/ in /etc/audit/audit.rules
    ansible.builtin.lineinfile:
      line: -w /usr/share/selinux/ -p wa -k MAC-policy
      state: present
      dest: /etc/audit/audit.rules
      create: true
      mode: '0600'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched
      == 0
    tags:
    - NIST-800-171-3.1.8
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - audit_rules_mac_modification_usr_share
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Set architecture for audit mount tasks
    ansible.builtin.set_fact:
      audit_arch: b64
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
      == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030302
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.7
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.7
    - audit_rules_media_export
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Perform remediation of Audit rules for mount for 32bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - mount
        syscall_grouping: []

    - name: Check existence of mount in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/export.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/export.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=export
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - mount
        syscall_grouping: []

    - name: Check existence of mount in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=export
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030302
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.7
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.7
    - audit_rules_media_export
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Perform remediation of Audit rules for mount for 64bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - mount
        syscall_grouping: []

    - name: Check existence of mount in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/export.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/export.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=export
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - mount
        syscall_grouping: []

    - name: Check existence of mount in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=export
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - audit_arch == "b64"
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030302
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.7
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.7
    - audit_rules_media_export
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Set architecture for audit tasks
    ansible.builtin.set_fact:
      audit_arch: b64
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
      == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_networkconfig_modification
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Remediate audit rules for network configuration for 32bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - sethostname
        - setdomainname
        syscall_grouping:
        - sethostname
        - setdomainname

    - name: Check existence of sethostname, setdomainname in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/audit_rules_networkconfig_modification.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/audit_rules_networkconfig_modification.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F key=audit_rules_networkconfig_modification
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - sethostname
        - setdomainname
        syscall_grouping:
        - sethostname
        - setdomainname

    - name: Check existence of sethostname, setdomainname in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F key=audit_rules_networkconfig_modification
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_networkconfig_modification
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Remediate audit rules for network configuration for 64bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - sethostname
        - setdomainname
        syscall_grouping:
        - sethostname
        - setdomainname

    - name: Check existence of sethostname, setdomainname in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/audit_rules_networkconfig_modification.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/audit_rules_networkconfig_modification.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F key=audit_rules_networkconfig_modification
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - sethostname
        - setdomainname
        syscall_grouping:
        - sethostname
        - setdomainname

    - name: Check existence of sethostname, setdomainname in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F key=audit_rules_networkconfig_modification
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - audit_arch == "b64"
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_networkconfig_modification
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify the System's Network Environment - Check if watch
      rule for /etc/issue already exists in /etc/audit/rules.d/
    ansible.builtin.find:
      paths: /etc/audit/rules.d
      contains: ^\s*-w\s+/etc/issue\s+-p\s+wa(\s|$)+
      patterns: '*.rules'
    register: find_existing_watch_rules_d
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_networkconfig_modification
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify the System's Network Environment - Search /etc/audit/rules.d
      for other rules with specified key audit_rules_networkconfig_modification
    ansible.builtin.find:
      paths: /etc/audit/rules.d
      contains: ^.*(?:-F key=|-k\s+)audit_rules_networkconfig_modification$
      patterns: '*.rules'
    register: find_watch_key
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
      == 0
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_networkconfig_modification
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify the System's Network Environment - Use /etc/audit/rules.d/audit_rules_networkconfig_modification.rules
      as the recipient for the rule
    ansible.builtin.set_fact:
      all_files:
      - /etc/audit/rules.d/audit_rules_networkconfig_modification.rules
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_watch_key.matched is defined and find_watch_key.matched == 0 and find_existing_watch_rules_d.matched
      is defined and find_existing_watch_rules_d.matched == 0
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_networkconfig_modification
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify the System's Network Environment - Use matched
      file as the recipient for the rule
    ansible.builtin.set_fact:
      all_files:
      - '{{ find_watch_key.files | map(attribute=''path'') | list | first }}'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_watch_key.matched is defined and find_watch_key.matched > 0 and find_existing_watch_rules_d.matched
      is defined and find_existing_watch_rules_d.matched == 0
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_networkconfig_modification
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify the System's Network Environment - Add watch rule
      for /etc/issue in /etc/audit/rules.d/
    ansible.builtin.lineinfile:
      path: '{{ all_files[0] }}'
      line: -w /etc/issue -p wa -k audit_rules_networkconfig_modification
      create: true
      mode: '0600'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
      == 0
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_networkconfig_modification
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify the System's Network Environment - Check if watch
      rule for /etc/issue already exists in /etc/audit/audit.rules
    ansible.builtin.find:
      paths: /etc/audit/
      contains: ^\s*-w\s+/etc/issue\s+-p\s+wa(\s|$)+
      patterns: audit.rules
    register: find_existing_watch_audit_rules
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_networkconfig_modification
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify the System's Network Environment - Add watch rule
      for /etc/issue in /etc/audit/audit.rules
    ansible.builtin.lineinfile:
      line: -w /etc/issue -p wa -k audit_rules_networkconfig_modification
      state: present
      dest: /etc/audit/audit.rules
      create: true
      mode: '0600'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched
      == 0
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_networkconfig_modification
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify the System's Network Environment - Check if watch
      rule for /etc/issue.net already exists in /etc/audit/rules.d/
    ansible.builtin.find:
      paths: /etc/audit/rules.d
      contains: ^\s*-w\s+/etc/issue.net\s+-p\s+wa(\s|$)+
      patterns: '*.rules'
    register: find_existing_watch_rules_d
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_networkconfig_modification
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify the System's Network Environment - Search /etc/audit/rules.d
      for other rules with specified key audit_rules_networkconfig_modification
    ansible.builtin.find:
      paths: /etc/audit/rules.d
      contains: ^.*(?:-F key=|-k\s+)audit_rules_networkconfig_modification$
      patterns: '*.rules'
    register: find_watch_key
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
      == 0
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_networkconfig_modification
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify the System's Network Environment - Use /etc/audit/rules.d/audit_rules_networkconfig_modification.rules
      as the recipient for the rule
    ansible.builtin.set_fact:
      all_files:
      - /etc/audit/rules.d/audit_rules_networkconfig_modification.rules
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_watch_key.matched is defined and find_watch_key.matched == 0 and find_existing_watch_rules_d.matched
      is defined and find_existing_watch_rules_d.matched == 0
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_networkconfig_modification
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify the System's Network Environment - Use matched
      file as the recipient for the rule
    ansible.builtin.set_fact:
      all_files:
      - '{{ find_watch_key.files | map(attribute=''path'') | list | first }}'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_watch_key.matched is defined and find_watch_key.matched > 0 and find_existing_watch_rules_d.matched
      is defined and find_existing_watch_rules_d.matched == 0
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_networkconfig_modification
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify the System's Network Environment - Add watch rule
      for /etc/issue.net in /etc/audit/rules.d/
    ansible.builtin.lineinfile:
      path: '{{ all_files[0] }}'
      line: -w /etc/issue.net -p wa -k audit_rules_networkconfig_modification
      create: true
      mode: '0600'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
      == 0
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_networkconfig_modification
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify the System's Network Environment - Check if watch
      rule for /etc/issue.net already exists in /etc/audit/audit.rules
    ansible.builtin.find:
      paths: /etc/audit/
      contains: ^\s*-w\s+/etc/issue.net\s+-p\s+wa(\s|$)+
      patterns: audit.rules
    register: find_existing_watch_audit_rules
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_networkconfig_modification
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify the System's Network Environment - Add watch rule
      for /etc/issue.net in /etc/audit/audit.rules
    ansible.builtin.lineinfile:
      line: -w /etc/issue.net -p wa -k audit_rules_networkconfig_modification
      state: present
      dest: /etc/audit/audit.rules
      create: true
      mode: '0600'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched
      == 0
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_networkconfig_modification
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify the System's Network Environment - Check if watch
      rule for /etc/hosts already exists in /etc/audit/rules.d/
    ansible.builtin.find:
      paths: /etc/audit/rules.d
      contains: ^\s*-w\s+/etc/hosts\s+-p\s+wa(\s|$)+
      patterns: '*.rules'
    register: find_existing_watch_rules_d
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_networkconfig_modification
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify the System's Network Environment - Search /etc/audit/rules.d
      for other rules with specified key audit_rules_networkconfig_modification
    ansible.builtin.find:
      paths: /etc/audit/rules.d
      contains: ^.*(?:-F key=|-k\s+)audit_rules_networkconfig_modification$
      patterns: '*.rules'
    register: find_watch_key
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
      == 0
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_networkconfig_modification
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify the System's Network Environment - Use /etc/audit/rules.d/audit_rules_networkconfig_modification.rules
      as the recipient for the rule
    ansible.builtin.set_fact:
      all_files:
      - /etc/audit/rules.d/audit_rules_networkconfig_modification.rules
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_watch_key.matched is defined and find_watch_key.matched == 0 and find_existing_watch_rules_d.matched
      is defined and find_existing_watch_rules_d.matched == 0
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_networkconfig_modification
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify the System's Network Environment - Use matched
      file as the recipient for the rule
    ansible.builtin.set_fact:
      all_files:
      - '{{ find_watch_key.files | map(attribute=''path'') | list | first }}'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_watch_key.matched is defined and find_watch_key.matched > 0 and find_existing_watch_rules_d.matched
      is defined and find_existing_watch_rules_d.matched == 0
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_networkconfig_modification
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify the System's Network Environment - Add watch rule
      for /etc/hosts in /etc/audit/rules.d/
    ansible.builtin.lineinfile:
      path: '{{ all_files[0] }}'
      line: -w /etc/hosts -p wa -k audit_rules_networkconfig_modification
      create: true
      mode: '0600'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
      == 0
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_networkconfig_modification
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify the System's Network Environment - Check if watch
      rule for /etc/hosts already exists in /etc/audit/audit.rules
    ansible.builtin.find:
      paths: /etc/audit/
      contains: ^\s*-w\s+/etc/hosts\s+-p\s+wa(\s|$)+
      patterns: audit.rules
    register: find_existing_watch_audit_rules
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_networkconfig_modification
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify the System's Network Environment - Add watch rule
      for /etc/hosts in /etc/audit/audit.rules
    ansible.builtin.lineinfile:
      line: -w /etc/hosts -p wa -k audit_rules_networkconfig_modification
      state: present
      dest: /etc/audit/audit.rules
      create: true
      mode: '0600'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched
      == 0
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_networkconfig_modification
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify the System's Network Environment - Check if watch
      rule for /etc/sysconfig/network already exists in /etc/audit/rules.d/
    ansible.builtin.find:
      paths: /etc/audit/rules.d
      contains: ^\s*-w\s+/etc/sysconfig/network\s+-p\s+wa(\s|$)+
      patterns: '*.rules'
    register: find_existing_watch_rules_d
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_networkconfig_modification
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify the System's Network Environment - Search /etc/audit/rules.d
      for other rules with specified key audit_rules_networkconfig_modification
    ansible.builtin.find:
      paths: /etc/audit/rules.d
      contains: ^.*(?:-F key=|-k\s+)audit_rules_networkconfig_modification$
      patterns: '*.rules'
    register: find_watch_key
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
      == 0
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_networkconfig_modification
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify the System's Network Environment - Use /etc/audit/rules.d/audit_rules_networkconfig_modification.rules
      as the recipient for the rule
    ansible.builtin.set_fact:
      all_files:
      - /etc/audit/rules.d/audit_rules_networkconfig_modification.rules
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_watch_key.matched is defined and find_watch_key.matched == 0 and find_existing_watch_rules_d.matched
      is defined and find_existing_watch_rules_d.matched == 0
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_networkconfig_modification
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify the System's Network Environment - Use matched
      file as the recipient for the rule
    ansible.builtin.set_fact:
      all_files:
      - '{{ find_watch_key.files | map(attribute=''path'') | list | first }}'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_watch_key.matched is defined and find_watch_key.matched > 0 and find_existing_watch_rules_d.matched
      is defined and find_existing_watch_rules_d.matched == 0
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_networkconfig_modification
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify the System's Network Environment - Add watch rule
      for /etc/sysconfig/network in /etc/audit/rules.d/
    ansible.builtin.lineinfile:
      path: '{{ all_files[0] }}'
      line: -w /etc/sysconfig/network -p wa -k audit_rules_networkconfig_modification
      create: true
      mode: '0600'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
      == 0
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_networkconfig_modification
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify the System's Network Environment - Check if watch
      rule for /etc/sysconfig/network already exists in /etc/audit/audit.rules
    ansible.builtin.find:
      paths: /etc/audit/
      contains: ^\s*-w\s+/etc/sysconfig/network\s+-p\s+wa(\s|$)+
      patterns: audit.rules
    register: find_existing_watch_audit_rules
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_networkconfig_modification
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify the System's Network Environment - Add watch rule
      for /etc/sysconfig/network in /etc/audit/audit.rules
    ansible.builtin.lineinfile:
      line: -w /etc/sysconfig/network -p wa -k audit_rules_networkconfig_modification
      state: present
      dest: /etc/audit/audit.rules
      create: true
      mode: '0600'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched
      == 0
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_networkconfig_modification
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify the System's Network Environment - /etc/sysconfig/network-scripts
      - Check if watch rule for /etc/sysconfig/network-scripts already exists in /etc/audit/rules.d/
    ansible.builtin.find:
      paths: /etc/audit/rules.d
      contains: ^\s*-w\s+/etc/sysconfig/network-scripts\s+-p\s+wa(\s|$)+
      patterns: '*.rules'
    register: find_existing_watch_rules_d
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - audit_rules_networkconfig_modification_network_scripts
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify the System's Network Environment - /etc/sysconfig/network-scripts
      - Search /etc/audit/rules.d for other rules with specified key system-locale
    ansible.builtin.find:
      paths: /etc/audit/rules.d
      contains: ^.*(?:-F key=|-k\s+)system-locale$
      patterns: '*.rules'
    register: find_watch_key
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
      == 0
    tags:
    - audit_rules_networkconfig_modification_network_scripts
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify the System's Network Environment - /etc/sysconfig/network-scripts
      - Use /etc/audit/rules.d/system-locale.rules as the recipient for the rule
    ansible.builtin.set_fact:
      all_files:
      - /etc/audit/rules.d/system-locale.rules
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_watch_key.matched is defined and find_watch_key.matched == 0 and find_existing_watch_rules_d.matched
      is defined and find_existing_watch_rules_d.matched == 0
    tags:
    - audit_rules_networkconfig_modification_network_scripts
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify the System's Network Environment - /etc/sysconfig/network-scripts
      - Use matched file as the recipient for the rule
    ansible.builtin.set_fact:
      all_files:
      - '{{ find_watch_key.files | map(attribute=''path'') | list | first }}'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_watch_key.matched is defined and find_watch_key.matched > 0 and find_existing_watch_rules_d.matched
      is defined and find_existing_watch_rules_d.matched == 0
    tags:
    - audit_rules_networkconfig_modification_network_scripts
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify the System's Network Environment - /etc/sysconfig/network-scripts
      - Add watch rule for /etc/sysconfig/network-scripts in /etc/audit/rules.d/
    ansible.builtin.lineinfile:
      path: '{{ all_files[0] }}'
      line: -w /etc/sysconfig/network-scripts -p wa -k system-locale
      create: true
      mode: '0600'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
      == 0
    tags:
    - audit_rules_networkconfig_modification_network_scripts
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify the System's Network Environment - /etc/sysconfig/network-scripts
      - Check if watch rule for /etc/sysconfig/network-scripts already exists in /etc/audit/audit.rules
    ansible.builtin.find:
      paths: /etc/audit/
      contains: ^\s*-w\s+/etc/sysconfig/network-scripts\s+-p\s+wa(\s|$)+
      patterns: audit.rules
    register: find_existing_watch_audit_rules
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - audit_rules_networkconfig_modification_network_scripts
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify the System's Network Environment - /etc/sysconfig/network-scripts
      - Add watch rule for /etc/sysconfig/network-scripts in /etc/audit/audit.rules
    ansible.builtin.lineinfile:
      line: -w /etc/sysconfig/network-scripts -p wa -k system-locale
      state: present
      dest: /etc/audit/audit.rules
      create: true
      mode: '0600'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched
      == 0
    tags:
    - audit_rules_networkconfig_modification_network_scripts
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Attempts to Alter Process and Session Initiation Information btmp
      - Check if watch rule for /var/log/btmp already exists in /etc/audit/rules.d/
    ansible.builtin.find:
      paths: /etc/audit/rules.d
      contains: ^\s*-w\s+/var/log/btmp\s+-p\s+wa(\s|$)+
      patterns: '*.rules'
    register: find_existing_watch_rules_d
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-12.1(iv)
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.3
    - audit_rules_session_events_btmp
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Attempts to Alter Process and Session Initiation Information btmp
      - Search /etc/audit/rules.d for other rules with specified key session
    ansible.builtin.find:
      paths: /etc/audit/rules.d
      contains: ^.*(?:-F key=|-k\s+)session$
      patterns: '*.rules'
    register: find_watch_key
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
      == 0
    tags:
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-12.1(iv)
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.3
    - audit_rules_session_events_btmp
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Attempts to Alter Process and Session Initiation Information btmp
      - Use /etc/audit/rules.d/session.rules as the recipient for the rule
    ansible.builtin.set_fact:
      all_files:
      - /etc/audit/rules.d/session.rules
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_watch_key.matched is defined and find_watch_key.matched == 0 and find_existing_watch_rules_d.matched
      is defined and find_existing_watch_rules_d.matched == 0
    tags:
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-12.1(iv)
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.3
    - audit_rules_session_events_btmp
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Attempts to Alter Process and Session Initiation Information btmp
      - Use matched file as the recipient for the rule
    ansible.builtin.set_fact:
      all_files:
      - '{{ find_watch_key.files | map(attribute=''path'') | list | first }}'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_watch_key.matched is defined and find_watch_key.matched > 0 and find_existing_watch_rules_d.matched
      is defined and find_existing_watch_rules_d.matched == 0
    tags:
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-12.1(iv)
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.3
    - audit_rules_session_events_btmp
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Attempts to Alter Process and Session Initiation Information btmp
      - Add watch rule for /var/log/btmp in /etc/audit/rules.d/
    ansible.builtin.lineinfile:
      path: '{{ all_files[0] }}'
      line: -w /var/log/btmp -p wa -k session
      create: true
      mode: '0600'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
      == 0
    tags:
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-12.1(iv)
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.3
    - audit_rules_session_events_btmp
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Attempts to Alter Process and Session Initiation Information btmp
      - Check if watch rule for /var/log/btmp already exists in /etc/audit/audit.rules
    ansible.builtin.find:
      paths: /etc/audit/
      contains: ^\s*-w\s+/var/log/btmp\s+-p\s+wa(\s|$)+
      patterns: audit.rules
    register: find_existing_watch_audit_rules
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-12.1(iv)
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.3
    - audit_rules_session_events_btmp
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Attempts to Alter Process and Session Initiation Information btmp
      - Add watch rule for /var/log/btmp in /etc/audit/audit.rules
    ansible.builtin.lineinfile:
      line: -w /var/log/btmp -p wa -k session
      state: present
      dest: /etc/audit/audit.rules
      create: true
      mode: '0600'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched
      == 0
    tags:
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-12.1(iv)
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.3
    - audit_rules_session_events_btmp
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Attempts to Alter Process and Session Initiation Information utmp
      - Check if watch rule for /var/run/utmp already exists in /etc/audit/rules.d/
    ansible.builtin.find:
      paths: /etc/audit/rules.d
      contains: ^\s*-w\s+/var/run/utmp\s+-p\s+wa(\s|$)+
      patterns: '*.rules'
    register: find_existing_watch_rules_d
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-12.1(iv)
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.3
    - audit_rules_session_events_utmp
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Attempts to Alter Process and Session Initiation Information utmp
      - Search /etc/audit/rules.d for other rules with specified key session
    ansible.builtin.find:
      paths: /etc/audit/rules.d
      contains: ^.*(?:-F key=|-k\s+)session$
      patterns: '*.rules'
    register: find_watch_key
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
      == 0
    tags:
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-12.1(iv)
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.3
    - audit_rules_session_events_utmp
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Attempts to Alter Process and Session Initiation Information utmp
      - Use /etc/audit/rules.d/session.rules as the recipient for the rule
    ansible.builtin.set_fact:
      all_files:
      - /etc/audit/rules.d/session.rules
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_watch_key.matched is defined and find_watch_key.matched == 0 and find_existing_watch_rules_d.matched
      is defined and find_existing_watch_rules_d.matched == 0
    tags:
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-12.1(iv)
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.3
    - audit_rules_session_events_utmp
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Attempts to Alter Process and Session Initiation Information utmp
      - Use matched file as the recipient for the rule
    ansible.builtin.set_fact:
      all_files:
      - '{{ find_watch_key.files | map(attribute=''path'') | list | first }}'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_watch_key.matched is defined and find_watch_key.matched > 0 and find_existing_watch_rules_d.matched
      is defined and find_existing_watch_rules_d.matched == 0
    tags:
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-12.1(iv)
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.3
    - audit_rules_session_events_utmp
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Attempts to Alter Process and Session Initiation Information utmp
      - Add watch rule for /var/run/utmp in /etc/audit/rules.d/
    ansible.builtin.lineinfile:
      path: '{{ all_files[0] }}'
      line: -w /var/run/utmp -p wa -k session
      create: true
      mode: '0600'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
      == 0
    tags:
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-12.1(iv)
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.3
    - audit_rules_session_events_utmp
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Attempts to Alter Process and Session Initiation Information utmp
      - Check if watch rule for /var/run/utmp already exists in /etc/audit/audit.rules
    ansible.builtin.find:
      paths: /etc/audit/
      contains: ^\s*-w\s+/var/run/utmp\s+-p\s+wa(\s|$)+
      patterns: audit.rules
    register: find_existing_watch_audit_rules
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-12.1(iv)
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.3
    - audit_rules_session_events_utmp
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Attempts to Alter Process and Session Initiation Information utmp
      - Add watch rule for /var/run/utmp in /etc/audit/audit.rules
    ansible.builtin.lineinfile:
      line: -w /var/run/utmp -p wa -k session
      state: present
      dest: /etc/audit/audit.rules
      create: true
      mode: '0600'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched
      == 0
    tags:
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-12.1(iv)
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.3
    - audit_rules_session_events_utmp
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Attempts to Alter Process and Session Initiation Information wtmp
      - Check if watch rule for /var/log/wtmp already exists in /etc/audit/rules.d/
    ansible.builtin.find:
      paths: /etc/audit/rules.d
      contains: ^\s*-w\s+/var/log/wtmp\s+-p\s+wa(\s|$)+
      patterns: '*.rules'
    register: find_existing_watch_rules_d
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-12.1(iv)
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.3
    - audit_rules_session_events_wtmp
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Attempts to Alter Process and Session Initiation Information wtmp
      - Search /etc/audit/rules.d for other rules with specified key session
    ansible.builtin.find:
      paths: /etc/audit/rules.d
      contains: ^.*(?:-F key=|-k\s+)session$
      patterns: '*.rules'
    register: find_watch_key
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
      == 0
    tags:
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-12.1(iv)
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.3
    - audit_rules_session_events_wtmp
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Attempts to Alter Process and Session Initiation Information wtmp
      - Use /etc/audit/rules.d/session.rules as the recipient for the rule
    ansible.builtin.set_fact:
      all_files:
      - /etc/audit/rules.d/session.rules
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_watch_key.matched is defined and find_watch_key.matched == 0 and find_existing_watch_rules_d.matched
      is defined and find_existing_watch_rules_d.matched == 0
    tags:
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-12.1(iv)
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.3
    - audit_rules_session_events_wtmp
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Attempts to Alter Process and Session Initiation Information wtmp
      - Use matched file as the recipient for the rule
    ansible.builtin.set_fact:
      all_files:
      - '{{ find_watch_key.files | map(attribute=''path'') | list | first }}'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_watch_key.matched is defined and find_watch_key.matched > 0 and find_existing_watch_rules_d.matched
      is defined and find_existing_watch_rules_d.matched == 0
    tags:
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-12.1(iv)
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.3
    - audit_rules_session_events_wtmp
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Attempts to Alter Process and Session Initiation Information wtmp
      - Add watch rule for /var/log/wtmp in /etc/audit/rules.d/
    ansible.builtin.lineinfile:
      path: '{{ all_files[0] }}'
      line: -w /var/log/wtmp -p wa -k session
      create: true
      mode: '0600'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
      == 0
    tags:
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-12.1(iv)
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.3
    - audit_rules_session_events_wtmp
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Attempts to Alter Process and Session Initiation Information wtmp
      - Check if watch rule for /var/log/wtmp already exists in /etc/audit/audit.rules
    ansible.builtin.find:
      paths: /etc/audit/
      contains: ^\s*-w\s+/var/log/wtmp\s+-p\s+wa(\s|$)+
      patterns: audit.rules
    register: find_existing_watch_audit_rules
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-12.1(iv)
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.3
    - audit_rules_session_events_wtmp
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Attempts to Alter Process and Session Initiation Information wtmp
      - Add watch rule for /var/log/wtmp in /etc/audit/audit.rules
    ansible.builtin.lineinfile:
      line: -w /var/log/wtmp -p wa -k session
      state: present
      dest: /etc/audit/audit.rules
      create: true
      mode: '0600'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched
      == 0
    tags:
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-12.1(iv)
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.3
    - audit_rules_session_events_wtmp
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Check the rules script being used
    ansible.builtin.command: grep '^ExecStartPost' /usr/lib/systemd/system/auditd.service
    register: check_rules_scripts_result
    changed_when: false
    failed_when: false
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - audit_rules_suid_auid_privilege_function
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Set suid_audit_rules fact
    ansible.builtin.set_fact:
      suid_audit_rules:
      - rule: -a always,exit -F arch=b32 -S execve -C euid!=uid -F auid!=unset -k
          user_emulation
        regex: ^[\s]*-a[\s]+always,exit[\s]+-F[\s]+arch=b32[\s]+-C[\s]+euid!=uid[\s]+-F[\s]+auid!=unset[\s]+-S[\s]+execve[\s]+(?:-k[\s]+|-F[\s]+key=)[\S]+[\s]*$
      - rule: -a always,exit -F arch=b64 -S execve -C euid!=uid -F auid!=unset -k
          user_emulation
        regex: ^[\s]*-a[\s]+always,exit[\s]+-F[\s]+arch=b64[\s]+-C[\s]+euid!=uid[\s]+-F[\s]+auid!=unset[\s]+-S[\s]+execve[\s]+(?:-k[\s]+|-F[\s]+key=)[\S]+[\s]*$
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - audit_rules_suid_auid_privilege_function
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Update /etc/audit/rules.d/user_emulation.rules to audit privileged functions
    ansible.builtin.lineinfile:
      path: /etc/audit/rules.d/user_emulation.rules
      line: '{{  item.rule  }}'
      regexp: '{{ item.regex }}'
      create: true
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - '"auditd.service" in ansible_facts.services'
    - '"augenrules" in check_rules_scripts_result.stdout'
    register: augenrules_audit_rules_privilege_function_update_result
    with_items: '{{ suid_audit_rules }}'
    tags:
    - audit_rules_suid_auid_privilege_function
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Update Update /etc/audit/audit.rules to audit privileged functions
    ansible.builtin.lineinfile:
      path: /etc/audit/audit.rules
      line: '{{  item.rule  }}'
      regexp: '{{ item.regex }}'
      create: true
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - '"auditd.service" in ansible_facts.services'
    - '"auditctl" in check_rules_scripts_result.stdout'
    register: auditctl_audit_rules_privilege_function_update_result
    with_items: '{{ suid_audit_rules }}'
    tags:
    - audit_rules_suid_auid_privilege_function
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Restart Auditd
    ansible.builtin.command: /usr/sbin/service auditd restart
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - (augenrules_audit_rules_privilege_function_update_result.changed or auditctl_audit_rules_privilege_function_update_result.changed)
    - ("auditd.service" in ansible_facts.services and ansible_facts.services["auditd.service"].state
      == "running")
    tags:
    - audit_rules_suid_auid_privilege_function
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure auditd Collects System Administrator Actions - Check if watch rule
      for /etc/sudoers already exists in /etc/audit/audit.rules
    ansible.builtin.find:
      paths: /etc/audit/
      contains: ^\s*-w\s+/etc/sudoers\s+-p\s+wa(\s|$)+
      patterns: audit.rules
    register: find_existing_watch_audit_rules
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-2(7)(b)
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.2
    - PCI-DSS-Req-10.2.5.b
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.5
    - audit_rules_sysadmin_actions
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure auditd Collects System Administrator Actions - Add watch rule for
      /etc/sudoers in /etc/audit/audit.rules
    ansible.builtin.lineinfile:
      line: -w /etc/sudoers -p wa -k actions
      state: present
      dest: /etc/audit/audit.rules
      create: true
      mode: '0600'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched
      == 0
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-2(7)(b)
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.2
    - PCI-DSS-Req-10.2.5.b
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.5
    - audit_rules_sysadmin_actions
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure auditd Collects System Administrator Actions - Check if watch rule
      for /etc/sudoers already exists in /etc/audit/rules.d/
    ansible.builtin.find:
      paths: /etc/audit/rules.d
      contains: ^\s*-w\s+/etc/sudoers\s+-p\s+wa(\s|$)+
      patterns: '*.rules'
    register: find_existing_watch_rules_d
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-2(7)(b)
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.2
    - PCI-DSS-Req-10.2.5.b
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.5
    - audit_rules_sysadmin_actions
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure auditd Collects System Administrator Actions - Search /etc/audit/rules.d
      for other rules with specified key actions
    ansible.builtin.find:
      paths: /etc/audit/rules.d
      contains: ^.*(?:-F key=|-k\s+)actions$
      patterns: '*.rules'
    register: find_watch_key
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
      == 0
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-2(7)(b)
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.2
    - PCI-DSS-Req-10.2.5.b
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.5
    - audit_rules_sysadmin_actions
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure auditd Collects System Administrator Actions - Use /etc/audit/rules.d/actions.rules
      as the recipient for the rule
    ansible.builtin.set_fact:
      all_files:
      - /etc/audit/rules.d/actions.rules
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_watch_key.matched is defined and find_watch_key.matched == 0 and find_existing_watch_rules_d.matched
      is defined and find_existing_watch_rules_d.matched == 0
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-2(7)(b)
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.2
    - PCI-DSS-Req-10.2.5.b
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.5
    - audit_rules_sysadmin_actions
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure auditd Collects System Administrator Actions - Use matched file as
      the recipient for the rule
    ansible.builtin.set_fact:
      all_files:
      - '{{ find_watch_key.files | map(attribute=''path'') | list | first }}'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_watch_key.matched is defined and find_watch_key.matched > 0 and find_existing_watch_rules_d.matched
      is defined and find_existing_watch_rules_d.matched == 0
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-2(7)(b)
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.2
    - PCI-DSS-Req-10.2.5.b
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.5
    - audit_rules_sysadmin_actions
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure auditd Collects System Administrator Actions - Add watch rule for
      /etc/sudoers in /etc/audit/rules.d/
    ansible.builtin.lineinfile:
      path: '{{ all_files[0] }}'
      line: -w /etc/sudoers -p wa -k actions
      create: true
      mode: '0600'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
      == 0
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-2(7)(b)
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.2
    - PCI-DSS-Req-10.2.5.b
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.5
    - audit_rules_sysadmin_actions
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure auditd Collects System Administrator Actions - Check if watch rule
      for /etc/sudoers.d/ already exists in /etc/audit/audit.rules
    ansible.builtin.find:
      paths: /etc/audit/
      contains: ^\s*-w\s+/etc/sudoers.d/\s+-p\s+wa(\s|$)+
      patterns: audit.rules
    register: find_existing_watch_audit_rules
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-2(7)(b)
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.2
    - PCI-DSS-Req-10.2.5.b
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.5
    - audit_rules_sysadmin_actions
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure auditd Collects System Administrator Actions - Add watch rule for
      /etc/sudoers.d/ in /etc/audit/audit.rules
    ansible.builtin.lineinfile:
      line: -w /etc/sudoers.d/ -p wa -k actions
      state: present
      dest: /etc/audit/audit.rules
      create: true
      mode: '0600'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched
      == 0
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-2(7)(b)
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.2
    - PCI-DSS-Req-10.2.5.b
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.5
    - audit_rules_sysadmin_actions
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure auditd Collects System Administrator Actions - Check if watch rule
      for /etc/sudoers.d/ already exists in /etc/audit/rules.d/
    ansible.builtin.find:
      paths: /etc/audit/rules.d
      contains: ^\s*-w\s+/etc/sudoers.d/\s+-p\s+wa(\s|$)+
      patterns: '*.rules'
    register: find_existing_watch_rules_d
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-2(7)(b)
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.2
    - PCI-DSS-Req-10.2.5.b
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.5
    - audit_rules_sysadmin_actions
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure auditd Collects System Administrator Actions - Search /etc/audit/rules.d
      for other rules with specified key actions
    ansible.builtin.find:
      paths: /etc/audit/rules.d
      contains: ^.*(?:-F key=|-k\s+)actions$
      patterns: '*.rules'
    register: find_watch_key
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
      == 0
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-2(7)(b)
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.2
    - PCI-DSS-Req-10.2.5.b
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.5
    - audit_rules_sysadmin_actions
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure auditd Collects System Administrator Actions - Use /etc/audit/rules.d/actions.rules
      as the recipient for the rule
    ansible.builtin.set_fact:
      all_files:
      - /etc/audit/rules.d/actions.rules
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_watch_key.matched is defined and find_watch_key.matched == 0 and find_existing_watch_rules_d.matched
      is defined and find_existing_watch_rules_d.matched == 0
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-2(7)(b)
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.2
    - PCI-DSS-Req-10.2.5.b
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.5
    - audit_rules_sysadmin_actions
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure auditd Collects System Administrator Actions - Use matched file as
      the recipient for the rule
    ansible.builtin.set_fact:
      all_files:
      - '{{ find_watch_key.files | map(attribute=''path'') | list | first }}'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_watch_key.matched is defined and find_watch_key.matched > 0 and find_existing_watch_rules_d.matched
      is defined and find_existing_watch_rules_d.matched == 0
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-2(7)(b)
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.2
    - PCI-DSS-Req-10.2.5.b
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.5
    - audit_rules_sysadmin_actions
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure auditd Collects System Administrator Actions - Add watch rule for
      /etc/sudoers.d/ in /etc/audit/rules.d/
    ansible.builtin.lineinfile:
      path: '{{ all_files[0] }}'
      line: -w /etc/sudoers.d/ -p wa -k actions
      create: true
      mode: '0600'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
      == 0
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-2(7)(b)
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.2
    - PCI-DSS-Req-10.2.5.b
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.5
    - audit_rules_sysadmin_actions
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify User/Group Information - /etc/group - Check if
      watch rule for /etc/group already exists in /etc/audit/rules.d/
    ansible.builtin.find:
      paths: /etc/audit/rules.d
      contains: ^\s*-w\s+/etc/group\s+-p\s+wa(\s|$)+
      patterns: '*.rules'
    register: find_existing_watch_rules_d
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030170
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-2(4)
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.5
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.5
    - audit_rules_usergroup_modification_group
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify User/Group Information - /etc/group - Search /etc/audit/rules.d
      for other rules with specified key audit_rules_usergroup_modification
    ansible.builtin.find:
      paths: /etc/audit/rules.d
      contains: ^.*(?:-F key=|-k\s+)audit_rules_usergroup_modification$
      patterns: '*.rules'
    register: find_watch_key
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
      == 0
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030170
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-2(4)
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.5
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.5
    - audit_rules_usergroup_modification_group
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify User/Group Information - /etc/group - Use /etc/audit/rules.d/audit_rules_usergroup_modification.rules
      as the recipient for the rule
    ansible.builtin.set_fact:
      all_files:
      - /etc/audit/rules.d/audit_rules_usergroup_modification.rules
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_watch_key.matched is defined and find_watch_key.matched == 0 and find_existing_watch_rules_d.matched
      is defined and find_existing_watch_rules_d.matched == 0
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030170
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-2(4)
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.5
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.5
    - audit_rules_usergroup_modification_group
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify User/Group Information - /etc/group - Use matched
      file as the recipient for the rule
    ansible.builtin.set_fact:
      all_files:
      - '{{ find_watch_key.files | map(attribute=''path'') | list | first }}'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_watch_key.matched is defined and find_watch_key.matched > 0 and find_existing_watch_rules_d.matched
      is defined and find_existing_watch_rules_d.matched == 0
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030170
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-2(4)
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.5
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.5
    - audit_rules_usergroup_modification_group
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify User/Group Information - /etc/group - Add watch
      rule for /etc/group in /etc/audit/rules.d/
    ansible.builtin.lineinfile:
      path: '{{ all_files[0] }}'
      line: -w /etc/group -p wa -k audit_rules_usergroup_modification
      create: true
      mode: '0600'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
      == 0
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030170
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-2(4)
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.5
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.5
    - audit_rules_usergroup_modification_group
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify User/Group Information - /etc/group - Check if
      watch rule for /etc/group already exists in /etc/audit/audit.rules
    ansible.builtin.find:
      paths: /etc/audit/
      contains: ^\s*-w\s+/etc/group\s+-p\s+wa(\s|$)+
      patterns: audit.rules
    register: find_existing_watch_audit_rules
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030170
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-2(4)
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.5
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.5
    - audit_rules_usergroup_modification_group
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify User/Group Information - /etc/group - Add watch
      rule for /etc/group in /etc/audit/audit.rules
    ansible.builtin.lineinfile:
      line: -w /etc/group -p wa -k audit_rules_usergroup_modification
      state: present
      dest: /etc/audit/audit.rules
      create: true
      mode: '0600'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched
      == 0
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030170
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-2(4)
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.5
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.5
    - audit_rules_usergroup_modification_group
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify User/Group Information - /etc/gshadow - Check
      if watch rule for /etc/gshadow already exists in /etc/audit/rules.d/
    ansible.builtin.find:
      paths: /etc/audit/rules.d
      contains: ^\s*-w\s+/etc/gshadow\s+-p\s+wa(\s|$)+
      patterns: '*.rules'
    register: find_existing_watch_rules_d
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030160
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-2(4)
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.5
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.5
    - audit_rules_usergroup_modification_gshadow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify User/Group Information - /etc/gshadow - Search
      /etc/audit/rules.d for other rules with specified key audit_rules_usergroup_modification
    ansible.builtin.find:
      paths: /etc/audit/rules.d
      contains: ^.*(?:-F key=|-k\s+)audit_rules_usergroup_modification$
      patterns: '*.rules'
    register: find_watch_key
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
      == 0
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030160
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-2(4)
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.5
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.5
    - audit_rules_usergroup_modification_gshadow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify User/Group Information - /etc/gshadow - Use /etc/audit/rules.d/audit_rules_usergroup_modification.rules
      as the recipient for the rule
    ansible.builtin.set_fact:
      all_files:
      - /etc/audit/rules.d/audit_rules_usergroup_modification.rules
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_watch_key.matched is defined and find_watch_key.matched == 0 and find_existing_watch_rules_d.matched
      is defined and find_existing_watch_rules_d.matched == 0
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030160
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-2(4)
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.5
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.5
    - audit_rules_usergroup_modification_gshadow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify User/Group Information - /etc/gshadow - Use matched
      file as the recipient for the rule
    ansible.builtin.set_fact:
      all_files:
      - '{{ find_watch_key.files | map(attribute=''path'') | list | first }}'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_watch_key.matched is defined and find_watch_key.matched > 0 and find_existing_watch_rules_d.matched
      is defined and find_existing_watch_rules_d.matched == 0
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030160
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-2(4)
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.5
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.5
    - audit_rules_usergroup_modification_gshadow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify User/Group Information - /etc/gshadow - Add watch
      rule for /etc/gshadow in /etc/audit/rules.d/
    ansible.builtin.lineinfile:
      path: '{{ all_files[0] }}'
      line: -w /etc/gshadow -p wa -k audit_rules_usergroup_modification
      create: true
      mode: '0600'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
      == 0
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030160
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-2(4)
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.5
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.5
    - audit_rules_usergroup_modification_gshadow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify User/Group Information - /etc/gshadow - Check
      if watch rule for /etc/gshadow already exists in /etc/audit/audit.rules
    ansible.builtin.find:
      paths: /etc/audit/
      contains: ^\s*-w\s+/etc/gshadow\s+-p\s+wa(\s|$)+
      patterns: audit.rules
    register: find_existing_watch_audit_rules
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030160
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-2(4)
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.5
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.5
    - audit_rules_usergroup_modification_gshadow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify User/Group Information - /etc/gshadow - Add watch
      rule for /etc/gshadow in /etc/audit/audit.rules
    ansible.builtin.lineinfile:
      line: -w /etc/gshadow -p wa -k audit_rules_usergroup_modification
      state: present
      dest: /etc/audit/audit.rules
      create: true
      mode: '0600'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched
      == 0
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030160
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-2(4)
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.5
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.5
    - audit_rules_usergroup_modification_gshadow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify User/Group Information - /etc/nsswitch.conf -
      Check if watch rule for /etc/nsswitch.conf already exists in /etc/audit/rules.d/
    ansible.builtin.find:
      paths: /etc/audit/rules.d
      contains: ^\s*-w\s+/etc/nsswitch.conf\s+-p\s+wa(\s|$)+
      patterns: '*.rules'
    register: find_existing_watch_rules_d
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - audit_rules_usergroup_modification_nsswitch_conf
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify User/Group Information - /etc/nsswitch.conf -
      Search /etc/audit/rules.d for other rules with specified key audit_rules_usergroup_modification
    ansible.builtin.find:
      paths: /etc/audit/rules.d
      contains: ^.*(?:-F key=|-k\s+)audit_rules_usergroup_modification$
      patterns: '*.rules'
    register: find_watch_key
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
      == 0
    tags:
    - audit_rules_usergroup_modification_nsswitch_conf
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify User/Group Information - /etc/nsswitch.conf -
      Use /etc/audit/rules.d/audit_rules_usergroup_modification.rules as the recipient
      for the rule
    ansible.builtin.set_fact:
      all_files:
      - /etc/audit/rules.d/audit_rules_usergroup_modification.rules
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_watch_key.matched is defined and find_watch_key.matched == 0 and find_existing_watch_rules_d.matched
      is defined and find_existing_watch_rules_d.matched == 0
    tags:
    - audit_rules_usergroup_modification_nsswitch_conf
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify User/Group Information - /etc/nsswitch.conf -
      Use matched file as the recipient for the rule
    ansible.builtin.set_fact:
      all_files:
      - '{{ find_watch_key.files | map(attribute=''path'') | list | first }}'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_watch_key.matched is defined and find_watch_key.matched > 0 and find_existing_watch_rules_d.matched
      is defined and find_existing_watch_rules_d.matched == 0
    tags:
    - audit_rules_usergroup_modification_nsswitch_conf
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify User/Group Information - /etc/nsswitch.conf -
      Add watch rule for /etc/nsswitch.conf in /etc/audit/rules.d/
    ansible.builtin.lineinfile:
      path: '{{ all_files[0] }}'
      line: -w /etc/nsswitch.conf -p wa -k audit_rules_usergroup_modification
      create: true
      mode: '0600'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
      == 0
    tags:
    - audit_rules_usergroup_modification_nsswitch_conf
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify User/Group Information - /etc/nsswitch.conf -
      Check if watch rule for /etc/nsswitch.conf already exists in /etc/audit/audit.rules
    ansible.builtin.find:
      paths: /etc/audit/
      contains: ^\s*-w\s+/etc/nsswitch.conf\s+-p\s+wa(\s|$)+
      patterns: audit.rules
    register: find_existing_watch_audit_rules
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - audit_rules_usergroup_modification_nsswitch_conf
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify User/Group Information - /etc/nsswitch.conf -
      Add watch rule for /etc/nsswitch.conf in /etc/audit/audit.rules
    ansible.builtin.lineinfile:
      line: -w /etc/nsswitch.conf -p wa -k audit_rules_usergroup_modification
      state: present
      dest: /etc/audit/audit.rules
      create: true
      mode: '0600'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched
      == 0
    tags:
    - audit_rules_usergroup_modification_nsswitch_conf
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify User/Group Information - /etc/security/opasswd
      - Check if watch rule for /etc/security/opasswd already exists in /etc/audit/rules.d/
    ansible.builtin.find:
      paths: /etc/audit/rules.d
      contains: ^\s*-w\s+/etc/security/opasswd\s+-p\s+wa(\s|$)+
      patterns: '*.rules'
    register: find_existing_watch_rules_d
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030140
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-2(4)
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.5
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.5
    - audit_rules_usergroup_modification_opasswd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify User/Group Information - /etc/security/opasswd
      - Search /etc/audit/rules.d for other rules with specified key audit_rules_usergroup_modification
    ansible.builtin.find:
      paths: /etc/audit/rules.d
      contains: ^.*(?:-F key=|-k\s+)audit_rules_usergroup_modification$
      patterns: '*.rules'
    register: find_watch_key
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
      == 0
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030140
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-2(4)
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.5
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.5
    - audit_rules_usergroup_modification_opasswd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify User/Group Information - /etc/security/opasswd
      - Use /etc/audit/rules.d/audit_rules_usergroup_modification.rules as the recipient
      for the rule
    ansible.builtin.set_fact:
      all_files:
      - /etc/audit/rules.d/audit_rules_usergroup_modification.rules
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_watch_key.matched is defined and find_watch_key.matched == 0 and find_existing_watch_rules_d.matched
      is defined and find_existing_watch_rules_d.matched == 0
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030140
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-2(4)
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.5
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.5
    - audit_rules_usergroup_modification_opasswd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify User/Group Information - /etc/security/opasswd
      - Use matched file as the recipient for the rule
    ansible.builtin.set_fact:
      all_files:
      - '{{ find_watch_key.files | map(attribute=''path'') | list | first }}'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_watch_key.matched is defined and find_watch_key.matched > 0 and find_existing_watch_rules_d.matched
      is defined and find_existing_watch_rules_d.matched == 0
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030140
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-2(4)
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.5
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.5
    - audit_rules_usergroup_modification_opasswd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify User/Group Information - /etc/security/opasswd
      - Add watch rule for /etc/security/opasswd in /etc/audit/rules.d/
    ansible.builtin.lineinfile:
      path: '{{ all_files[0] }}'
      line: -w /etc/security/opasswd -p wa -k audit_rules_usergroup_modification
      create: true
      mode: '0600'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
      == 0
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030140
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-2(4)
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.5
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.5
    - audit_rules_usergroup_modification_opasswd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify User/Group Information - /etc/security/opasswd
      - Check if watch rule for /etc/security/opasswd already exists in /etc/audit/audit.rules
    ansible.builtin.find:
      paths: /etc/audit/
      contains: ^\s*-w\s+/etc/security/opasswd\s+-p\s+wa(\s|$)+
      patterns: audit.rules
    register: find_existing_watch_audit_rules
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030140
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-2(4)
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.5
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.5
    - audit_rules_usergroup_modification_opasswd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify User/Group Information - /etc/security/opasswd
      - Add watch rule for /etc/security/opasswd in /etc/audit/audit.rules
    ansible.builtin.lineinfile:
      line: -w /etc/security/opasswd -p wa -k audit_rules_usergroup_modification
      state: present
      dest: /etc/audit/audit.rules
      create: true
      mode: '0600'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched
      == 0
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030140
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-2(4)
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.5
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.5
    - audit_rules_usergroup_modification_opasswd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify User/Group Information - /etc/pam.conf - Check
      if watch rule for /etc/pam.conf already exists in /etc/audit/rules.d/
    ansible.builtin.find:
      paths: /etc/audit/rules.d
      contains: ^\s*-w\s+/etc/pam.conf\s+-p\s+wa(\s|$)+
      patterns: '*.rules'
    register: find_existing_watch_rules_d
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - audit_rules_usergroup_modification_pam_conf
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify User/Group Information - /etc/pam.conf - Search
      /etc/audit/rules.d for other rules with specified key audit_rules_usergroup_modification
    ansible.builtin.find:
      paths: /etc/audit/rules.d
      contains: ^.*(?:-F key=|-k\s+)audit_rules_usergroup_modification$
      patterns: '*.rules'
    register: find_watch_key
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
      == 0
    tags:
    - audit_rules_usergroup_modification_pam_conf
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify User/Group Information - /etc/pam.conf - Use /etc/audit/rules.d/audit_rules_usergroup_modification.rules
      as the recipient for the rule
    ansible.builtin.set_fact:
      all_files:
      - /etc/audit/rules.d/audit_rules_usergroup_modification.rules
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_watch_key.matched is defined and find_watch_key.matched == 0 and find_existing_watch_rules_d.matched
      is defined and find_existing_watch_rules_d.matched == 0
    tags:
    - audit_rules_usergroup_modification_pam_conf
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify User/Group Information - /etc/pam.conf - Use matched
      file as the recipient for the rule
    ansible.builtin.set_fact:
      all_files:
      - '{{ find_watch_key.files | map(attribute=''path'') | list | first }}'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_watch_key.matched is defined and find_watch_key.matched > 0 and find_existing_watch_rules_d.matched
      is defined and find_existing_watch_rules_d.matched == 0
    tags:
    - audit_rules_usergroup_modification_pam_conf
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify User/Group Information - /etc/pam.conf - Add watch
      rule for /etc/pam.conf in /etc/audit/rules.d/
    ansible.builtin.lineinfile:
      path: '{{ all_files[0] }}'
      line: -w /etc/pam.conf -p wa -k audit_rules_usergroup_modification
      create: true
      mode: '0600'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
      == 0
    tags:
    - audit_rules_usergroup_modification_pam_conf
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify User/Group Information - /etc/pam.conf - Check
      if watch rule for /etc/pam.conf already exists in /etc/audit/audit.rules
    ansible.builtin.find:
      paths: /etc/audit/
      contains: ^\s*-w\s+/etc/pam.conf\s+-p\s+wa(\s|$)+
      patterns: audit.rules
    register: find_existing_watch_audit_rules
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - audit_rules_usergroup_modification_pam_conf
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify User/Group Information - /etc/pam.conf - Add watch
      rule for /etc/pam.conf in /etc/audit/audit.rules
    ansible.builtin.lineinfile:
      line: -w /etc/pam.conf -p wa -k audit_rules_usergroup_modification
      state: present
      dest: /etc/audit/audit.rules
      create: true
      mode: '0600'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched
      == 0
    tags:
    - audit_rules_usergroup_modification_pam_conf
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify User/Group Information - /etc/pam.d/ - Check if
      watch rule for /etc/pam.d/ already exists in /etc/audit/rules.d/
    ansible.builtin.find:
      paths: /etc/audit/rules.d
      contains: ^\s*-w\s+/etc/pam.d/\s+-p\s+wa(\s|$)+
      patterns: '*.rules'
    register: find_existing_watch_rules_d
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - audit_rules_usergroup_modification_pamd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify User/Group Information - /etc/pam.d/ - Search
      /etc/audit/rules.d for other rules with specified key audit_rules_usergroup_modification
    ansible.builtin.find:
      paths: /etc/audit/rules.d
      contains: ^.*(?:-F key=|-k\s+)audit_rules_usergroup_modification$
      patterns: '*.rules'
    register: find_watch_key
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
      == 0
    tags:
    - audit_rules_usergroup_modification_pamd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify User/Group Information - /etc/pam.d/ - Use /etc/audit/rules.d/audit_rules_usergroup_modification.rules
      as the recipient for the rule
    ansible.builtin.set_fact:
      all_files:
      - /etc/audit/rules.d/audit_rules_usergroup_modification.rules
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_watch_key.matched is defined and find_watch_key.matched == 0 and find_existing_watch_rules_d.matched
      is defined and find_existing_watch_rules_d.matched == 0
    tags:
    - audit_rules_usergroup_modification_pamd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify User/Group Information - /etc/pam.d/ - Use matched
      file as the recipient for the rule
    ansible.builtin.set_fact:
      all_files:
      - '{{ find_watch_key.files | map(attribute=''path'') | list | first }}'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_watch_key.matched is defined and find_watch_key.matched > 0 and find_existing_watch_rules_d.matched
      is defined and find_existing_watch_rules_d.matched == 0
    tags:
    - audit_rules_usergroup_modification_pamd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify User/Group Information - /etc/pam.d/ - Add watch
      rule for /etc/pam.d/ in /etc/audit/rules.d/
    ansible.builtin.lineinfile:
      path: '{{ all_files[0] }}'
      line: -w /etc/pam.d/ -p wa -k audit_rules_usergroup_modification
      create: true
      mode: '0600'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
      == 0
    tags:
    - audit_rules_usergroup_modification_pamd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify User/Group Information - /etc/pam.d/ - Check if
      watch rule for /etc/pam.d/ already exists in /etc/audit/audit.rules
    ansible.builtin.find:
      paths: /etc/audit/
      contains: ^\s*-w\s+/etc/pam.d/\s+-p\s+wa(\s|$)+
      patterns: audit.rules
    register: find_existing_watch_audit_rules
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - audit_rules_usergroup_modification_pamd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify User/Group Information - /etc/pam.d/ - Add watch
      rule for /etc/pam.d/ in /etc/audit/audit.rules
    ansible.builtin.lineinfile:
      line: -w /etc/pam.d/ -p wa -k audit_rules_usergroup_modification
      state: present
      dest: /etc/audit/audit.rules
      create: true
      mode: '0600'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched
      == 0
    tags:
    - audit_rules_usergroup_modification_pamd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify User/Group Information - /etc/passwd - Check if
      watch rule for /etc/passwd already exists in /etc/audit/rules.d/
    ansible.builtin.find:
      paths: /etc/audit/rules.d
      contains: ^\s*-w\s+/etc/passwd\s+-p\s+wa(\s|$)+
      patterns: '*.rules'
    register: find_existing_watch_rules_d
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030150
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-2(4)
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.5
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.5
    - audit_rules_usergroup_modification_passwd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify User/Group Information - /etc/passwd - Search
      /etc/audit/rules.d for other rules with specified key audit_rules_usergroup_modification
    ansible.builtin.find:
      paths: /etc/audit/rules.d
      contains: ^.*(?:-F key=|-k\s+)audit_rules_usergroup_modification$
      patterns: '*.rules'
    register: find_watch_key
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
      == 0
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030150
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-2(4)
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.5
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.5
    - audit_rules_usergroup_modification_passwd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify User/Group Information - /etc/passwd - Use /etc/audit/rules.d/audit_rules_usergroup_modification.rules
      as the recipient for the rule
    ansible.builtin.set_fact:
      all_files:
      - /etc/audit/rules.d/audit_rules_usergroup_modification.rules
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_watch_key.matched is defined and find_watch_key.matched == 0 and find_existing_watch_rules_d.matched
      is defined and find_existing_watch_rules_d.matched == 0
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030150
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-2(4)
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.5
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.5
    - audit_rules_usergroup_modification_passwd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify User/Group Information - /etc/passwd - Use matched
      file as the recipient for the rule
    ansible.builtin.set_fact:
      all_files:
      - '{{ find_watch_key.files | map(attribute=''path'') | list | first }}'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_watch_key.matched is defined and find_watch_key.matched > 0 and find_existing_watch_rules_d.matched
      is defined and find_existing_watch_rules_d.matched == 0
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030150
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-2(4)
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.5
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.5
    - audit_rules_usergroup_modification_passwd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify User/Group Information - /etc/passwd - Add watch
      rule for /etc/passwd in /etc/audit/rules.d/
    ansible.builtin.lineinfile:
      path: '{{ all_files[0] }}'
      line: -w /etc/passwd -p wa -k audit_rules_usergroup_modification
      create: true
      mode: '0600'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
      == 0
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030150
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-2(4)
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.5
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.5
    - audit_rules_usergroup_modification_passwd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify User/Group Information - /etc/passwd - Check if
      watch rule for /etc/passwd already exists in /etc/audit/audit.rules
    ansible.builtin.find:
      paths: /etc/audit/
      contains: ^\s*-w\s+/etc/passwd\s+-p\s+wa(\s|$)+
      patterns: audit.rules
    register: find_existing_watch_audit_rules
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030150
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-2(4)
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.5
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.5
    - audit_rules_usergroup_modification_passwd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify User/Group Information - /etc/passwd - Add watch
      rule for /etc/passwd in /etc/audit/audit.rules
    ansible.builtin.lineinfile:
      line: -w /etc/passwd -p wa -k audit_rules_usergroup_modification
      state: present
      dest: /etc/audit/audit.rules
      create: true
      mode: '0600'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched
      == 0
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030150
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-2(4)
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.5
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.5
    - audit_rules_usergroup_modification_passwd
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify User/Group Information - /etc/shadow - Check if
      watch rule for /etc/shadow already exists in /etc/audit/rules.d/
    ansible.builtin.find:
      paths: /etc/audit/rules.d
      contains: ^\s*-w\s+/etc/shadow\s+-p\s+wa(\s|$)+
      patterns: '*.rules'
    register: find_existing_watch_rules_d
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030130
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-2(4)
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.5
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.5
    - audit_rules_usergroup_modification_shadow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify User/Group Information - /etc/shadow - Search
      /etc/audit/rules.d for other rules with specified key audit_rules_usergroup_modification
    ansible.builtin.find:
      paths: /etc/audit/rules.d
      contains: ^.*(?:-F key=|-k\s+)audit_rules_usergroup_modification$
      patterns: '*.rules'
    register: find_watch_key
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
      == 0
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030130
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-2(4)
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.5
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.5
    - audit_rules_usergroup_modification_shadow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify User/Group Information - /etc/shadow - Use /etc/audit/rules.d/audit_rules_usergroup_modification.rules
      as the recipient for the rule
    ansible.builtin.set_fact:
      all_files:
      - /etc/audit/rules.d/audit_rules_usergroup_modification.rules
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_watch_key.matched is defined and find_watch_key.matched == 0 and find_existing_watch_rules_d.matched
      is defined and find_existing_watch_rules_d.matched == 0
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030130
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-2(4)
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.5
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.5
    - audit_rules_usergroup_modification_shadow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify User/Group Information - /etc/shadow - Use matched
      file as the recipient for the rule
    ansible.builtin.set_fact:
      all_files:
      - '{{ find_watch_key.files | map(attribute=''path'') | list | first }}'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_watch_key.matched is defined and find_watch_key.matched > 0 and find_existing_watch_rules_d.matched
      is defined and find_existing_watch_rules_d.matched == 0
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030130
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-2(4)
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.5
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.5
    - audit_rules_usergroup_modification_shadow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify User/Group Information - /etc/shadow - Add watch
      rule for /etc/shadow in /etc/audit/rules.d/
    ansible.builtin.lineinfile:
      path: '{{ all_files[0] }}'
      line: -w /etc/shadow -p wa -k audit_rules_usergroup_modification
      create: true
      mode: '0600'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
      == 0
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030130
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-2(4)
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.5
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.5
    - audit_rules_usergroup_modification_shadow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify User/Group Information - /etc/shadow - Check if
      watch rule for /etc/shadow already exists in /etc/audit/audit.rules
    ansible.builtin.find:
      paths: /etc/audit/
      contains: ^\s*-w\s+/etc/shadow\s+-p\s+wa(\s|$)+
      patterns: audit.rules
    register: find_existing_watch_audit_rules
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030130
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-2(4)
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.5
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.5
    - audit_rules_usergroup_modification_shadow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Events that Modify User/Group Information - /etc/shadow - Add watch
      rule for /etc/shadow in /etc/audit/audit.rules
    ansible.builtin.lineinfile:
      line: -w /etc/shadow -p wa -k audit_rules_usergroup_modification
      state: present
      dest: /etc/audit/audit.rules
      create: true
      mode: '0600'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched
      == 0
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030130
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-2(4)
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.5
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.5
    - audit_rules_usergroup_modification_shadow
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Attempts to perform maintenance activities - Check if watch rule
      for /var/log/sudo.log already exists in /etc/audit/rules.d/
    ansible.builtin.find:
      paths: /etc/audit/rules.d
      contains: ^\s*-w\s+/var/log/sudo.log\s+-p\s+wa(\s|$)+
      patterns: '*.rules'
    register: find_existing_watch_rules_d
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - PCI-DSS-Req-10.2.2
    - PCI-DSS-Req-10.2.5.b
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.3
    - audit_sudo_log_events
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Attempts to perform maintenance activities - Search /etc/audit/rules.d
      for other rules with specified key maintenance
    ansible.builtin.find:
      paths: /etc/audit/rules.d
      contains: ^.*(?:-F key=|-k\s+)maintenance$
      patterns: '*.rules'
    register: find_watch_key
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
      == 0
    tags:
    - PCI-DSS-Req-10.2.2
    - PCI-DSS-Req-10.2.5.b
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.3
    - audit_sudo_log_events
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Attempts to perform maintenance activities - Use /etc/audit/rules.d/maintenance.rules
      as the recipient for the rule
    ansible.builtin.set_fact:
      all_files:
      - /etc/audit/rules.d/maintenance.rules
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_watch_key.matched is defined and find_watch_key.matched == 0 and find_existing_watch_rules_d.matched
      is defined and find_existing_watch_rules_d.matched == 0
    tags:
    - PCI-DSS-Req-10.2.2
    - PCI-DSS-Req-10.2.5.b
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.3
    - audit_sudo_log_events
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Attempts to perform maintenance activities - Use matched file as
      the recipient for the rule
    ansible.builtin.set_fact:
      all_files:
      - '{{ find_watch_key.files | map(attribute=''path'') | list | first }}'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_watch_key.matched is defined and find_watch_key.matched > 0 and find_existing_watch_rules_d.matched
      is defined and find_existing_watch_rules_d.matched == 0
    tags:
    - PCI-DSS-Req-10.2.2
    - PCI-DSS-Req-10.2.5.b
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.3
    - audit_sudo_log_events
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Attempts to perform maintenance activities - Add watch rule for /var/log/sudo.log
      in /etc/audit/rules.d/
    ansible.builtin.lineinfile:
      path: '{{ all_files[0] }}'
      line: -w /var/log/sudo.log -p wa -k maintenance
      create: true
      mode: '0600'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
      == 0
    tags:
    - PCI-DSS-Req-10.2.2
    - PCI-DSS-Req-10.2.5.b
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.3
    - audit_sudo_log_events
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Attempts to perform maintenance activities - Check if watch rule
      for /var/log/sudo.log already exists in /etc/audit/audit.rules
    ansible.builtin.find:
      paths: /etc/audit/
      contains: ^\s*-w\s+/var/log/sudo.log\s+-p\s+wa(\s|$)+
      patterns: audit.rules
    register: find_existing_watch_audit_rules
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - PCI-DSS-Req-10.2.2
    - PCI-DSS-Req-10.2.5.b
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.3
    - audit_sudo_log_events
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Attempts to perform maintenance activities - Add watch rule for /var/log/sudo.log
      in /etc/audit/audit.rules
    ansible.builtin.lineinfile:
      line: -w /var/log/sudo.log -p wa -k maintenance
      state: present
      dest: /etc/audit/audit.rules
      create: true
      mode: '0600'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched
      == 0
    tags:
    - PCI-DSS-Req-10.2.2
    - PCI-DSS-Req-10.2.5.b
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.3
    - audit_sudo_log_events
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: System Audit Logs Must Have Mode 0750 or Less Permissive - Get audit log
      file from /etc/audit/auditd.conf
    ansible.builtin.command: grep -iw ^log_file /etc/audit/auditd.conf
    check_mode: false
    failed_when: false
    changed_when: false
    register: log_file_exists
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-030120
    - NIST-800-53-AC-6(1)
    - NIST-800-53-AU-9
    - NIST-800-53-CM-6(a)
    - directory_permissions_var_log_audit
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: System Audit Logs Must Have Mode 0750 or Less Permissive - Set audit log
      directory path
    ansible.builtin.set_fact:
      log_file_dir: '{{ (log_file_exists.stdout | default('''') | split('' '') | last
        | dirname) | default(''/var/log/audit'', true) }}'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-030120
    - NIST-800-53-AC-6(1)
    - NIST-800-53-AU-9
    - NIST-800-53-CM-6(a)
    - directory_permissions_var_log_audit
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: System Audit Logs Must Have Mode 0750 or Less Permissive - Get audit log
      group from /etc/audit/auditd.conf
    ansible.builtin.command: grep -iw ^log_group /etc/audit/auditd.conf
    check_mode: false
    failed_when: false
    changed_when: false
    register: log_group_exists
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-030120
    - NIST-800-53-AC-6(1)
    - NIST-800-53-AU-9
    - NIST-800-53-CM-6(a)
    - directory_permissions_var_log_audit
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: System Audit Logs Must Have Mode 0750 or Less Permissive - Set audit log
      group
    ansible.builtin.set_fact:
      log_group: '{{ (log_group_exists.stdout | default('''') | split('' '') | last)
        | default(''root'', true) }}'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-030120
    - NIST-800-53-AC-6(1)
    - NIST-800-53-AU-9
    - NIST-800-53-CM-6(a)
    - directory_permissions_var_log_audit
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: System Audit Logs Must Have Mode 0750 or Less Permissive - Set audit log
      directory permissions
    ansible.builtin.file:
      path: '{{ log_file_dir }}'
      state: directory
      mode: '{{ ''0700'' if log_group == ''root'' else ''0750'' }}'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-030120
    - NIST-800-53-AC-6(1)
    - NIST-800-53-AU-9
    - NIST-800-53-CM-6(a)
    - directory_permissions_var_log_audit
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Set the file_groupownership_audit_configuration_newgroup variable if represented
      by gid
    ansible.builtin.set_fact:
      file_groupownership_audit_configuration_newgroup: '0'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - configure_strategy
    - file_groupownership_audit_configuration
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Find /etc/audit/ file(s) matching ^.*audit(\.rules|d\.conf)$
    ansible.builtin.command: find -P /etc/audit/ -maxdepth 1 -type f  ! -group 0 -regextype
      posix-extended -regex "^.*audit(\.rules|d\.conf)$"
    register: files_found
    changed_when: false
    failed_when: false
    check_mode: false
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - configure_strategy
    - file_groupownership_audit_configuration
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure group owner on /etc/audit/ file(s) matching ^.*audit(\.rules|d\.conf)$
    ansible.builtin.file:
      path: '{{ item }}'
      follow: false
      group: '{{ file_groupownership_audit_configuration_newgroup }}'
      state: file
    with_items:
    - '{{ files_found.stdout_lines }}'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - configure_strategy
    - file_groupownership_audit_configuration
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Find /etc/audit/rules.d/ file(s) matching ^.*\.rules$
    ansible.builtin.command: find -P /etc/audit/rules.d/ -maxdepth 1 -type f  ! -group
      0 -regextype posix-extended -regex "^.*\.rules$"
    register: files_found
    changed_when: false
    failed_when: false
    check_mode: false
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - configure_strategy
    - file_groupownership_audit_configuration
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure group owner on /etc/audit/rules.d/ file(s) matching ^.*\.rules$
    ansible.builtin.file:
      path: '{{ item }}'
      follow: false
      group: '{{ file_groupownership_audit_configuration_newgroup }}'
      state: file
    with_items:
    - '{{ files_found.stdout_lines }}'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - configure_strategy
    - file_groupownership_audit_configuration
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set the file_ownership_audit_configuration_newown variable if represented
      by uid
    ansible.builtin.set_fact:
      file_ownership_audit_configuration_newown: '0'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - configure_strategy
    - file_ownership_audit_configuration
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Find /etc/audit/ file(s) matching ^.*audit(\.rules|d\.conf)$
    ansible.builtin.command: find -P /etc/audit/ -maxdepth 1 -type f  ! -user 0 -regextype
      posix-extended -regex "^.*audit(\.rules|d\.conf)$"
    register: files_found
    changed_when: false
    failed_when: false
    check_mode: false
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - configure_strategy
    - file_ownership_audit_configuration
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure owner on /etc/audit/ file(s) matching ^.*audit(\.rules|d\.conf)$
    ansible.builtin.file:
      path: '{{ item }}'
      follow: false
      owner: '{{ file_ownership_audit_configuration_newown }}'
      state: file
    with_items:
    - '{{ files_found.stdout_lines }}'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - configure_strategy
    - file_ownership_audit_configuration
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Find /etc/audit/rules.d/ file(s) matching ^.*\.rules$
    ansible.builtin.command: find -P /etc/audit/rules.d/ -maxdepth 1 -type f  ! -user
      0 -regextype posix-extended -regex "^.*\.rules$"
    register: files_found
    changed_when: false
    failed_when: false
    check_mode: false
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - configure_strategy
    - file_ownership_audit_configuration
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure owner on /etc/audit/rules.d/ file(s) matching ^.*\.rules$
    ansible.builtin.file:
      path: '{{ item }}'
      follow: false
      owner: '{{ file_ownership_audit_configuration_newown }}'
      state: file
    with_items:
    - '{{ files_found.stdout_lines }}'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - configure_strategy
    - file_ownership_audit_configuration
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Find /etc/audit/ file(s)
    ansible.builtin.command: find -P /etc/audit/ -maxdepth 1 -perm /u+xs,g+xws,o+xwrt  -type
      f -regextype posix-extended -regex "^.*audit(\.rules|d\.conf)$"
    register: files_found
    changed_when: false
    failed_when: false
    check_mode: false
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AU-12 b
    - configure_strategy
    - file_permissions_audit_configuration
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set permissions for /etc/audit/ file(s)
    ansible.builtin.file:
      path: '{{ item }}'
      mode: u-xs,g-xws,o-xwrt
      state: file
    with_items:
    - '{{ files_found.stdout_lines }}'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AU-12 b
    - configure_strategy
    - file_permissions_audit_configuration
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Find /etc/audit/rules.d/ file(s)
    ansible.builtin.command: find -P /etc/audit/rules.d/ -maxdepth 1 -perm /u+xs,g+xws,o+xwrt  -type
      f -regextype posix-extended -regex "^.*\.rules$"
    register: files_found
    changed_when: false
    failed_when: false
    check_mode: false
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AU-12 b
    - configure_strategy
    - file_permissions_audit_configuration
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set permissions for /etc/audit/rules.d/ file(s)
    ansible.builtin.file:
      path: '{{ item }}'
      mode: u-xs,g-xws,o-xwrt
      state: file
    with_items:
    - '{{ files_found.stdout_lines }}'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - NIST-800-53-AU-12 b
    - configure_strategy
    - file_permissions_audit_configuration
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: System Audit Logs Must Have Mode 0640 or Less Permissive - Get audit log
      file from /etc/audit/auditd.conf
    ansible.builtin.command: grep -iw ^log_file /etc/audit/auditd.conf
    check_mode: false
    failed_when: false
    changed_when: false
    register: log_file_exists
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030070
    - NIST-800-171-3.3.1
    - NIST-800-53-AC-6(1)
    - NIST-800-53-AU-9(4)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.1
    - file_permissions_var_log_audit
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: System Audit Logs Must Have Mode 0640 or Less Permissive - Set audit log
      file path
    ansible.builtin.set_fact:
      log_file_path: '{{ (log_file_exists.stdout | default('''') | split('' '') |
        last) | default(''/var/log/audit/audit.log'', true) }}'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030070
    - NIST-800-171-3.3.1
    - NIST-800-53-AC-6(1)
    - NIST-800-53-AU-9(4)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.1
    - file_permissions_var_log_audit
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: System Audit Logs Must Have Mode 0640 or Less Permissive - Get audit log
      group from /etc/audit/auditd.conf
    ansible.builtin.command: grep -iw ^log_group /etc/audit/auditd.conf
    check_mode: false
    failed_when: false
    changed_when: false
    register: log_group_exists
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030070
    - NIST-800-171-3.3.1
    - NIST-800-53-AC-6(1)
    - NIST-800-53-AU-9(4)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.1
    - file_permissions_var_log_audit
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: System Audit Logs Must Have Mode 0640 or Less Permissive - Set audit log
      group
    ansible.builtin.set_fact:
      log_group: '{{ (log_group_exists.stdout | default('''') | split('' '') | last)
        | default(''root'', true) }}'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030070
    - NIST-800-171-3.3.1
    - NIST-800-53-AC-6(1)
    - NIST-800-53-AU-9(4)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.1
    - file_permissions_var_log_audit
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: System Audit Logs Must Have Mode 0640 or Less Permissive - Set audit log
      file permissions
    ansible.builtin.file:
      path: '{{ log_file_path }}'
      state: file
      mode: '{{ ''0600'' if log_group == ''root'' else ''0640'' }}'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030070
    - NIST-800-171-3.3.1
    - NIST-800-53-AC-6(1)
    - NIST-800-53-AU-9(4)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.1
    - file_permissions_var_log_audit
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Set architecture for audit chmod tasks
    ansible.builtin.set_fact:
      audit_arch: b64
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - not ( ansible_architecture == "aarch64" )
    - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
      == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030490
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_dac_modification_chmod
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Perform remediation of Audit rules for chmod for 32bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - chmod
        syscall_grouping:
        - chmod
        - fchmod
        - fchmodat

    - name: Check existence of chmod in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=perm_mod
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - chmod
        syscall_grouping:
        - chmod
        - fchmod
        - fchmodat

    - name: Check existence of chmod in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=perm_mod
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - not ( ansible_architecture == "aarch64" )
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030490
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_dac_modification_chmod
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Perform remediation of Audit rules for chmod for 64bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - chmod
        syscall_grouping:
        - chmod
        - fchmod
        - fchmodat

    - name: Check existence of chmod in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=perm_mod
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - chmod
        syscall_grouping:
        - chmod
        - fchmod
        - fchmodat

    - name: Check existence of chmod in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=perm_mod
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - not ( ansible_architecture == "aarch64" )
    - audit_arch == "b64"
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030490
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_dac_modification_chmod
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Set architecture for audit chown tasks
    ansible.builtin.set_fact:
      audit_arch: b64
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - not ( ansible_architecture == "aarch64" )
    - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
      == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030480
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_dac_modification_chown
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Perform remediation of Audit rules for chown for 32bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - chown
        syscall_grouping:
        - chown
        - fchown
        - fchownat
        - lchown

    - name: Check existence of chown in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=perm_mod
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - chown
        syscall_grouping:
        - chown
        - fchown
        - fchownat
        - lchown

    - name: Check existence of chown in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=perm_mod
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - not ( ansible_architecture == "aarch64" )
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030480
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_dac_modification_chown
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Perform remediation of Audit rules for chown for 64bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - chown
        syscall_grouping:
        - chown
        - fchown
        - fchownat
        - lchown

    - name: Check existence of chown in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=perm_mod
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - chown
        syscall_grouping:
        - chown
        - fchown
        - fchownat
        - lchown

    - name: Check existence of chown in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=perm_mod
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - not ( ansible_architecture == "aarch64" )
    - audit_arch == "b64"
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030480
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_dac_modification_chown
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Set architecture for audit fchmod tasks
    ansible.builtin.set_fact:
      audit_arch: b64
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
      == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030490
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_dac_modification_fchmod
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Perform remediation of Audit rules for fchmod for 32bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - fchmod
        syscall_grouping:
        - chmod
        - fchmod
        - fchmodat

    - name: Check existence of fchmod in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=perm_mod
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - fchmod
        syscall_grouping:
        - chmod
        - fchmod
        - fchmodat

    - name: Check existence of fchmod in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=perm_mod
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030490
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_dac_modification_fchmod
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Perform remediation of Audit rules for fchmod for 64bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - fchmod
        syscall_grouping:
        - chmod
        - fchmod
        - fchmodat

    - name: Check existence of fchmod in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=perm_mod
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - fchmod
        syscall_grouping:
        - chmod
        - fchmod
        - fchmodat

    - name: Check existence of fchmod in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=perm_mod
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - audit_arch == "b64"
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030490
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_dac_modification_fchmod
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Set architecture for audit fchmodat tasks
    ansible.builtin.set_fact:
      audit_arch: b64
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
      == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030490
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_dac_modification_fchmodat
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Perform remediation of Audit rules for fchmodat for 32bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - fchmodat
        syscall_grouping:
        - chmod
        - fchmod
        - fchmodat

    - name: Check existence of fchmodat in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=perm_mod
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - fchmodat
        syscall_grouping:
        - chmod
        - fchmod
        - fchmodat

    - name: Check existence of fchmodat in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=perm_mod
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030490
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_dac_modification_fchmodat
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Perform remediation of Audit rules for fchmodat for 64bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - fchmodat
        syscall_grouping:
        - chmod
        - fchmod
        - fchmodat

    - name: Check existence of fchmodat in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=perm_mod
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - fchmodat
        syscall_grouping:
        - chmod
        - fchmod
        - fchmodat

    - name: Check existence of fchmodat in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=perm_mod
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - audit_arch == "b64"
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030490
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_dac_modification_fchmodat
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Set architecture for audit fchown tasks
    ansible.builtin.set_fact:
      audit_arch: b64
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
      == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030480
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_dac_modification_fchown
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Perform remediation of Audit rules for fchown for 32bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - fchown
        syscall_grouping:
        - chown
        - fchown
        - fchownat
        - lchown

    - name: Check existence of fchown in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=perm_mod
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - fchown
        syscall_grouping:
        - chown
        - fchown
        - fchownat
        - lchown

    - name: Check existence of fchown in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=perm_mod
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030480
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_dac_modification_fchown
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Perform remediation of Audit rules for fchown for 64bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - fchown
        syscall_grouping:
        - chown
        - fchown
        - fchownat
        - lchown

    - name: Check existence of fchown in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=perm_mod
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - fchown
        syscall_grouping:
        - chown
        - fchown
        - fchownat
        - lchown

    - name: Check existence of fchown in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=perm_mod
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - audit_arch == "b64"
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030480
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_dac_modification_fchown
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Set architecture for audit fchownat tasks
    ansible.builtin.set_fact:
      audit_arch: b64
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
      == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030480
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_dac_modification_fchownat
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Perform remediation of Audit rules for fchownat for 32bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - fchownat
        syscall_grouping:
        - chown
        - fchown
        - fchownat
        - lchown

    - name: Check existence of fchownat in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=perm_mod
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - fchownat
        syscall_grouping:
        - chown
        - fchown
        - fchownat
        - lchown

    - name: Check existence of fchownat in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=perm_mod
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030480
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_dac_modification_fchownat
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Perform remediation of Audit rules for fchownat for 64bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - fchownat
        syscall_grouping:
        - chown
        - fchown
        - fchownat
        - lchown

    - name: Check existence of fchownat in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=perm_mod
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - fchownat
        syscall_grouping:
        - chown
        - fchown
        - fchownat
        - lchown

    - name: Check existence of fchownat in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=perm_mod
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - audit_arch == "b64"
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030480
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_dac_modification_fchownat
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Set architecture for audit fremovexattr tasks
    ansible.builtin.set_fact:
      audit_arch: b64
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
      == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030200
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_dac_modification_fremovexattr
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Perform remediation of Audit rules for fremovexattr for 32bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - fremovexattr
        syscall_grouping:
        - fremovexattr
        - lremovexattr
        - removexattr
        - fsetxattr
        - lsetxattr
        - setxattr

    - name: Check existence of fremovexattr in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=perm_mod
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - fremovexattr
        syscall_grouping:
        - fremovexattr
        - lremovexattr
        - removexattr
        - fsetxattr
        - lsetxattr
        - setxattr

    - name: Check existence of fremovexattr in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=perm_mod
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030200
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_dac_modification_fremovexattr
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Perform remediation of Audit rules for fremovexattr for 64bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - fremovexattr
        syscall_grouping:
        - fremovexattr
        - lremovexattr
        - removexattr
        - fsetxattr
        - lsetxattr
        - setxattr

    - name: Check existence of fremovexattr in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=perm_mod
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - fremovexattr
        syscall_grouping:
        - fremovexattr
        - lremovexattr
        - removexattr
        - fsetxattr
        - lsetxattr
        - setxattr

    - name: Check existence of fremovexattr in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=perm_mod
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - audit_arch == "b64"
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030200
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_dac_modification_fremovexattr
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Set architecture for audit fsetxattr tasks
    ansible.builtin.set_fact:
      audit_arch: b64
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
      == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030200
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_dac_modification_fsetxattr
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Perform remediation of Audit rules for fsetxattr for 32bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - fsetxattr
        syscall_grouping:
        - fremovexattr
        - lremovexattr
        - removexattr
        - fsetxattr
        - lsetxattr
        - setxattr

    - name: Check existence of fsetxattr in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=perm_mod
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - fsetxattr
        syscall_grouping:
        - fremovexattr
        - lremovexattr
        - removexattr
        - fsetxattr
        - lsetxattr
        - setxattr

    - name: Check existence of fsetxattr in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=perm_mod
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030200
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_dac_modification_fsetxattr
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Perform remediation of Audit rules for fsetxattr for 64bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - fsetxattr
        syscall_grouping:
        - fremovexattr
        - lremovexattr
        - removexattr
        - fsetxattr
        - lsetxattr
        - setxattr

    - name: Check existence of fsetxattr in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=perm_mod
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - fsetxattr
        syscall_grouping:
        - fremovexattr
        - lremovexattr
        - removexattr
        - fsetxattr
        - lsetxattr
        - setxattr

    - name: Check existence of fsetxattr in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=perm_mod
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - audit_arch == "b64"
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030200
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_dac_modification_fsetxattr
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Set architecture for audit lchown tasks
    ansible.builtin.set_fact:
      audit_arch: b64
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - not ( ansible_architecture == "aarch64" )
    - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
      == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030480
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_dac_modification_lchown
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Perform remediation of Audit rules for lchown for 32bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - lchown
        syscall_grouping:
        - chown
        - fchown
        - fchownat
        - lchown

    - name: Check existence of lchown in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=perm_mod
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - lchown
        syscall_grouping:
        - chown
        - fchown
        - fchownat
        - lchown

    - name: Check existence of lchown in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=perm_mod
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - not ( ansible_architecture == "aarch64" )
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030480
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_dac_modification_lchown
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Perform remediation of Audit rules for lchown for 64bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - lchown
        syscall_grouping:
        - chown
        - fchown
        - fchownat
        - lchown

    - name: Check existence of lchown in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=perm_mod
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - lchown
        syscall_grouping:
        - chown
        - fchown
        - fchownat
        - lchown

    - name: Check existence of lchown in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=perm_mod
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - not ( ansible_architecture == "aarch64" )
    - audit_arch == "b64"
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030480
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_dac_modification_lchown
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Set architecture for audit lremovexattr tasks
    ansible.builtin.set_fact:
      audit_arch: b64
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
      == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030200
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_dac_modification_lremovexattr
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Perform remediation of Audit rules for lremovexattr for 32bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - lremovexattr
        syscall_grouping:
        - fremovexattr
        - lremovexattr
        - removexattr
        - fsetxattr
        - lsetxattr
        - setxattr

    - name: Check existence of lremovexattr in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=perm_mod
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - lremovexattr
        syscall_grouping:
        - fremovexattr
        - lremovexattr
        - removexattr
        - fsetxattr
        - lsetxattr
        - setxattr

    - name: Check existence of lremovexattr in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=perm_mod
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030200
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_dac_modification_lremovexattr
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Perform remediation of Audit rules for lremovexattr for 64bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - lremovexattr
        syscall_grouping:
        - fremovexattr
        - lremovexattr
        - removexattr
        - fsetxattr
        - lsetxattr
        - setxattr

    - name: Check existence of lremovexattr in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=perm_mod
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - lremovexattr
        syscall_grouping:
        - fremovexattr
        - lremovexattr
        - removexattr
        - fsetxattr
        - lsetxattr
        - setxattr

    - name: Check existence of lremovexattr in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=perm_mod
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - audit_arch == "b64"
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030200
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_dac_modification_lremovexattr
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Set architecture for audit lsetxattr tasks
    ansible.builtin.set_fact:
      audit_arch: b64
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
      == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030200
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_dac_modification_lsetxattr
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Perform remediation of Audit rules for lsetxattr for 32bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - lsetxattr
        syscall_grouping:
        - fremovexattr
        - lremovexattr
        - removexattr
        - fsetxattr
        - lsetxattr
        - setxattr

    - name: Check existence of lsetxattr in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=perm_mod
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - lsetxattr
        syscall_grouping:
        - fremovexattr
        - lremovexattr
        - removexattr
        - fsetxattr
        - lsetxattr
        - setxattr

    - name: Check existence of lsetxattr in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=perm_mod
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030200
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_dac_modification_lsetxattr
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Perform remediation of Audit rules for lsetxattr for 64bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - lsetxattr
        syscall_grouping:
        - fremovexattr
        - lremovexattr
        - removexattr
        - fsetxattr
        - lsetxattr
        - setxattr

    - name: Check existence of lsetxattr in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=perm_mod
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - lsetxattr
        syscall_grouping:
        - fremovexattr
        - lremovexattr
        - removexattr
        - fsetxattr
        - lsetxattr
        - setxattr

    - name: Check existence of lsetxattr in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=perm_mod
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - audit_arch == "b64"
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030200
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_dac_modification_lsetxattr
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Set architecture for audit removexattr tasks
    ansible.builtin.set_fact:
      audit_arch: b64
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
      == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030200
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_dac_modification_removexattr
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Perform remediation of Audit rules for removexattr for 32bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - removexattr
        syscall_grouping:
        - fremovexattr
        - lremovexattr
        - removexattr
        - fsetxattr
        - lsetxattr
        - setxattr

    - name: Check existence of removexattr in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=perm_mod
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - removexattr
        syscall_grouping:
        - fremovexattr
        - lremovexattr
        - removexattr
        - fsetxattr
        - lsetxattr
        - setxattr

    - name: Check existence of removexattr in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=perm_mod
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030200
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_dac_modification_removexattr
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Perform remediation of Audit rules for removexattr for 64bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - removexattr
        syscall_grouping:
        - fremovexattr
        - lremovexattr
        - removexattr
        - fsetxattr
        - lsetxattr
        - setxattr

    - name: Check existence of removexattr in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=perm_mod
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - removexattr
        syscall_grouping:
        - fremovexattr
        - lremovexattr
        - removexattr
        - fsetxattr
        - lsetxattr
        - setxattr

    - name: Check existence of removexattr in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=perm_mod
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - audit_arch == "b64"
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030200
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_dac_modification_removexattr
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Set architecture for audit setxattr tasks
    ansible.builtin.set_fact:
      audit_arch: b64
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
      == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030200
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_dac_modification_setxattr
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Perform remediation of Audit rules for setxattr for 32bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - setxattr
        syscall_grouping:
        - fremovexattr
        - lremovexattr
        - removexattr
        - fsetxattr
        - lsetxattr
        - setxattr

    - name: Check existence of setxattr in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=perm_mod
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - setxattr
        syscall_grouping:
        - fremovexattr
        - lremovexattr
        - removexattr
        - fsetxattr
        - lsetxattr
        - setxattr

    - name: Check existence of setxattr in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=perm_mod
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030200
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_dac_modification_setxattr
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Perform remediation of Audit rules for setxattr for 64bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - setxattr
        syscall_grouping:
        - fremovexattr
        - lremovexattr
        - removexattr
        - fsetxattr
        - lsetxattr
        - setxattr

    - name: Check existence of setxattr in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=perm_mod
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - setxattr
        syscall_grouping:
        - fremovexattr
        - lremovexattr
        - removexattr
        - fsetxattr
        - lsetxattr
        - setxattr

    - name: Check existence of setxattr in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=perm_mod
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - audit_arch == "b64"
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030200
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.5.5
    - PCI-DSSv4-10.3
    - PCI-DSSv4-10.3.4
    - audit_rules_dac_modification_setxattr
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Record Any Attempts to Run chacl - Perform remediation of Audit rules for
      /usr/bin/chacl
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls: []
        syscall_grouping: []

    - name: Check existence of  in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)*
          -F path=/usr/bin/chacl -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/privileged.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/privileged.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F path=/usr/bin/chacl -F auid>=1000
          -F auid!=unset (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/bin/chacl -F auid>=1000
          -F auid!=unset -F key=privileged
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls: []
        syscall_grouping: []

    - name: Check existence of  in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)*
          -F path=/usr/bin/chacl -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|")
          }}))\b)((?:( -S |,)\w+)+)( -F path=/usr/bin/chacl -F auid>=1000 -F auid!=unset
          (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/bin/chacl -F auid>=1000
          -F auid!=unset -F key=privileged
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-030570
    - audit_rules_execution_chacl
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Any Attempts to Run setfacl - Perform remediation of Audit rules
      for /usr/bin/setfacl
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls: []
        syscall_grouping: []

    - name: Check existence of  in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)*
          -F path=/usr/bin/setfacl -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/privileged.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/privileged.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F path=/usr/bin/setfacl -F auid>=1000
          -F auid!=unset (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/bin/setfacl -F
          auid>=1000 -F auid!=unset -F key=privileged
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls: []
        syscall_grouping: []

    - name: Check existence of  in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)*
          -F path=/usr/bin/setfacl -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|")
          }}))\b)((?:( -S |,)\w+)+)( -F path=/usr/bin/setfacl -F auid>=1000 -F auid!=unset
          (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/bin/setfacl -F
          auid>=1000 -F auid!=unset -F key=privileged
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-030330
    - audit_rules_execution_setfacl
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Any Attempts to Run chcon - Perform remediation of Audit rules for
      /usr/bin/chcon
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls: []
        syscall_grouping: []

    - name: Check existence of  in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)*
          -F path=/usr/bin/chcon -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/privileged.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/privileged.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F path=/usr/bin/chcon -F auid>=1000
          -F auid!=unset (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/bin/chcon -F auid>=1000
          -F auid!=unset -F key=privileged
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls: []
        syscall_grouping: []

    - name: Check existence of  in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)*
          -F path=/usr/bin/chcon -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|")
          }}))\b)((?:( -S |,)\w+)+)( -F path=/usr/bin/chcon -F auid>=1000 -F auid!=unset
          (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/bin/chcon -F auid>=1000
          -F auid!=unset -F key=privileged
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-030260
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - audit_rules_execution_chcon
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Set architecture for audit rename tasks
    ansible.builtin.set_fact:
      audit_arch: b64
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - not ( ansible_architecture == "aarch64" )
    - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
      == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
    tags:
    - DISA-STIG-RHEL-08-030361
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.7
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.7
    - audit_rules_file_deletion_events_rename
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Perform remediation of Audit rules for rename for 32bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - rename
        syscall_grouping:
        - unlink
        - unlinkat
        - rename
        - renameat
        - renameat2
        - rmdir

    - name: Check existence of rename in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/delete.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/delete.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=delete
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - rename
        syscall_grouping:
        - unlink
        - unlinkat
        - rename
        - renameat
        - renameat2
        - rmdir

    - name: Check existence of rename in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=delete
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - not ( ansible_architecture == "aarch64" )
    tags:
    - DISA-STIG-RHEL-08-030361
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.7
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.7
    - audit_rules_file_deletion_events_rename
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Perform remediation of Audit rules for rename for 64bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - rename
        syscall_grouping:
        - unlink
        - unlinkat
        - rename
        - renameat
        - renameat2
        - rmdir

    - name: Check existence of rename in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/delete.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/delete.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=delete
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - rename
        syscall_grouping:
        - unlink
        - unlinkat
        - rename
        - renameat
        - renameat2
        - rmdir

    - name: Check existence of rename in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=delete
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - not ( ansible_architecture == "aarch64" )
    - audit_arch == "b64"
    tags:
    - DISA-STIG-RHEL-08-030361
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.7
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.7
    - audit_rules_file_deletion_events_rename
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Set architecture for audit renameat tasks
    ansible.builtin.set_fact:
      audit_arch: b64
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
      == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
    tags:
    - DISA-STIG-RHEL-08-030361
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.7
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.7
    - audit_rules_file_deletion_events_renameat
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Perform remediation of Audit rules for renameat for 32bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - renameat
        syscall_grouping:
        - unlink
        - unlinkat
        - rename
        - renameat
        - renameat2
        - rmdir

    - name: Check existence of renameat in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/delete.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/delete.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=delete
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - renameat
        syscall_grouping:
        - unlink
        - unlinkat
        - rename
        - renameat
        - renameat2
        - rmdir

    - name: Check existence of renameat in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=delete
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-030361
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.7
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.7
    - audit_rules_file_deletion_events_renameat
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Perform remediation of Audit rules for renameat for 64bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - renameat
        syscall_grouping:
        - unlink
        - unlinkat
        - rename
        - renameat
        - renameat2
        - rmdir

    - name: Check existence of renameat in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/delete.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/delete.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=delete
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - renameat
        syscall_grouping:
        - unlink
        - unlinkat
        - rename
        - renameat
        - renameat2
        - rmdir

    - name: Check existence of renameat in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=delete
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - audit_arch == "b64"
    tags:
    - DISA-STIG-RHEL-08-030361
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.7
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.7
    - audit_rules_file_deletion_events_renameat
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Set architecture for audit unlink tasks
    ansible.builtin.set_fact:
      audit_arch: b64
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - not ( ansible_architecture == "aarch64" )
    - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
      == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
    tags:
    - DISA-STIG-RHEL-08-030361
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.7
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.7
    - audit_rules_file_deletion_events_unlink
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Perform remediation of Audit rules for unlink for 32bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - unlink
        syscall_grouping:
        - unlink
        - unlinkat
        - rename
        - renameat
        - renameat2
        - rmdir

    - name: Check existence of unlink in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/delete.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/delete.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=delete
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - unlink
        syscall_grouping:
        - unlink
        - unlinkat
        - rename
        - renameat
        - renameat2
        - rmdir

    - name: Check existence of unlink in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=delete
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - not ( ansible_architecture == "aarch64" )
    tags:
    - DISA-STIG-RHEL-08-030361
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.7
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.7
    - audit_rules_file_deletion_events_unlink
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Perform remediation of Audit rules for unlink for 64bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - unlink
        syscall_grouping:
        - unlink
        - unlinkat
        - rename
        - renameat
        - renameat2
        - rmdir

    - name: Check existence of unlink in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/delete.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/delete.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=delete
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - unlink
        syscall_grouping:
        - unlink
        - unlinkat
        - rename
        - renameat
        - renameat2
        - rmdir

    - name: Check existence of unlink in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=delete
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - not ( ansible_architecture == "aarch64" )
    - audit_arch == "b64"
    tags:
    - DISA-STIG-RHEL-08-030361
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.7
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.7
    - audit_rules_file_deletion_events_unlink
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Set architecture for audit unlinkat tasks
    ansible.builtin.set_fact:
      audit_arch: b64
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
      == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
    tags:
    - DISA-STIG-RHEL-08-030361
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.7
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.7
    - audit_rules_file_deletion_events_unlinkat
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Perform remediation of Audit rules for unlinkat for 32bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - unlinkat
        syscall_grouping:
        - unlink
        - unlinkat
        - rename
        - renameat
        - renameat2
        - rmdir

    - name: Check existence of unlinkat in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/delete.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/delete.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=delete
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - unlinkat
        syscall_grouping:
        - unlink
        - unlinkat
        - rename
        - renameat
        - renameat2
        - rmdir

    - name: Check existence of unlinkat in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=delete
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-030361
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.7
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.7
    - audit_rules_file_deletion_events_unlinkat
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Perform remediation of Audit rules for unlinkat for 64bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - unlinkat
        syscall_grouping:
        - unlink
        - unlinkat
        - rename
        - renameat
        - renameat2
        - rmdir

    - name: Check existence of unlinkat in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/delete.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/delete.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=delete
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - unlinkat
        syscall_grouping:
        - unlink
        - unlinkat
        - rename
        - renameat
        - renameat2
        - rmdir

    - name: Check existence of unlinkat in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=delete
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - audit_arch == "b64"
    tags:
    - DISA-STIG-RHEL-08-030361
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.7
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.7
    - audit_rules_file_deletion_events_unlinkat
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Set architecture for audit creat tasks
    ansible.builtin.set_fact:
      audit_arch: b64
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - not ( ansible_architecture == "aarch64" )
    - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
      == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
    tags:
    - DISA-STIG-RHEL-08-030420
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.1
    - PCI-DSS-Req-10.2.4
    - audit_rules_unsuccessful_file_modification_creat
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Perform remediation of Audit rules for creat EACCES for 32bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - creat
        syscall_grouping:
        - creat
        - ftruncate
        - truncate
        - open
        - openat
        - open_by_handle_at

    - name: Check existence of creat in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/access.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F
          auid!=unset (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EACCES
          -F auid>=1000 -F auid!=unset -F key=access
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - creat
        syscall_grouping:
        - creat
        - ftruncate
        - truncate
        - open
        - openat
        - open_by_handle_at

    - name: Check existence of creat in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F
          auid!=unset (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EACCES
          -F auid>=1000 -F auid!=unset -F key=access
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - not ( ansible_architecture == "aarch64" )
    tags:
    - DISA-STIG-RHEL-08-030420
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.1
    - PCI-DSS-Req-10.2.4
    - audit_rules_unsuccessful_file_modification_creat
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Perform remediation of Audit rules for creat EACCES for 64bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - creat
        syscall_grouping:
        - creat
        - ftruncate
        - truncate
        - open
        - openat
        - open_by_handle_at

    - name: Check existence of creat in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/access.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F
          auid!=unset (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EACCES
          -F auid>=1000 -F auid!=unset -F key=access
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - creat
        syscall_grouping:
        - creat
        - ftruncate
        - truncate
        - open
        - openat
        - open_by_handle_at

    - name: Check existence of creat in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F
          auid!=unset (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EACCES
          -F auid>=1000 -F auid!=unset -F key=access
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - not ( ansible_architecture == "aarch64" )
    - audit_arch == "b64"
    tags:
    - DISA-STIG-RHEL-08-030420
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.1
    - PCI-DSS-Req-10.2.4
    - audit_rules_unsuccessful_file_modification_creat
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Perform remediation of Audit rules for creat EPERM for 32bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - creat
        syscall_grouping:
        - creat
        - ftruncate
        - truncate
        - open
        - openat
        - open_by_handle_at

    - name: Check existence of creat in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/access.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset
          (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EPERM
          -F auid>=1000 -F auid!=unset -F key=access
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - creat
        syscall_grouping:
        - creat
        - ftruncate
        - truncate
        - open
        - openat
        - open_by_handle_at

    - name: Check existence of creat in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset
          (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EPERM
          -F auid>=1000 -F auid!=unset -F key=access
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - not ( ansible_architecture == "aarch64" )
    tags:
    - DISA-STIG-RHEL-08-030420
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.1
    - PCI-DSS-Req-10.2.4
    - audit_rules_unsuccessful_file_modification_creat
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Perform remediation of Audit rules for creat EPERM for 64bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - creat
        syscall_grouping:
        - creat
        - ftruncate
        - truncate
        - open
        - openat
        - open_by_handle_at

    - name: Check existence of creat in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/access.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset
          (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EPERM
          -F auid>=1000 -F auid!=unset -F key=access
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - creat
        syscall_grouping:
        - creat
        - ftruncate
        - truncate
        - open
        - openat
        - open_by_handle_at

    - name: Check existence of creat in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset
          (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EPERM
          -F auid>=1000 -F auid!=unset -F key=access
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - not ( ansible_architecture == "aarch64" )
    - audit_arch == "b64"
    tags:
    - DISA-STIG-RHEL-08-030420
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.1
    - PCI-DSS-Req-10.2.4
    - audit_rules_unsuccessful_file_modification_creat
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Set architecture for audit ftruncate tasks
    ansible.builtin.set_fact:
      audit_arch: b64
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
      == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
    tags:
    - DISA-STIG-RHEL-08-030420
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.1
    - PCI-DSS-Req-10.2.4
    - audit_rules_unsuccessful_file_modification_ftruncate
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Perform remediation of Audit rules for ftruncate EACCES for 32bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - ftruncate
        syscall_grouping:
        - creat
        - ftruncate
        - truncate
        - open
        - openat
        - open_by_handle_at

    - name: Check existence of ftruncate in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/access.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F
          auid!=unset (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EACCES
          -F auid>=1000 -F auid!=unset -F key=access
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - ftruncate
        syscall_grouping:
        - creat
        - ftruncate
        - truncate
        - open
        - openat
        - open_by_handle_at

    - name: Check existence of ftruncate in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F
          auid!=unset (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EACCES
          -F auid>=1000 -F auid!=unset -F key=access
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-030420
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.1
    - PCI-DSS-Req-10.2.4
    - audit_rules_unsuccessful_file_modification_ftruncate
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Perform remediation of Audit rules for ftruncate EACCES for 64bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - ftruncate
        syscall_grouping:
        - creat
        - ftruncate
        - truncate
        - open
        - openat
        - open_by_handle_at

    - name: Check existence of ftruncate in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/access.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F
          auid!=unset (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EACCES
          -F auid>=1000 -F auid!=unset -F key=access
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - ftruncate
        syscall_grouping:
        - creat
        - ftruncate
        - truncate
        - open
        - openat
        - open_by_handle_at

    - name: Check existence of ftruncate in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F
          auid!=unset (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EACCES
          -F auid>=1000 -F auid!=unset -F key=access
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - audit_arch == "b64"
    tags:
    - DISA-STIG-RHEL-08-030420
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.1
    - PCI-DSS-Req-10.2.4
    - audit_rules_unsuccessful_file_modification_ftruncate
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Perform remediation of Audit rules for ftruncate EPERM for 32bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - ftruncate
        syscall_grouping:
        - creat
        - ftruncate
        - truncate
        - open
        - openat
        - open_by_handle_at

    - name: Check existence of ftruncate in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/access.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset
          (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EPERM
          -F auid>=1000 -F auid!=unset -F key=access
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - ftruncate
        syscall_grouping:
        - creat
        - ftruncate
        - truncate
        - open
        - openat
        - open_by_handle_at

    - name: Check existence of ftruncate in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset
          (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EPERM
          -F auid>=1000 -F auid!=unset -F key=access
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-030420
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.1
    - PCI-DSS-Req-10.2.4
    - audit_rules_unsuccessful_file_modification_ftruncate
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Perform remediation of Audit rules for ftruncate EPERM for 64bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - ftruncate
        syscall_grouping:
        - creat
        - ftruncate
        - truncate
        - open
        - openat
        - open_by_handle_at

    - name: Check existence of ftruncate in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/access.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset
          (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EPERM
          -F auid>=1000 -F auid!=unset -F key=access
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - ftruncate
        syscall_grouping:
        - creat
        - ftruncate
        - truncate
        - open
        - openat
        - open_by_handle_at

    - name: Check existence of ftruncate in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset
          (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EPERM
          -F auid>=1000 -F auid!=unset -F key=access
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - audit_arch == "b64"
    tags:
    - DISA-STIG-RHEL-08-030420
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.1
    - PCI-DSS-Req-10.2.4
    - audit_rules_unsuccessful_file_modification_ftruncate
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Set architecture for audit open tasks
    ansible.builtin.set_fact:
      audit_arch: b64
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - not ( ansible_architecture == "aarch64" )
    - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
      == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
    tags:
    - DISA-STIG-RHEL-08-030420
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.1
    - PCI-DSS-Req-10.2.4
    - audit_rules_unsuccessful_file_modification_open
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Perform remediation of Audit rules for open EACCES for 32bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - open
        syscall_grouping:
        - creat
        - ftruncate
        - truncate
        - open
        - openat
        - open_by_handle_at

    - name: Check existence of open in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/access.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F
          auid!=unset (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EACCES
          -F auid>=1000 -F auid!=unset -F key=access
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - open
        syscall_grouping:
        - creat
        - ftruncate
        - truncate
        - open
        - openat
        - open_by_handle_at

    - name: Check existence of open in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F
          auid!=unset (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EACCES
          -F auid>=1000 -F auid!=unset -F key=access
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - not ( ansible_architecture == "aarch64" )
    tags:
    - DISA-STIG-RHEL-08-030420
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.1
    - PCI-DSS-Req-10.2.4
    - audit_rules_unsuccessful_file_modification_open
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Perform remediation of Audit rules for open EACCES for 64bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - open
        syscall_grouping:
        - creat
        - ftruncate
        - truncate
        - open
        - openat
        - open_by_handle_at

    - name: Check existence of open in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/access.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F
          auid!=unset (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EACCES
          -F auid>=1000 -F auid!=unset -F key=access
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - open
        syscall_grouping:
        - creat
        - ftruncate
        - truncate
        - open
        - openat
        - open_by_handle_at

    - name: Check existence of open in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F
          auid!=unset (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EACCES
          -F auid>=1000 -F auid!=unset -F key=access
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - not ( ansible_architecture == "aarch64" )
    - audit_arch == "b64"
    tags:
    - DISA-STIG-RHEL-08-030420
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.1
    - PCI-DSS-Req-10.2.4
    - audit_rules_unsuccessful_file_modification_open
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Perform remediation of Audit rules for open EPERM for 32bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - open
        syscall_grouping:
        - creat
        - ftruncate
        - truncate
        - open
        - openat
        - open_by_handle_at

    - name: Check existence of open in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/access.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset
          (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EPERM
          -F auid>=1000 -F auid!=unset -F key=access
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - open
        syscall_grouping:
        - creat
        - ftruncate
        - truncate
        - open
        - openat
        - open_by_handle_at

    - name: Check existence of open in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset
          (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EPERM
          -F auid>=1000 -F auid!=unset -F key=access
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - not ( ansible_architecture == "aarch64" )
    tags:
    - DISA-STIG-RHEL-08-030420
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.1
    - PCI-DSS-Req-10.2.4
    - audit_rules_unsuccessful_file_modification_open
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Perform remediation of Audit rules for open EPERM for 64bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - open
        syscall_grouping:
        - creat
        - ftruncate
        - truncate
        - open
        - openat
        - open_by_handle_at

    - name: Check existence of open in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/access.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset
          (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EPERM
          -F auid>=1000 -F auid!=unset -F key=access
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - open
        syscall_grouping:
        - creat
        - ftruncate
        - truncate
        - open
        - openat
        - open_by_handle_at

    - name: Check existence of open in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset
          (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EPERM
          -F auid>=1000 -F auid!=unset -F key=access
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - not ( ansible_architecture == "aarch64" )
    - audit_arch == "b64"
    tags:
    - DISA-STIG-RHEL-08-030420
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.1
    - PCI-DSS-Req-10.2.4
    - audit_rules_unsuccessful_file_modification_open
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Set architecture for audit openat tasks
    ansible.builtin.set_fact:
      audit_arch: b64
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
      == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
    tags:
    - DISA-STIG-RHEL-08-030420
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.1
    - PCI-DSS-Req-10.2.4
    - audit_rules_unsuccessful_file_modification_openat
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Perform remediation of Audit rules for openat EACCES for 32bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - openat
        syscall_grouping:
        - creat
        - ftruncate
        - truncate
        - open
        - openat
        - open_by_handle_at

    - name: Check existence of openat in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/access.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F
          auid!=unset (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EACCES
          -F auid>=1000 -F auid!=unset -F key=access
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - openat
        syscall_grouping:
        - creat
        - ftruncate
        - truncate
        - open
        - openat
        - open_by_handle_at

    - name: Check existence of openat in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F
          auid!=unset (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EACCES
          -F auid>=1000 -F auid!=unset -F key=access
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-030420
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.1
    - PCI-DSS-Req-10.2.4
    - audit_rules_unsuccessful_file_modification_openat
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Perform remediation of Audit rules for openat EACCES for 64bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - openat
        syscall_grouping:
        - creat
        - ftruncate
        - truncate
        - open
        - openat
        - open_by_handle_at

    - name: Check existence of openat in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/access.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F
          auid!=unset (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EACCES
          -F auid>=1000 -F auid!=unset -F key=access
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - openat
        syscall_grouping:
        - creat
        - ftruncate
        - truncate
        - open
        - openat
        - open_by_handle_at

    - name: Check existence of openat in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F
          auid!=unset (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EACCES
          -F auid>=1000 -F auid!=unset -F key=access
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - audit_arch == "b64"
    tags:
    - DISA-STIG-RHEL-08-030420
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.1
    - PCI-DSS-Req-10.2.4
    - audit_rules_unsuccessful_file_modification_openat
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Perform remediation of Audit rules for openat EPERM for 32bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - openat
        syscall_grouping:
        - creat
        - ftruncate
        - truncate
        - open
        - openat
        - open_by_handle_at

    - name: Check existence of openat in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/access.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset
          (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EPERM
          -F auid>=1000 -F auid!=unset -F key=access
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - openat
        syscall_grouping:
        - creat
        - ftruncate
        - truncate
        - open
        - openat
        - open_by_handle_at

    - name: Check existence of openat in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset
          (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EPERM
          -F auid>=1000 -F auid!=unset -F key=access
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-030420
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.1
    - PCI-DSS-Req-10.2.4
    - audit_rules_unsuccessful_file_modification_openat
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Perform remediation of Audit rules for openat EPERM for 64bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - openat
        syscall_grouping:
        - creat
        - ftruncate
        - truncate
        - open
        - openat
        - open_by_handle_at

    - name: Check existence of openat in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/access.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset
          (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EPERM
          -F auid>=1000 -F auid!=unset -F key=access
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - openat
        syscall_grouping:
        - creat
        - ftruncate
        - truncate
        - open
        - openat
        - open_by_handle_at

    - name: Check existence of openat in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset
          (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EPERM
          -F auid>=1000 -F auid!=unset -F key=access
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - audit_arch == "b64"
    tags:
    - DISA-STIG-RHEL-08-030420
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.1
    - PCI-DSS-Req-10.2.4
    - audit_rules_unsuccessful_file_modification_openat
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Set architecture for audit truncate tasks
    ansible.builtin.set_fact:
      audit_arch: b64
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
      == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
    tags:
    - DISA-STIG-RHEL-08-030420
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.1
    - PCI-DSS-Req-10.2.4
    - audit_rules_unsuccessful_file_modification_truncate
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Perform remediation of Audit rules for truncate EACCES for 32bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - truncate
        syscall_grouping:
        - creat
        - ftruncate
        - truncate
        - open
        - openat
        - open_by_handle_at

    - name: Check existence of truncate in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/access.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F
          auid!=unset (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EACCES
          -F auid>=1000 -F auid!=unset -F key=access
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - truncate
        syscall_grouping:
        - creat
        - ftruncate
        - truncate
        - open
        - openat
        - open_by_handle_at

    - name: Check existence of truncate in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F
          auid!=unset (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EACCES
          -F auid>=1000 -F auid!=unset -F key=access
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-030420
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.1
    - PCI-DSS-Req-10.2.4
    - audit_rules_unsuccessful_file_modification_truncate
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Perform remediation of Audit rules for truncate EACCES for 64bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - truncate
        syscall_grouping:
        - creat
        - ftruncate
        - truncate
        - open
        - openat
        - open_by_handle_at

    - name: Check existence of truncate in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/access.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F
          auid!=unset (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EACCES
          -F auid>=1000 -F auid!=unset -F key=access
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - truncate
        syscall_grouping:
        - creat
        - ftruncate
        - truncate
        - open
        - openat
        - open_by_handle_at

    - name: Check existence of truncate in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F exit=-EACCES -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EACCES -F auid>=1000 -F
          auid!=unset (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EACCES
          -F auid>=1000 -F auid!=unset -F key=access
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - audit_arch == "b64"
    tags:
    - DISA-STIG-RHEL-08-030420
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.1
    - PCI-DSS-Req-10.2.4
    - audit_rules_unsuccessful_file_modification_truncate
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Perform remediation of Audit rules for truncate EPERM for 32bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - truncate
        syscall_grouping:
        - creat
        - ftruncate
        - truncate
        - open
        - openat
        - open_by_handle_at

    - name: Check existence of truncate in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/access.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset
          (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EPERM
          -F auid>=1000 -F auid!=unset -F key=access
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - truncate
        syscall_grouping:
        - creat
        - ftruncate
        - truncate
        - open
        - openat
        - open_by_handle_at

    - name: Check existence of truncate in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset
          (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F exit=-EPERM
          -F auid>=1000 -F auid!=unset -F key=access
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-030420
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.1
    - PCI-DSS-Req-10.2.4
    - audit_rules_unsuccessful_file_modification_truncate
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Perform remediation of Audit rules for truncate EPERM for 64bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - truncate
        syscall_grouping:
        - creat
        - ftruncate
        - truncate
        - open
        - openat
        - open_by_handle_at

    - name: Check existence of truncate in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/access.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/access.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset
          (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EPERM
          -F auid>=1000 -F auid!=unset -F key=access
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - truncate
        syscall_grouping:
        - creat
        - ftruncate
        - truncate
        - open
        - openat
        - open_by_handle_at

    - name: Check existence of truncate in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F exit=-EPERM -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F exit=-EPERM -F auid>=1000 -F auid!=unset
          (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F exit=-EPERM
          -F auid>=1000 -F auid!=unset -F key=access
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - audit_arch == "b64"
    tags:
    - DISA-STIG-RHEL-08-030420
    - NIST-800-171-3.1.7
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.1
    - PCI-DSS-Req-10.2.4
    - audit_rules_unsuccessful_file_modification_truncate
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

  - name: Ensure auditd Collects Information on Kernel Module Unloading - create_module
      - Set architecture for audit ['create_module'] tasks
    ansible.builtin.set_fact:
      audit_arch: b64
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - not ( ansible_architecture == "aarch64" )
    - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
      == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
    tags:
    - audit_rules_kernel_module_loading_create
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure auditd Collects Information on Kernel Module Unloading - create_module
      - Perform remediation of Audit rules for ['create_module'] for 32bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - create_module
        syscall_grouping:
        - create_module
        - delete_module
        - finit_module
        - init_module
        - query_module

    - name: Check existence of create_module in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/modules.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/modules.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=modules
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - create_module
        syscall_grouping:
        - create_module
        - delete_module
        - finit_module
        - init_module
        - query_module

    - name: Check existence of create_module in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=modules
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - not ( ansible_architecture == "aarch64" )
    tags:
    - audit_rules_kernel_module_loading_create
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure auditd Collects Information on Kernel Module Unloading - create_module
      - Perform remediation of Audit rules for ['create_module'] for 64bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - create_module
        syscall_grouping:
        - create_module
        - delete_module
        - finit_module
        - init_module
        - query_module

    - name: Check existence of create_module in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/modules.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/modules.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=modules
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - create_module
        syscall_grouping:
        - create_module
        - delete_module
        - finit_module
        - init_module
        - query_module

    - name: Check existence of create_module in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=modules
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - not ( ansible_architecture == "aarch64" )
    - audit_arch == "b64"
    tags:
    - audit_rules_kernel_module_loading_create
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure auditd Collects Information on Kernel Module Unloading - delete_module
      - Set architecture for audit ['delete_module'] tasks
    ansible.builtin.set_fact:
      audit_arch: b64
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
      == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
    tags:
    - DISA-STIG-RHEL-08-030390
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.7
    - audit_rules_kernel_module_loading_delete
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure auditd Collects Information on Kernel Module Unloading - delete_module
      - Perform remediation of Audit rules for ['delete_module'] for 32bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - delete_module
        syscall_grouping:
        - create_module
        - delete_module
        - finit_module
        - init_module
        - query_module

    - name: Check existence of delete_module in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/modules.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/modules.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=modules
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - delete_module
        syscall_grouping:
        - create_module
        - delete_module
        - finit_module
        - init_module
        - query_module

    - name: Check existence of delete_module in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=modules
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-030390
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.7
    - audit_rules_kernel_module_loading_delete
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure auditd Collects Information on Kernel Module Unloading - delete_module
      - Perform remediation of Audit rules for ['delete_module'] for 64bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - delete_module
        syscall_grouping:
        - create_module
        - delete_module
        - finit_module
        - init_module
        - query_module

    - name: Check existence of delete_module in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/modules.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/modules.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=modules
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - delete_module
        syscall_grouping:
        - create_module
        - delete_module
        - finit_module
        - init_module
        - query_module

    - name: Check existence of delete_module in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=modules
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - audit_arch == "b64"
    tags:
    - DISA-STIG-RHEL-08-030390
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.7
    - audit_rules_kernel_module_loading_delete
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure auditd Collects Information on Kernel Module Loading and Unloading
      - finit_module - Set architecture for audit ['finit_module'] tasks
    ansible.builtin.set_fact:
      audit_arch: b64
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
      == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
    tags:
    - DISA-STIG-RHEL-08-030360
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.7
    - audit_rules_kernel_module_loading_finit
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure auditd Collects Information on Kernel Module Loading and Unloading
      - finit_module - Perform remediation of Audit rules for ['finit_module'] for
      32bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - finit_module
        syscall_grouping:
        - create_module
        - delete_module
        - finit_module
        - init_module
        - query_module

    - name: Check existence of finit_module in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/modules.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/modules.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=modules
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - finit_module
        syscall_grouping:
        - create_module
        - delete_module
        - finit_module
        - init_module
        - query_module

    - name: Check existence of finit_module in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=modules
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-030360
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.7
    - audit_rules_kernel_module_loading_finit
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure auditd Collects Information on Kernel Module Loading and Unloading
      - finit_module - Perform remediation of Audit rules for ['finit_module'] for
      64bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - finit_module
        syscall_grouping:
        - create_module
        - delete_module
        - finit_module
        - init_module
        - query_module

    - name: Check existence of finit_module in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/modules.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/modules.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=modules
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - finit_module
        syscall_grouping:
        - create_module
        - delete_module
        - finit_module
        - init_module
        - query_module

    - name: Check existence of finit_module in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=modules
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - audit_arch == "b64"
    tags:
    - DISA-STIG-RHEL-08-030360
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.7
    - audit_rules_kernel_module_loading_finit
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure auditd Collects Information on Kernel Module Loading - init_module
      - Set architecture for audit ['init_module'] tasks
    ansible.builtin.set_fact:
      audit_arch: b64
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
      == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
    tags:
    - DISA-STIG-RHEL-08-030360
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.7
    - audit_rules_kernel_module_loading_init
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure auditd Collects Information on Kernel Module Loading - init_module
      - Perform remediation of Audit rules for ['init_module'] for 32bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - init_module
        syscall_grouping:
        - create_module
        - delete_module
        - finit_module
        - init_module
        - query_module

    - name: Check existence of init_module in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/modules.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/modules.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=modules
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - init_module
        syscall_grouping:
        - create_module
        - delete_module
        - finit_module
        - init_module
        - query_module

    - name: Check existence of init_module in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=modules
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-030360
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.7
    - audit_rules_kernel_module_loading_init
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure auditd Collects Information on Kernel Module Loading - init_module
      - Perform remediation of Audit rules for ['init_module'] for 64bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - init_module
        syscall_grouping:
        - create_module
        - delete_module
        - finit_module
        - init_module
        - query_module

    - name: Check existence of init_module in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/modules.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/modules.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=modules
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - init_module
        syscall_grouping:
        - create_module
        - delete_module
        - finit_module
        - init_module
        - query_module

    - name: Check existence of init_module in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=modules
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - audit_arch == "b64"
    tags:
    - DISA-STIG-RHEL-08-030360
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.7
    - audit_rules_kernel_module_loading_init
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure auditd Collects Information on Kernel Module Loading and Unloading
      - query_module - Set architecture for audit ['query_module'] tasks
    ansible.builtin.set_fact:
      audit_arch: b64
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - not ( ansible_architecture == "aarch64" )
    - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
      == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
    tags:
    - audit_rules_kernel_module_loading_query
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure auditd Collects Information on Kernel Module Loading and Unloading
      - query_module - Perform remediation of Audit rules for ['query_module'] for
      32bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - query_module
        syscall_grouping:
        - create_module
        - delete_module
        - finit_module
        - init_module
        - query_module

    - name: Check existence of query_module in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/modules.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/modules.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=modules
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - query_module
        syscall_grouping:
        - create_module
        - delete_module
        - finit_module
        - init_module
        - query_module

    - name: Check existence of query_module in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=modules
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - not ( ansible_architecture == "aarch64" )
    tags:
    - audit_rules_kernel_module_loading_query
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure auditd Collects Information on Kernel Module Loading and Unloading
      - query_module - Perform remediation of Audit rules for ['query_module'] for
      64bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - query_module
        syscall_grouping:
        - create_module
        - delete_module
        - finit_module
        - init_module
        - query_module

    - name: Check existence of query_module in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/modules.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/modules.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=modules
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - query_module
        syscall_grouping:
        - create_module
        - delete_module
        - finit_module
        - init_module
        - query_module

    - name: Check existence of query_module in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
          |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
          -F auid!=unset -F key=modules
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - not ( ansible_architecture == "aarch64" )
    - audit_arch == "b64"
    tags:
    - audit_rules_kernel_module_loading_query
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Record Attempts to Alter Logon and Logout Events - faillock - Check if watch
      rule for {{ var_accounts_passwords_pam_faillock_dir }} already exists in /etc/audit/rules.d/
    ansible.builtin.find:
      paths: /etc/audit/rules.d
      contains: ^\s*-w\s+{{ var_accounts_passwords_pam_faillock_dir }}\s+-p\s+wa(\s|$)+
      patterns: '*.rules'
    register: find_existing_watch_rules_d
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-030590
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.3
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.3
    - audit_rules_login_events_faillock
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Attempts to Alter Logon and Logout Events - faillock - Search /etc/audit/rules.d
      for other rules with specified key logins
    ansible.builtin.find:
      paths: /etc/audit/rules.d
      contains: ^.*(?:-F key=|-k\s+)logins$
      patterns: '*.rules'
    register: find_watch_key
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
      == 0
    tags:
    - DISA-STIG-RHEL-08-030590
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.3
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.3
    - audit_rules_login_events_faillock
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Attempts to Alter Logon and Logout Events - faillock - Use /etc/audit/rules.d/logins.rules
      as the recipient for the rule
    ansible.builtin.set_fact:
      all_files:
      - /etc/audit/rules.d/logins.rules
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_watch_key.matched is defined and find_watch_key.matched == 0 and find_existing_watch_rules_d.matched
      is defined and find_existing_watch_rules_d.matched == 0
    tags:
    - DISA-STIG-RHEL-08-030590
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.3
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.3
    - audit_rules_login_events_faillock
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Attempts to Alter Logon and Logout Events - faillock - Use matched
      file as the recipient for the rule
    ansible.builtin.set_fact:
      all_files:
      - '{{ find_watch_key.files | map(attribute=''path'') | list | first }}'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_watch_key.matched is defined and find_watch_key.matched > 0 and find_existing_watch_rules_d.matched
      is defined and find_existing_watch_rules_d.matched == 0
    tags:
    - DISA-STIG-RHEL-08-030590
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.3
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.3
    - audit_rules_login_events_faillock
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Attempts to Alter Logon and Logout Events - faillock - Add watch
      rule for {{ var_accounts_passwords_pam_faillock_dir }} in /etc/audit/rules.d/
    ansible.builtin.lineinfile:
      path: '{{ all_files[0] }}'
      line: -w {{ var_accounts_passwords_pam_faillock_dir }} -p wa -k logins
      create: true
      mode: '0600'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
      == 0
    tags:
    - DISA-STIG-RHEL-08-030590
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.3
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.3
    - audit_rules_login_events_faillock
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Attempts to Alter Logon and Logout Events - faillock - Check if watch
      rule for {{ var_accounts_passwords_pam_faillock_dir }} already exists in /etc/audit/audit.rules
    ansible.builtin.find:
      paths: /etc/audit/
      contains: ^\s*-w\s+{{ var_accounts_passwords_pam_faillock_dir }}\s+-p\s+wa(\s|$)+
      patterns: audit.rules
    register: find_existing_watch_audit_rules
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-030590
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.3
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.3
    - audit_rules_login_events_faillock
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Attempts to Alter Logon and Logout Events - faillock - Add watch
      rule for {{ var_accounts_passwords_pam_faillock_dir }} in /etc/audit/audit.rules
    ansible.builtin.lineinfile:
      line: -w {{ var_accounts_passwords_pam_faillock_dir }} -p wa -k logins
      state: present
      dest: /etc/audit/audit.rules
      create: true
      mode: '0600'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched
      == 0
    tags:
    - DISA-STIG-RHEL-08-030590
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.3
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.3
    - audit_rules_login_events_faillock
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Attempts to Alter Logon and Logout Events - lastlog - Check if watch
      rule for /var/log/lastlog already exists in /etc/audit/rules.d/
    ansible.builtin.find:
      paths: /etc/audit/rules.d
      contains: ^\s*-w\s+/var/log/lastlog\s+-p\s+wa(\s|$)+
      patterns: '*.rules'
    register: find_existing_watch_rules_d
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-030600
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.3
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.3
    - audit_rules_login_events_lastlog
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Attempts to Alter Logon and Logout Events - lastlog - Search /etc/audit/rules.d
      for other rules with specified key logins
    ansible.builtin.find:
      paths: /etc/audit/rules.d
      contains: ^.*(?:-F key=|-k\s+)logins$
      patterns: '*.rules'
    register: find_watch_key
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
      == 0
    tags:
    - DISA-STIG-RHEL-08-030600
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.3
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.3
    - audit_rules_login_events_lastlog
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Attempts to Alter Logon and Logout Events - lastlog - Use /etc/audit/rules.d/logins.rules
      as the recipient for the rule
    ansible.builtin.set_fact:
      all_files:
      - /etc/audit/rules.d/logins.rules
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_watch_key.matched is defined and find_watch_key.matched == 0 and find_existing_watch_rules_d.matched
      is defined and find_existing_watch_rules_d.matched == 0
    tags:
    - DISA-STIG-RHEL-08-030600
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.3
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.3
    - audit_rules_login_events_lastlog
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Attempts to Alter Logon and Logout Events - lastlog - Use matched
      file as the recipient for the rule
    ansible.builtin.set_fact:
      all_files:
      - '{{ find_watch_key.files | map(attribute=''path'') | list | first }}'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_watch_key.matched is defined and find_watch_key.matched > 0 and find_existing_watch_rules_d.matched
      is defined and find_existing_watch_rules_d.matched == 0
    tags:
    - DISA-STIG-RHEL-08-030600
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.3
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.3
    - audit_rules_login_events_lastlog
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Attempts to Alter Logon and Logout Events - lastlog - Add watch rule
      for /var/log/lastlog in /etc/audit/rules.d/
    ansible.builtin.lineinfile:
      path: '{{ all_files[0] }}'
      line: -w /var/log/lastlog -p wa -k logins
      create: true
      mode: '0600'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
      == 0
    tags:
    - DISA-STIG-RHEL-08-030600
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.3
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.3
    - audit_rules_login_events_lastlog
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Attempts to Alter Logon and Logout Events - lastlog - Check if watch
      rule for /var/log/lastlog already exists in /etc/audit/audit.rules
    ansible.builtin.find:
      paths: /etc/audit/
      contains: ^\s*-w\s+/var/log/lastlog\s+-p\s+wa(\s|$)+
      patterns: audit.rules
    register: find_existing_watch_audit_rules
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-030600
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.3
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.3
    - audit_rules_login_events_lastlog
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Attempts to Alter Logon and Logout Events - lastlog - Add watch rule
      for /var/log/lastlog in /etc/audit/audit.rules
    ansible.builtin.lineinfile:
      line: -w /var/log/lastlog -p wa -k logins
      state: present
      dest: /etc/audit/audit.rules
      create: true
      mode: '0600'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched
      == 0
    tags:
    - DISA-STIG-RHEL-08-030600
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.3
    - PCI-DSSv4-10.2
    - PCI-DSSv4-10.2.1
    - PCI-DSSv4-10.2.1.3
    - audit_rules_login_events_lastlog
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure auditd Collects Information on the Use of Privileged Commands - Set
      List of Mount Points Which Permits Execution of Privileged Commands
    ansible.builtin.set_fact:
      privileged_mount_points: '{{ (ansible_facts.mounts | rejectattr(''options'',
        ''search'', ''noexec|nosuid'') | rejectattr(''mount'', ''match'', ''/proc($|/.*$)'')
        | map(attribute=''mount'') | list ) }}'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-2(4)
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.2
    - audit_rules_privileged_commands
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure auditd Collects Information on the Use of Privileged Commands - Search
      for Privileged Commands in Eligible Mount Points
    ansible.builtin.shell:
      cmd: find {{ item }} -xdev -perm /6000 -type f 2>/dev/null
    register: result_privileged_commands_search
    changed_when: false
    failed_when: false
    with_items: '{{ privileged_mount_points }}'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-2(4)
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.2
    - audit_rules_privileged_commands
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure auditd Collects Information on the Use of Privileged Commands - Set
      List of Privileged Commands Found in Eligible Mount Points
    ansible.builtin.set_fact:
      privileged_commands: '{{ privileged_commands | default([]) + item.stdout_lines
        }}'
    loop: '{{ result_privileged_commands_search.results }}'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - item is not skipped
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-2(4)
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.2
    - audit_rules_privileged_commands
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure auditd Collects Information on the Use of Privileged Commands - Privileged
      Commands are Present in the System
    block:

    - name: Ensure auditd Collects Information on the Use of Privileged Commands -
        Ensure Rules for All Privileged Commands in augenrules Format
      ansible.builtin.lineinfile:
        path: /etc/audit/rules.d/privileged.rules
        line: -a always,exit -F path={{ item }} -F perm=x -F auid>=1000 -F auid!=unset
          -F key=privileged
        regexp: ^.*path={{ item | regex_escape() }} .*$
        create: true
      with_items:
      - '{{ privileged_commands }}'

    - name: Ensure auditd Collects Information on the Use of Privileged Commands -
        Ensure Rules for All Privileged Commands in auditctl Format
      ansible.builtin.lineinfile:
        path: /etc/audit/audit.rules
        line: -a always,exit -F path={{ item }} -F perm=x -F auid>=1000 -F auid!=unset
          -F key=privileged
        regexp: ^.*path={{ item | regex_escape() }} .*$
        create: true
      with_items:
      - '{{ privileged_commands }}'

    - name: Ensure auditd Collects Information on the Use of Privileged Commands -
        Search for Duplicated Rules in Other Files
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        recurse: false
        contains: ^-a always,exit (-F arch=b32 |-F arch=b64 )?-F path={{ item | regex_escape()
          }} .*$
        patterns: '*.rules'
      with_items:
      - '{{ privileged_commands }}'
      register: result_augenrules_files

    - name: Ensure auditd Collects Information on the Use of Privileged Commands -
        Ensure Rules for Privileged Commands are Defined Only in One File
      ansible.builtin.lineinfile:
        path: '{{ item.1.path }}'
        regexp: ^-a always,exit (-F arch=b32 |-F arch=b64 )?-F path={{ item.0.item
          | regex_escape() }} .*$
        state: absent
      with_subelements:
      - '{{ result_augenrules_files.results }}'
      - files
      when:
      - item.1.path != '/etc/audit/rules.d/privileged.rules'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - privileged_commands is defined
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-2(4)
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.2.2
    - audit_rules_privileged_commands
    - configure_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure auditd Collects Information on the Use of Privileged Commands - kmod
      - Perform remediation of Audit rules for /usr/bin/kmod
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls: []
        syscall_grouping: []

    - name: Check existence of  in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)*
          -F path=/usr/bin/kmod -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/privileged.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/privileged.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F path=/usr/bin/kmod -F auid>=1000
          -F auid!=unset (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/bin/kmod -F auid>=1000
          -F auid!=unset -F key=privileged
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls: []
        syscall_grouping: []

    - name: Check existence of  in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)*
          -F path=/usr/bin/kmod -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|")
          }}))\b)((?:( -S |,)\w+)+)( -F path=/usr/bin/kmod -F auid>=1000 -F auid!=unset
          (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/bin/kmod -F auid>=1000
          -F auid!=unset -F key=privileged
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-030580
    - NIST-800-53-AU-12(a)
    - NIST-800-53-AU-12.1(ii)
    - NIST-800-53-AU-12.1(iv)AU-12(c)
    - NIST-800-53-AU-3
    - NIST-800-53-AU-3.1
    - NIST-800-53-MA-4(1)(a)
    - audit_rules_privileged_commands_kmod
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Ensure auditd Collects Information on the Use of Privileged Commands - usermod
      - Perform remediation of Audit rules for /usr/sbin/usermod
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls: []
        syscall_grouping: []

    - name: Check existence of  in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)*
          -F path=/usr/sbin/usermod -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/privileged.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/privileged.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F path=/usr/sbin/usermod -F auid>=1000
          -F auid!=unset (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/sbin/usermod -F
          auid>=1000 -F auid!=unset -F key=privileged
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls: []
        syscall_grouping: []

    - name: Check existence of  in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit(( -S |,)\w+)*(( -S |,){{ item }})+(( -S |,)\w+)*
          -F path=/usr/sbin/usermod -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit)(?=.*(?:(?:-S |,)(?:{{ syscalls_found | join("|")
          }}))\b)((?:( -S |,)\w+)+)( -F path=/usr/sbin/usermod -F auid>=1000 -F auid!=unset
          (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit{{ syscalls | join(',') }} -F path=/usr/sbin/usermod -F
          auid>=1000 -F auid!=unset -F key=privileged
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-030560
    - audit_rules_privileged_commands_usermod
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Set architecture for audit tasks
    ansible.builtin.set_fact:
      audit_arch: b64
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
      == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.4.2.b
    - PCI-DSSv4-10.6
    - PCI-DSSv4-10.6.3
    - audit_rules_time_adjtimex
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Perform remediation of Audit rules for adjtimex for 32bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - adjtimex
        syscall_grouping:
        - adjtimex
        - settimeofday
        - stime

    - name: Check existence of adjtimex in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/audit_time_rules.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/audit_time_rules.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F key=audit_time_rules
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - adjtimex
        syscall_grouping:
        - adjtimex
        - settimeofday
        - stime

    - name: Check existence of adjtimex in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F key=audit_time_rules
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.4.2.b
    - PCI-DSSv4-10.6
    - PCI-DSSv4-10.6.3
    - audit_rules_time_adjtimex
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Perform remediation of Audit rules for adjtimex for 64bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - adjtimex
        syscall_grouping:
        - adjtimex
        - settimeofday

    - name: Check existence of adjtimex in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/audit_time_rules.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/audit_time_rules.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F key=audit_time_rules
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - adjtimex
        syscall_grouping:
        - adjtimex
        - settimeofday
        - stime

    - name: Check existence of adjtimex in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F key=audit_time_rules
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - audit_arch == "b64"
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.4.2.b
    - PCI-DSSv4-10.6
    - PCI-DSSv4-10.6.3
    - audit_rules_time_adjtimex
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Set architecture for audit tasks
    ansible.builtin.set_fact:
      audit_arch: b64
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
      == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.4.2.b
    - PCI-DSSv4-10.6
    - PCI-DSSv4-10.6.3
    - audit_rules_time_clock_settime
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Perform remediation of Audit rules for clock_settime for 32bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - clock_settime
        syscall_grouping: []

    - name: Check existence of clock_settime in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F a0=0x0 (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/time-change.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/time-change.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F a0=0x0 (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F a0=0x0 -F
          key=time-change
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - clock_settime
        syscall_grouping: []

    - name: Check existence of clock_settime in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F a0=0x0 (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F a0=0x0 (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F a0=0x0 -F
          key=time-change
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.4.2.b
    - PCI-DSSv4-10.6
    - PCI-DSSv4-10.6.3
    - audit_rules_time_clock_settime
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Perform remediation of Audit rules for clock_settime for 64bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - clock_settime
        syscall_grouping: []

    - name: Check existence of clock_settime in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F a0=0x0 (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/time-change.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/time-change.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F a0=0x0 (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F a0=0x0 -F
          key=time-change
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - clock_settime
        syscall_grouping: []

    - name: Check existence of clock_settime in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* -F a0=0x0 (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( -F a0=0x0 (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F a0=0x0 -F
          key=time-change
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - audit_arch == "b64"
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.4.2.b
    - PCI-DSSv4-10.6
    - PCI-DSSv4-10.6.3
    - audit_rules_time_clock_settime
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Set architecture for audit tasks
    set_fact:
      audit_arch: b64
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
      == "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.4.2.b
    - PCI-DSSv4-10.6
    - PCI-DSSv4-10.6.3
    - audit_rules_time_settimeofday
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Perform remediation of Audit rules for settimeofday for 32bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - settimeofday
        syscall_grouping:
        - adjtimex
        - settimeofday
        - stime

    - name: Check existence of settimeofday in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/audit_time_rules.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/audit_time_rules.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F key=audit_time_rules
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - settimeofday
        syscall_grouping:
        - adjtimex
        - settimeofday
        - stime

    - name: Check existence of settimeofday in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F key=audit_time_rules
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.4.2.b
    - PCI-DSSv4-10.6
    - PCI-DSSv4-10.6.3
    - audit_rules_time_settimeofday
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Perform remediation of Audit rules for settimeofday for 64bit platform
    block:

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - settimeofday
        syscall_grouping:
        - adjtimex
        - settimeofday
        - stime

    - name: Check existence of settimeofday in /etc/audit/rules.d/
      ansible.builtin.find:
        paths: /etc/audit/rules.d
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* (-k\s+|-F\s+key=)\S+\s*$
        patterns: '*.rules'
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Reset syscalls found per file
      ansible.builtin.set_fact:
        syscalls_per_file: {}
        found_paths_dict: {}

    - name: Declare syscalls found per file
      ansible.builtin.set_fact: syscalls_per_file="{{ syscalls_per_file | combine(
        {item.files[0].path :[item.item] + syscalls_per_file.get(item.files[0].path,
        []) } ) }}"
      loop: '{{ find_command.results | selectattr(''matched'') | list }}'

    - name: Declare files where syscalls were found
      ansible.builtin.set_fact: found_paths="{{ find_command.results | map(attribute='files')
        | flatten | map(attribute='path') | list }}"

    - name: Count occurrences of syscalls in paths
      ansible.builtin.set_fact: found_paths_dict="{{ found_paths_dict | combine({
        item:1+found_paths_dict.get(item, 0) }) }}"
      loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
        | list }}'

    - name: Get path with most syscalls
      ansible.builtin.set_fact: audit_file="{{ (found_paths_dict | dict2items() |
        sort(attribute='value') | last).key }}"
      when: found_paths | length >= 1

    - name: No file with syscall found, set path to /etc/audit/rules.d/audit_time_rules.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/rules.d/audit_time_rules.rules"
      when: found_paths | length == 0

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
          | join("|") }}))\b)((?:( -S |,)\w+)+)( (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F key=audit_time_rules
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0

    - name: Declare list of syscalls
      ansible.builtin.set_fact:
        syscalls:
        - settimeofday
        syscall_grouping:
        - adjtimex
        - settimeofday
        - stime

    - name: Check existence of settimeofday in /etc/audit/audit.rules
      ansible.builtin.find:
        paths: /etc/audit
        contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+((
          -S |,)\w+)* (-k\s+|-F\s+key=)\S+\s*$
        patterns: audit.rules
      register: find_command
      loop: '{{ (syscall_grouping + syscalls) | unique }}'

    - name: Set path to /etc/audit/audit.rules
      ansible.builtin.set_fact: audit_file="/etc/audit/audit.rules"

    - name: Declare found syscalls
      ansible.builtin.set_fact: syscalls_found="{{ find_command.results | selectattr('matched')
        | map(attribute='item') | list }}"

    - name: Declare missing syscalls
      ansible.builtin.set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found)
        }}"

    - name: Replace the audit rule in {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found
          | join("|") }}))\b)((?:( -S |,)\w+)+)( (?:-k |-F key=)\w+)
        line: \1\2\3{{ missing_syscalls | join("\3") }}\4
        backrefs: true
        state: present
        mode: g-rwx,o-rwx
      when: syscalls_found | length > 0 and missing_syscalls | length > 0

    - name: Add the audit rule to {{ audit_file }}
      ansible.builtin.lineinfile:
        path: '{{ audit_file }}'
        line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F key=audit_time_rules
        create: true
        mode: g-rwx,o-rwx
        state: present
      when: syscalls_found | length == 0
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - audit_arch == "b64"
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.4.2.b
    - PCI-DSSv4-10.6
    - PCI-DSSv4-10.6.3
    - audit_rules_time_settimeofday
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Attempts to Alter the localtime File - Check if watch rule for /etc/localtime
      already exists in /etc/audit/rules.d/
    ansible.builtin.find:
      paths: /etc/audit/rules.d
      contains: ^\s*-w\s+/etc/localtime\s+-p\s+wa(\s|$)+
      patterns: '*.rules'
    register: find_existing_watch_rules_d
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.4.2.b
    - PCI-DSSv4-10.6
    - PCI-DSSv4-10.6.3
    - audit_rules_time_watch_localtime
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Attempts to Alter the localtime File - Search /etc/audit/rules.d
      for other rules with specified key audit_time_rules
    ansible.builtin.find:
      paths: /etc/audit/rules.d
      contains: ^.*(?:-F key=|-k\s+)audit_time_rules$
      patterns: '*.rules'
    register: find_watch_key
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
      == 0
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.4.2.b
    - PCI-DSSv4-10.6
    - PCI-DSSv4-10.6.3
    - audit_rules_time_watch_localtime
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Attempts to Alter the localtime File - Use /etc/audit/rules.d/audit_time_rules.rules
      as the recipient for the rule
    ansible.builtin.set_fact:
      all_files:
      - /etc/audit/rules.d/audit_time_rules.rules
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_watch_key.matched is defined and find_watch_key.matched == 0 and find_existing_watch_rules_d.matched
      is defined and find_existing_watch_rules_d.matched == 0
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.4.2.b
    - PCI-DSSv4-10.6
    - PCI-DSSv4-10.6.3
    - audit_rules_time_watch_localtime
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Attempts to Alter the localtime File - Use matched file as the recipient
      for the rule
    ansible.builtin.set_fact:
      all_files:
      - '{{ find_watch_key.files | map(attribute=''path'') | list | first }}'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_watch_key.matched is defined and find_watch_key.matched > 0 and find_existing_watch_rules_d.matched
      is defined and find_existing_watch_rules_d.matched == 0
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.4.2.b
    - PCI-DSSv4-10.6
    - PCI-DSSv4-10.6.3
    - audit_rules_time_watch_localtime
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Attempts to Alter the localtime File - Add watch rule for /etc/localtime
      in /etc/audit/rules.d/
    ansible.builtin.lineinfile:
      path: '{{ all_files[0] }}'
      line: -w /etc/localtime -p wa -k audit_time_rules
      create: true
      mode: '0600'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_rules_d.matched is defined and find_existing_watch_rules_d.matched
      == 0
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.4.2.b
    - PCI-DSSv4-10.6
    - PCI-DSSv4-10.6.3
    - audit_rules_time_watch_localtime
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Attempts to Alter the localtime File - Check if watch rule for /etc/localtime
      already exists in /etc/audit/audit.rules
    ansible.builtin.find:
      paths: /etc/audit/
      contains: ^\s*-w\s+/etc/localtime\s+-p\s+wa(\s|$)+
      patterns: audit.rules
    register: find_existing_watch_audit_rules
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.4.2.b
    - PCI-DSSv4-10.6
    - PCI-DSSv4-10.6.3
    - audit_rules_time_watch_localtime
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Record Attempts to Alter the localtime File - Add watch rule for /etc/localtime
      in /etc/audit/audit.rules
    ansible.builtin.lineinfile:
      line: -w /etc/localtime -p wa -k audit_time_rules
      state: present
      dest: /etc/audit/audit.rules
      create: true
      mode: '0600'
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    - find_existing_watch_audit_rules.matched is defined and find_existing_watch_audit_rules.matched
      == 0
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.1.7
    - NIST-800-53-AC-6(9)
    - NIST-800-53-AU-12(c)
    - NIST-800-53-AU-2(d)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.4.2.b
    - PCI-DSSv4-10.6
    - PCI-DSSv4-10.6.3
    - audit_rules_time_watch_localtime
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Configure auditd Disk Error Action on Disk Error
    ansible.builtin.lineinfile:
      dest: /etc/audit/auditd.conf
      line: disk_error_action = {{ var_auditd_disk_error_action.split('|')[0] }}
      regexp: ^\s*disk_error_action\s*=\s*.*$
      state: present
      create: true
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-030040
    - NIST-800-53-AU-5(1)
    - NIST-800-53-AU-5(2)
    - NIST-800-53-AU-5(4)
    - NIST-800-53-AU-5(b)
    - NIST-800-53-CM-6(a)
    - auditd_data_disk_error_action
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Configure auditd Disk Full Action when Disk Space Is Full
    ansible.builtin.lineinfile:
      dest: /etc/audit/auditd.conf
      line: disk_full_action = {{ var_auditd_disk_full_action.split('|')[0] }}
      regexp: ^\s*disk_full_action\s*=\s*.*$
      state: present
      create: true
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - DISA-STIG-RHEL-08-030060
    - NIST-800-53-AU-5(1)
    - NIST-800-53-AU-5(2)
    - NIST-800-53-AU-5(4)
    - NIST-800-53-AU-5(b)
    - NIST-800-53-CM-6(a)
    - auditd_data_disk_full_action
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Configure auditd admin_space_left Action on Low Disk Space
    ansible.builtin.lineinfile:
      dest: /etc/audit/auditd.conf
      line: admin_space_left_action = {{ var_auditd_admin_space_left_action .split('|')[0]
        }}
      regexp: ^\s*admin_space_left_action\s*=\s*.*$
      state: present
      create: true
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.4.1.1
    - NIST-800-171-3.3.1
    - NIST-800-53-AU-5(1)
    - NIST-800-53-AU-5(2)
    - NIST-800-53-AU-5(4)
    - NIST-800-53-AU-5(b)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.7
    - PCI-DSSv4-10.5
    - PCI-DSSv4-10.5.1
    - auditd_data_retention_admin_space_left_action
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Configure auditd Max Log File Size
    ansible.builtin.lineinfile:
      dest: /etc/audit/auditd.conf
      regexp: ^\s*max_log_file\s*=\s*.*$
      line: max_log_file = {{ var_auditd_max_log_file }}
      state: present
      create: true
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.4.1.1
    - NIST-800-53-AU-11
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.7
    - auditd_data_retention_max_log_file
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Configure auditd max_log_file_action Upon Reaching Maximum Log Size
    ansible.builtin.lineinfile:
      dest: /etc/audit/auditd.conf
      line: max_log_file_action = {{ var_auditd_max_log_file_action }}
      regexp: ^\s*max_log_file_action\s*=\s*.*$
      state: present
      create: true
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.4.1.1
    - NIST-800-53-AU-5(1)
    - NIST-800-53-AU-5(2)
    - NIST-800-53-AU-5(4)
    - NIST-800-53-AU-5(b)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.7
    - auditd_data_retention_max_log_file_action
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Configure auditd space_left Action on Low Disk Space
    ansible.builtin.lineinfile:
      dest: /etc/audit/auditd.conf
      line: space_left_action = {{ var_auditd_space_left_action.split('|')[0] }}
      regexp: ^\s*space_left_action\s*=\s*.*$
      state: present
      create: true
    when:
    - '"audit" in ansible_facts.packages'
    - '"kernel" in ansible_facts.packages'
    tags:
    - CJIS-5.4.1.1
    - DISA-STIG-RHEL-08-030731
    - NIST-800-171-3.3.1
    - NIST-800-53-AU-5(1)
    - NIST-800-53-AU-5(2)
    - NIST-800-53-AU-5(4)
    - NIST-800-53-AU-5(b)
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-10.7
    - PCI-DSSv4-10.5
    - PCI-DSSv4-10.5.1
    - auditd_data_retention_space_left_action
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

  - name: Set the file_groupownership_audit_binaries_newgroup variable if represented
      by gid
    ansible.builtin.set_fact:
      file_groupownership_audit_binaries_newgroup: '0'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - configure_strategy
    - file_groupownership_audit_binaries
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /sbin/auditctl
    ansible.builtin.stat:
      path: /sbin/auditctl
    register: file_exists
    when: '"kernel" in ansible_facts.packages'
    tags:
    - configure_strategy
    - file_groupownership_audit_binaries
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure group owner on /sbin/auditctl
    ansible.builtin.file:
      path: /sbin/auditctl
      follow: false
      group: '{{ file_groupownership_audit_binaries_newgroup }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - file_exists.stat is defined and file_exists.stat.exists
    tags:
    - configure_strategy
    - file_groupownership_audit_binaries
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /sbin/aureport
    ansible.builtin.stat:
      path: /sbin/aureport
    register: file_exists
    when: '"kernel" in ansible_facts.packages'
    tags:
    - configure_strategy
    - file_groupownership_audit_binaries
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure group owner on /sbin/aureport
    ansible.builtin.file:
      path: /sbin/aureport
      follow: false
      group: '{{ file_groupownership_audit_binaries_newgroup }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - file_exists.stat is defined and file_exists.stat.exists
    tags:
    - configure_strategy
    - file_groupownership_audit_binaries
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /sbin/ausearch
    ansible.builtin.stat:
      path: /sbin/ausearch
    register: file_exists
    when: '"kernel" in ansible_facts.packages'
    tags:
    - configure_strategy
    - file_groupownership_audit_binaries
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure group owner on /sbin/ausearch
    ansible.builtin.file:
      path: /sbin/ausearch
      follow: false
      group: '{{ file_groupownership_audit_binaries_newgroup }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - file_exists.stat is defined and file_exists.stat.exists
    tags:
    - configure_strategy
    - file_groupownership_audit_binaries
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /sbin/autrace
    ansible.builtin.stat:
      path: /sbin/autrace
    register: file_exists
    when: '"kernel" in ansible_facts.packages'
    tags:
    - configure_strategy
    - file_groupownership_audit_binaries
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure group owner on /sbin/autrace
    ansible.builtin.file:
      path: /sbin/autrace
      follow: false
      group: '{{ file_groupownership_audit_binaries_newgroup }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - file_exists.stat is defined and file_exists.stat.exists
    tags:
    - configure_strategy
    - file_groupownership_audit_binaries
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /sbin/auditd
    ansible.builtin.stat:
      path: /sbin/auditd
    register: file_exists
    when: '"kernel" in ansible_facts.packages'
    tags:
    - configure_strategy
    - file_groupownership_audit_binaries
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure group owner on /sbin/auditd
    ansible.builtin.file:
      path: /sbin/auditd
      follow: false
      group: '{{ file_groupownership_audit_binaries_newgroup }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - file_exists.stat is defined and file_exists.stat.exists
    tags:
    - configure_strategy
    - file_groupownership_audit_binaries
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /sbin/audispd
    ansible.builtin.stat:
      path: /sbin/audispd
    register: file_exists
    when: '"kernel" in ansible_facts.packages'
    tags:
    - configure_strategy
    - file_groupownership_audit_binaries
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure group owner on /sbin/audispd
    ansible.builtin.file:
      path: /sbin/audispd
      follow: false
      group: '{{ file_groupownership_audit_binaries_newgroup }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - file_exists.stat is defined and file_exists.stat.exists
    tags:
    - configure_strategy
    - file_groupownership_audit_binaries
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /sbin/augenrules
    ansible.builtin.stat:
      path: /sbin/augenrules
    register: file_exists
    when: '"kernel" in ansible_facts.packages'
    tags:
    - configure_strategy
    - file_groupownership_audit_binaries
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure group owner on /sbin/augenrules
    ansible.builtin.file:
      path: /sbin/augenrules
      follow: false
      group: '{{ file_groupownership_audit_binaries_newgroup }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - file_exists.stat is defined and file_exists.stat.exists
    tags:
    - configure_strategy
    - file_groupownership_audit_binaries
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Set the file_ownership_audit_binaries_newown variable if represented by
      uid
    ansible.builtin.set_fact:
      file_ownership_audit_binaries_newown: '0'
    when: '"kernel" in ansible_facts.packages'
    tags:
    - configure_strategy
    - file_ownership_audit_binaries
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /sbin/auditctl
    ansible.builtin.stat:
      path: /sbin/auditctl
    register: file_exists
    when: '"kernel" in ansible_facts.packages'
    tags:
    - configure_strategy
    - file_ownership_audit_binaries
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure owner on /sbin/auditctl
    ansible.builtin.file:
      path: /sbin/auditctl
      follow: false
      owner: '{{ file_ownership_audit_binaries_newown }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - file_exists.stat is defined and file_exists.stat.exists
    tags:
    - configure_strategy
    - file_ownership_audit_binaries
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /sbin/aureport
    ansible.builtin.stat:
      path: /sbin/aureport
    register: file_exists
    when: '"kernel" in ansible_facts.packages'
    tags:
    - configure_strategy
    - file_ownership_audit_binaries
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure owner on /sbin/aureport
    ansible.builtin.file:
      path: /sbin/aureport
      follow: false
      owner: '{{ file_ownership_audit_binaries_newown }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - file_exists.stat is defined and file_exists.stat.exists
    tags:
    - configure_strategy
    - file_ownership_audit_binaries
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /sbin/ausearch
    ansible.builtin.stat:
      path: /sbin/ausearch
    register: file_exists
    when: '"kernel" in ansible_facts.packages'
    tags:
    - configure_strategy
    - file_ownership_audit_binaries
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure owner on /sbin/ausearch
    ansible.builtin.file:
      path: /sbin/ausearch
      follow: false
      owner: '{{ file_ownership_audit_binaries_newown }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - file_exists.stat is defined and file_exists.stat.exists
    tags:
    - configure_strategy
    - file_ownership_audit_binaries
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /sbin/autrace
    ansible.builtin.stat:
      path: /sbin/autrace
    register: file_exists
    when: '"kernel" in ansible_facts.packages'
    tags:
    - configure_strategy
    - file_ownership_audit_binaries
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure owner on /sbin/autrace
    ansible.builtin.file:
      path: /sbin/autrace
      follow: false
      owner: '{{ file_ownership_audit_binaries_newown }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - file_exists.stat is defined and file_exists.stat.exists
    tags:
    - configure_strategy
    - file_ownership_audit_binaries
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /sbin/auditd
    ansible.builtin.stat:
      path: /sbin/auditd
    register: file_exists
    when: '"kernel" in ansible_facts.packages'
    tags:
    - configure_strategy
    - file_ownership_audit_binaries
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure owner on /sbin/auditd
    ansible.builtin.file:
      path: /sbin/auditd
      follow: false
      owner: '{{ file_ownership_audit_binaries_newown }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - file_exists.stat is defined and file_exists.stat.exists
    tags:
    - configure_strategy
    - file_ownership_audit_binaries
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /sbin/audispd
    ansible.builtin.stat:
      path: /sbin/audispd
    register: file_exists
    when: '"kernel" in ansible_facts.packages'
    tags:
    - configure_strategy
    - file_ownership_audit_binaries
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure owner on /sbin/audispd
    ansible.builtin.file:
      path: /sbin/audispd
      follow: false
      owner: '{{ file_ownership_audit_binaries_newown }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - file_exists.stat is defined and file_exists.stat.exists
    tags:
    - configure_strategy
    - file_ownership_audit_binaries
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /sbin/augenrules
    ansible.builtin.stat:
      path: /sbin/augenrules
    register: file_exists
    when: '"kernel" in ansible_facts.packages'
    tags:
    - configure_strategy
    - file_ownership_audit_binaries
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure owner on /sbin/augenrules
    ansible.builtin.file:
      path: /sbin/augenrules
      follow: false
      owner: '{{ file_ownership_audit_binaries_newown }}'
    when:
    - '"kernel" in ansible_facts.packages'
    - file_exists.stat is defined and file_exists.stat.exists
    tags:
    - configure_strategy
    - file_ownership_audit_binaries
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /sbin/auditctl
    ansible.builtin.stat:
      path: /sbin/auditctl
    register: file_exists
    when: '"kernel" in ansible_facts.packages'
    tags:
    - configure_strategy
    - file_permissions_audit_binaries
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure permission u-s,g-ws,o-wt on /sbin/auditctl
    ansible.builtin.file:
      path: /sbin/auditctl
      mode: u-s,g-ws,o-wt
    when:
    - '"kernel" in ansible_facts.packages'
    - file_exists.stat is defined and file_exists.stat.exists
    tags:
    - configure_strategy
    - file_permissions_audit_binaries
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /sbin/aureport
    ansible.builtin.stat:
      path: /sbin/aureport
    register: file_exists
    when: '"kernel" in ansible_facts.packages'
    tags:
    - configure_strategy
    - file_permissions_audit_binaries
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure permission u-s,g-ws,o-wt on /sbin/aureport
    ansible.builtin.file:
      path: /sbin/aureport
      mode: u-s,g-ws,o-wt
    when:
    - '"kernel" in ansible_facts.packages'
    - file_exists.stat is defined and file_exists.stat.exists
    tags:
    - configure_strategy
    - file_permissions_audit_binaries
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /sbin/ausearch
    ansible.builtin.stat:
      path: /sbin/ausearch
    register: file_exists
    when: '"kernel" in ansible_facts.packages'
    tags:
    - configure_strategy
    - file_permissions_audit_binaries
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure permission u-s,g-ws,o-wt on /sbin/ausearch
    ansible.builtin.file:
      path: /sbin/ausearch
      mode: u-s,g-ws,o-wt
    when:
    - '"kernel" in ansible_facts.packages'
    - file_exists.stat is defined and file_exists.stat.exists
    tags:
    - configure_strategy
    - file_permissions_audit_binaries
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /sbin/autrace
    ansible.builtin.stat:
      path: /sbin/autrace
    register: file_exists
    when: '"kernel" in ansible_facts.packages'
    tags:
    - configure_strategy
    - file_permissions_audit_binaries
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure permission u-s,g-ws,o-wt on /sbin/autrace
    ansible.builtin.file:
      path: /sbin/autrace
      mode: u-s,g-ws,o-wt
    when:
    - '"kernel" in ansible_facts.packages'
    - file_exists.stat is defined and file_exists.stat.exists
    tags:
    - configure_strategy
    - file_permissions_audit_binaries
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /sbin/auditd
    ansible.builtin.stat:
      path: /sbin/auditd
    register: file_exists
    when: '"kernel" in ansible_facts.packages'
    tags:
    - configure_strategy
    - file_permissions_audit_binaries
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure permission u-s,g-ws,o-wt on /sbin/auditd
    ansible.builtin.file:
      path: /sbin/auditd
      mode: u-s,g-ws,o-wt
    when:
    - '"kernel" in ansible_facts.packages'
    - file_exists.stat is defined and file_exists.stat.exists
    tags:
    - configure_strategy
    - file_permissions_audit_binaries
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /sbin/audispd
    ansible.builtin.stat:
      path: /sbin/audispd
    register: file_exists
    when: '"kernel" in ansible_facts.packages'
    tags:
    - configure_strategy
    - file_permissions_audit_binaries
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure permission u-s,g-ws,o-wt on /sbin/audispd
    ansible.builtin.file:
      path: /sbin/audispd
      mode: u-s,g-ws,o-wt
    when:
    - '"kernel" in ansible_facts.packages'
    - file_exists.stat is defined and file_exists.stat.exists
    tags:
    - configure_strategy
    - file_permissions_audit_binaries
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Test for existence /sbin/augenrules
    ansible.builtin.stat:
      path: /sbin/augenrules
    register: file_exists
    when: '"kernel" in ansible_facts.packages'
    tags:
    - configure_strategy
    - file_permissions_audit_binaries
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

  - name: Ensure permission u-s,g-ws,o-wt on /sbin/augenrules
    ansible.builtin.file:
      path: /sbin/augenrules
      mode: u-s,g-ws,o-wt
    when:
    - '"kernel" in ansible_facts.packages'
    - file_exists.stat is defined and file_exists.stat.exists
    tags:
    - configure_strategy
    - file_permissions_audit_binaries
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed

Youez - 2016 - github.com/yon3zu
LinuXploit