From cf54d139c26e18cfa49b5cdb037e5c70a38df714 Mon Sep 17 00:00:00 2001
From: Rafael Guterres Jeffman <rjeffman@redhat.com>
Date: Fri, 29 May 2020 15:19:12 -0300
Subject: [PATCH] Fixes attempt to create rules with members when category is
 `all`.

Current implementation of hbacrule and sudorule allow for a new rule
creation script to be partialy successful when a member is provided and
the respective member category is set to `all` (either users, hosts,
services, commands, and their group counterparts).

Since the creation of the rule is independent of the adittion of members,
the rule is succesfully created, but member addition fails, leaving with
a created rule that has no members on it.

This patch fixes both modules by verifying if user, host, service or
commands (and groups of members) are being added if the corresponding
category is set to `all`, when the state is `present` and the action is
not `member`. If so, it fails before the rule is created.
---
 plugins/modules/ipahbacrule.py              | 10 +++
 plugins/modules/ipasudorule.py              | 11 +++
 tests/hbacrule/test_hbacrule_categories.yml | 54 +++++++++++++++
 tests/sudorule/test_sudorule_categories.yml | 76 ++++++++++++++++++++-
 4 files changed, 149 insertions(+), 2 deletions(-)

diff --git a/plugins/modules/ipahbacrule.py b/plugins/modules/ipahbacrule.py
index a94758e9..12725c70 100644
--- a/plugins/modules/ipahbacrule.py
+++ b/plugins/modules/ipahbacrule.py
@@ -270,6 +270,16 @@ def main():
                     ansible_module.fail_json(
                         msg="Argument '%s' can not be used with action "
                         "'%s'" % (x, action))
+        else:
+            if hostcategory == 'all' and any([host, hostgroup]):
+                ansible_module.fail_json(
+                    msg="Hosts cannot be added when host category='all'")
+            if usercategory == 'all' and any([user, group]):
+                ansible_module.fail_json(
+                    msg="Users cannot be added when user category='all'")
+            if servicecategory == 'all' and any([hbacsvc, hbacsvcgroup]):
+                ansible_module.fail_json(
+                    msg="Services cannot be added when service category='all'")
 
     elif state == "absent":
         if len(names) < 1:
diff --git a/plugins/modules/ipasudorule.py b/plugins/modules/ipasudorule.py
index 72c5a73b..741028cf 100644
--- a/plugins/modules/ipasudorule.py
+++ b/plugins/modules/ipasudorule.py
@@ -339,6 +339,17 @@ def main():
                     ansible_module.fail_json(
                         msg="Argument '%s' can not be used with action "
                         "'%s'" % (arg, action))
+        else:
+            if hostcategory == 'all' and any([host, hostgroup]):
+                ansible_module.fail_json(
+                    msg="Hosts cannot be added when host category='all'")
+            if usercategory == 'all' and any([user, group]):
+                ansible_module.fail_json(
+                    msg="Users cannot be added when user category='all'")
+            if cmdcategory == 'all' \
+               and any([allow_sudocmd, allow_sudocmdgroup]):
+                ansible_module.fail_json(
+                    msg="Commands cannot be added when command category='all'")
 
     elif state == "absent":
         if len(names) < 1:
diff --git a/tests/hbacrule/test_hbacrule_categories.yml b/tests/hbacrule/test_hbacrule_categories.yml
index 5f1934bc..67bc9934 100644
--- a/tests/hbacrule/test_hbacrule_categories.yml
+++ b/tests/hbacrule/test_hbacrule_categories.yml
@@ -109,6 +109,60 @@
     register: result
     failed_when: result.changed
 
+  - name: Ensure `user` cannot be added if usercategory is `all`.
+    ipahbacrule:
+      ipaadmin_password: SomeADMINpassword
+      name: allusers
+      user: shouldfail01
+      usercategory: "all"
+    register: result
+    failed_when: not result.failed or "Users cannot be added when user category='all'" not in result.msg
+
+  - name: Ensure `group` cannot be added if usercategory is `all`.
+    ipahbacrule:
+      ipaadmin_password: SomeADMINpassword
+      name: allusers
+      group: shouldfail01
+      usercategory: "all"
+    register: result
+    failed_when: not result.failed or "Users cannot be added when user category='all'" not in result.msg
+
+  - name: Ensure `host` cannot be added if hostcategory is `all`.
+    ipahbacrule:
+      ipaadmin_password: SomeADMINpassword
+      name: allusers
+      host: host.shouldfail.com
+      hostcategory: "all"
+    register: result
+    failed_when: not result.failed or "Hosts cannot be added when host category='all'" not in result.msg
+
+  - name: Ensure `hostgroup` cannot be added if hostcategory is `all`.
+    ipahbacrule:
+      ipaadmin_password: SomeADMINpassword
+      name: allusers
+      hostgroup: shouldfail_hostgroup
+      hostcategory: "all"
+    register: result
+    failed_when: not result.failed or "Hosts cannot be added when host category='all'" not in result.msg
+
+  - name: Ensure `hbacsvc` cannot be added if hbacsvccategory is `all`.
+    ipahbacrule:
+      ipaadmin_password: SomeADMINpassword
+      name: allusers
+      hbacsvc: "HTTP/fail.example.com"
+      servicecategory: "all"
+    register: result
+    failed_when: not result.failed or "Services cannot be added when service category='all'" not in result.msg
+
+  - name: Ensure `hbacsvcgroup` cannot be added if hbacsvccategory is `all`.
+    ipahbacrule:
+      ipaadmin_password: SomeADMINpassword
+      name: allusers
+      hbacsvcgroup: shouldfail_svcgroup
+      servicecategory: "all"
+    register: result
+    failed_when: not result.failed or "Services cannot be added when service category='all'" not in result.msg
+
   - name: Ensure HBAC rules are absent
     ipahbacrule:
       ipaadmin_password: SomeADMINpassword
diff --git a/tests/sudorule/test_sudorule_categories.yml b/tests/sudorule/test_sudorule_categories.yml
index c4aaeda6..e28ca63c 100644
--- a/tests/sudorule/test_sudorule_categories.yml
+++ b/tests/sudorule/test_sudorule_categories.yml
@@ -1,10 +1,13 @@
 ---
 - name: Test sudorule user category
   hosts: ipaserver
-  become: true
-  gather_facts: false
+  become: yes
+  gather_facts: yes
 
   tasks:
+  - name: Get Domain from the server name
+    set_fact:
+      ipaserver_domain: "{{ groups.ipaserver[0].split('.')[1:] | join ('.') }}"
 
   - name: Ensure sudorules are absent
     ipasudorule:
@@ -173,6 +176,75 @@
     register: result
     failed_when: result.changed
 
+  - name: Ensure sudorules are absent
+    ipasudorule:
+      ipaadmin_password: SomeADMINpassword
+      name:
+      - allusers
+      state: absent
+    register: result
+    failed_when: not result.changed
+
+  - name: Ensure `host` cannot be added if hostcategory is `all`.
+    ipasudorule:
+      ipaadmin_password: SomeADMINpassword
+      name: allusers
+      description: sudo rule
+      host: "{{ 'shouldfail.' + ipaserver_domain }}"
+      hostcategory: "all"
+    register: result
+    failed_when: not result.failed or "Hosts cannot be added when host category='all'" not in result.msg
+
+  - name: Ensure `hostgroup` cannot be added if hostcategory is `all`.
+    ipasudorule:
+      ipaadmin_password: SomeADMINpassword
+      name: allusers
+      description: sudo rule
+      hostgroup: shouldfail_hostgroup
+      hostcategory: "all"
+    register: result
+    failed_when: not result.failed or "Hosts cannot be added when host category='all'" not in result.msg
+
+  - name: Ensure `user` cannot be added if usercategory is `all`.
+    ipasudorule:
+      ipaadmin_password: SomeADMINpassword
+      name: allusers
+      description: sudo rule
+      user: "shouldfail01"
+      usercategory: "all"
+    register: result
+    failed_when: not result.failed or "Users cannot be added when user category='all'" not in result.msg
+
+  - name: Ensure `group` cannot be added if usercategory is `all`.
+    ipasudorule:
+      ipaadmin_password: SomeADMINpassword
+      name: allusers
+      description: sudo rule
+      group: "shouldfail01"
+      usercategory: "all"
+    register: result
+    failed_when: not result.failed or "Users cannot be added when user category='all'" not in result.msg
+
+  - name: Ensure `command` cannot be added if cmdcategory is `all`.
+    ipasudorule:
+      ipaadmin_password: SomeADMINpassword
+      name: allusers
+      description: sudo rule
+      allow_sudocmd: "/bin/shouldfail"
+      cmdcategory: "all"
+    register: result
+    failed_when: not result.failed or "Commands cannot be added when command category='all'" not in result.msg
+
+  - name: Ensure `command group` cannot be added if cmdcategory is `all`.
+    ipasudorule:
+      ipaadmin_password: SomeADMINpassword
+      name: allusers
+      description: sudo rule
+      allow_sudocmdgroup: shouldfail_cmdgroup
+      cmdcategory: "all"
+    register: result
+    failed_when: not result.failed or "Commands cannot be added when command category='all'" not in result.msg
+
   # cleanup
   - name: Ensure sudorules are absent
     ipasudorule:
-- 
GitLab