I just retested on 3.12, and the issue is still there. And it is becoming more urgent as until now we've been able to mitigate this with a hook script, denying the wrong actions. But since hooks are now gone we don't have a way to mitigate this any more.
To expand on the previous descriptions, it is possible for a user to violate RBAC restrictions and both modify and delete a Template association belonging to another Organization which the user is not part of.
I have created a sequence of hammer commands to make it easier to reproduce. All the actions can be done in hammer, except for one near the end (update) which for some reason is disallowed in hammer (good), but still allowed in GUI (bad).
Also note that for some reason the hammer commands executed as the individual test users tend to fail randomly. But they work again after one or two retries. This even applies to the list commands, and is likely another bug. But there is no need to go into detail about that - just remember that you might have to try some of the commands one or two times more if they fail first time.
# Start from a clean Foreman+Katello installation
# "foreman-installer --scenario katello"
# Create two separate environments (Organizations with user etc)
for idx in 1 2; do
hammer organization create --name TEST${idx}
hammer location create --name TEST${idx}_LOC
hammer role clone --id 3 --new-name 'OrgAdmin'${idx} --organizations TEST${idx}
hammer user create --auth-source Internal --login test${idx} --mail test${idx}@nowhere.nowhere --organizations TEST${idx} --locations TEST${idx}_LOC --password test${idx} --roles OrgAdmin${idx}
hammer hostgroup create --name hg${idx} --organizations "TEST${idx}"
done
# Shortcuts for hammer access via either test user
hammertest1="hammer -u test1 -p test1"
hammertest2="hammer -u test2 -p test2"
# Create a template - could also use an existing
echo 'some content' | hammer template create --name aaa --file /dev/stdin --type provision --organizations '["Default Organization", "TEST1", "TEST2"]'
# Verify that it has no associations (combinations)
hammer template combination list --provisioning-template aaa
$hammertest1 template combination list --provisioning-template aaa
$hammertest2 template combination list --provisioning-template aaa
# Side note: The user specific hammer commands sometimes fail and then works if retried. Bug...?
# Associate template, each user to the hostgroup they see
$hammertest1 template combination create --provisioning-template aaa --hostgroup-title hg1
$hammertest2 template combination create --provisioning-template aaa --hostgroup-title hg2
# Template is now associated to two hostgroups. Both can be seen by admin, and each
# user can see its own hostgroup only. But also an entry for the one belonging to the
# other user ...
hammer template combination list --provisioning-template aaa
---|-----------------------|----------
ID | PROVISIONING TEMPLATE | HOSTGROUP
---|-----------------------|----------
3 | aaa | hg1
4 | aaa | hg2
---|-----------------------|----------
$hammertest1 template combination list --provisioning-template aaa
---|-----------------------|----------
ID | PROVISIONING TEMPLATE | HOSTGROUP
---|-----------------------|----------
3 | aaa | hg1
4 | aaa |
---|-----------------------|----------
$hammertest2 template combination list --provisioning-template aaa
---|-----------------------|----------
ID | PROVISIONING TEMPLATE | HOSTGROUP
---|-----------------------|----------
3 | aaa |
4 | aaa | hg2
---|-----------------------|----------
# First fun test - delete combination 4 which belongs to Org TEST1 by user test2
idx=$($hammertest2 --csv --no-headers template combination list --provisioning-template aaa --fields id,hostgroup | grep -v hg | cut -d, -f1)
$hammertest2 template combination delete --id $idx
# This succeeds - but shouldn't have as that association belongs to another Organization
# Recreate to get same state as before
$hammertest1 template combination create --provisioning-template aaa --hostgroup-title hg1
# Ids have changed, so running the list commands again:
hammer template combination list --provisioning-template aaa
---|-----------------------|----------
ID | PROVISIONING TEMPLATE | HOSTGROUP
---|-----------------------|----------
4 | aaa | hg2
5 | aaa | hg1
---|-----------------------|----------
$hammertest1 template combination list --provisioning-template aaa
---|-----------------------|----------
ID | PROVISIONING TEMPLATE | HOSTGROUP
---|-----------------------|----------
4 | aaa |
5 | aaa | hg1
---|-----------------------|----------
$hammertest2 template combination list --provisioning-template aaa
---|-----------------------|----------
ID | PROVISIONING TEMPLATE | HOSTGROUP
---|-----------------------|----------
4 | aaa | hg2
5 | aaa |
---|-----------------------|----------
# Second test - update as wrong user
# First lets create one more Hostgroup for TEST1
hammer hostgroup create --name hg1b --organizations "TEST1"
# Now, as user test1 update the association belonging to TEST2
idx=$($hammertest1 --csv --no-headers template combination list --provisioning-template aaa --fields id,hostgroup | grep -v hg | cut -d, -f1)
$hammertest1 template combination update --id $idx --hostgroup hg1b
# The interesting part here is that the above command fails. But if you do the exact same
# action in the GUI as user test1 then it succeeds and "steals" the association from TEST2
# In more detail:
# - Login to the GUI as user test1
# - Navigate to Hosts > Templates > Provisioning Templates
# - Click on Template "aaa" to edit it
# - Go to Association and scroll down to bottom
# - In section "Valid Host Groups" there will be two "Host Group" entries, one of which looks blank
# - Click on the drop-down triangle for the blank item and select "hg1b"
# - Click on "Submit" - it will now show the list of all Templates
# - It is now visible that the association changed
# ... and at this point the changed association can also be seen with the same list commands as before
hammer template combination list --provisioning-template aaa
---|-----------------------|----------
ID | PROVISIONING TEMPLATE | HOSTGROUP
---|-----------------------|----------
5 | aaa | hg1
4 | aaa | hg1b
---|-----------------------|----------
$hammertest1 template combination list --provisioning-template aaa
---|-----------------------|----------
ID | PROVISIONING TEMPLATE | HOSTGROUP
---|-----------------------|----------
5 | aaa | hg1
4 | aaa | hg1b
---|-----------------------|----------
$hammertest2 template combination list --provisioning-template aaa
---|-----------------------|----------
ID | PROVISIONING TEMPLATE | HOSTGROUP
---|-----------------------|----------
5 | aaa |
4 | aaa |
---|-----------------------|----------