freeipa/ipatests/test_integration/test_subids.py

236 lines
8.1 KiB
Python
Raw Normal View History

#
# Copyright (C) 2021 FreeIPA Contributors see COPYING for license
#
"""Tests for subordinate ids
"""
import os
from ipalib.constants import SUBID_COUNT, SUBID_RANGE_START, SUBID_RANGE_MAX
from ipaplatform.paths import paths
from ipatests.pytest_ipa.integration import tasks
from ipatests.test_integration.base import IntegrationTest
class TestSubordinateId(IntegrationTest):
num_replicas = 0
topology = "star"
def _parse_result(self, result):
# ipa CLI should get an --outform json option
info = {}
for line in result.stdout_text.split("\n"):
line = line.strip()
if line:
if ":" not in line:
continue
k, v = line.split(":", 1)
k = k.strip()
v = v.strip()
try:
v = int(v, 10)
except ValueError:
if v == "FALSE":
v = False
elif v == "TRUE":
v = True
info.setdefault(k.lower(), []).append(v)
for k, v in info.items():
if len(v) == 1:
info[k] = v[0]
else:
info[k] = set(v)
return info
def assert_subid_info(self, uid, info):
assert info["ipauniqueid"]
basedn = self.master.domain.basedn
assert info["ipaowner"] == f"uid={uid},cn=users,cn=accounts,{basedn}"
assert info["ipasubuidnumber"] == info["ipasubuidnumber"]
assert info["ipasubuidnumber"] >= SUBID_RANGE_START
assert info["ipasubuidnumber"] <= SUBID_RANGE_MAX
assert info["ipasubuidcount"] == SUBID_COUNT
assert info["ipasubgidnumber"] == info["ipasubgidnumber"]
assert info["ipasubgidnumber"] == info["ipasubuidnumber"]
assert info["ipasubgidcount"] == SUBID_COUNT
def assert_subid(self, uid, *, match):
cmd = ["ipa", "subid-find", "--raw", "--owner", uid]
result = self.master.run_command(cmd, raiseonerr=False)
if not match:
assert result.returncode >= 1
if result.returncode == 1:
assert "0 subordinate ids matched" in result.stdout_text
elif result.returncode == 2:
assert "user not found" in result.stderr_text
return None
else:
assert result.returncode == 0
assert "1 subordinate id matched" in result.stdout_text
info = self._parse_result(result)
self.assert_subid_info(uid, info)
self.master.run_command(
["ipa", "subid-show", info["ipauniqueid"]]
)
return info
def subid_generate(self, uid, **kwargs):
cmd = ["ipa", "subid-generate"]
if uid is not None:
cmd.extend(("--owner", uid))
return self.master.run_command(cmd, **kwargs)
def test_auto_generate_subid(self):
uid = "testuser_auto1"
passwd = "Secret123"
tasks.create_active_user(self.master, uid, password=passwd)
tasks.kinit_admin(self.master)
self.assert_subid(uid, match=False)
# add subid by name
self.subid_generate(uid)
info = self.assert_subid(uid, match=True)
# second generate fails due to unique index on ipaowner
result = self.subid_generate(uid, raiseonerr=False)
assert result.returncode > 0
assert f'for user "{uid}" already exists' in result.stderr_text
# check matching
subuid = info["ipasubuidnumber"]
for offset in (0, 1, 65535):
result = self.master.run_command(
["ipa", "subid-match", f"--subuid={subuid + offset}", "--raw"]
)
match = self._parse_result(result)
self.assert_subid_info(uid, match)
def test_ipa_subid_script(self):
tasks.kinit_admin(self.master)
tool = os.path.join(paths.LIBEXEC_IPA_DIR, "ipa-subids")
users = []
for i in range(1, 11):
uid = f"testuser_script{i}"
users.append(uid)
tasks.user_add(self.master, uid)
self.assert_subid(uid, match=False)
cmd = [tool, "--verbose", "--group", "ipausers"]
self.master.run_command(cmd)
for uid in users:
self.assert_subid(uid, match=True)
def test_subid_selfservice(self):
uid1 = "testuser_selfservice1"
uid2 = "testuser_selfservice2"
password = "Secret123"
role = "Subordinate ID Selfservice User"
tasks.create_active_user(self.master, uid1, password=password)
tasks.create_active_user(self.master, uid2, password=password)
tasks.kinit_user(self.master, uid1, password=password)
self.assert_subid(uid1, match=False)
result = self.subid_generate(uid1, raiseonerr=False)
assert result.returncode > 0
result = self.subid_generate(None, raiseonerr=False)
assert result.returncode > 0
tasks.kinit_admin(self.master)
self.master.run_command(
["ipa", "role-add-member", role, "--groups=ipausers"]
)
try:
tasks.kinit_user(self.master, uid1, password)
self.subid_generate(uid1)
self.assert_subid(uid1, match=True)
# add subid from whoami
tasks.kinit_as_user(self.master, uid2, password=password)
self.subid_generate(None)
self.assert_subid(uid2, match=True)
finally:
tasks.kinit_admin(self.master)
self.master.run_command(
["ipa", "role-remove-member", role, "--groups=ipausers"]
)
def test_subid_useradmin(self):
tasks.kinit_admin(self.master)
uid_useradmin = "testuser_usermgr_mgr1"
role = "User Administrator"
uid = "testuser_usermgr_user1"
password = "Secret123"
# create user administrator
tasks.create_active_user(
self.master, uid_useradmin, password=password
)
# add user to user admin group
tasks.kinit_admin(self.master)
self.master.run_command(
["ipa", "role-add-member", role, f"--users={uid_useradmin}"],
)
# kinit as user admin
tasks.kinit_user(self.master, uid_useradmin, password)
# create new user as user admin
tasks.user_add(self.master, uid)
# assign new subid to user (with useradmin credentials)
self.subid_generate(uid)
# test that user admin can preserve and delete users with subids
self.master.run_command(["ipa", "user-del", "--preserve", uid])
# XXX does not work, see subordinate-ids.md
# subid should still exist
# self.assert_subid(uid, match=True)
# final delete should remove the user and subid
self.master.run_command(["ipa", "user-del", uid])
self.assert_subid(uid, match=False)
def tset_subid_auto_assign(self):
tasks.kinit_admin(self.master)
uid = "testuser_autoassign_user1"
self.master.run_command(
["ipa", "config-mod", "--user-default-subid=true"]
)
try:
tasks.user_add(self.master, uid)
self.assert_subid(uid, match=True)
finally:
self.master.run_command(
["ipa", "config-mod", "--user-default-subid=false"]
)
def test_idrange_subid(self):
tasks.kinit_admin(self.master)
range_name = f"{self.master.domain.realm}_subid_range"
result = self.master.run_command(
["ipa", "idrange-show", range_name, "--raw"]
)
info = self._parse_result(result)
# see https://github.com/SSSD/sssd/issues/5571
assert info["iparangetype"] == "ipa-ad-trust"
assert info["ipabaseid"] == SUBID_RANGE_START
assert info["ipaidrangesize"] == SUBID_RANGE_MAX - SUBID_RANGE_START
assert info["ipabaserid"] < SUBID_RANGE_START
assert "ipasecondarybaserid" not in info
assert info["ipanttrusteddomainsid"].startswith(
"S-1-5-21-738065-838566-"
)
def test_subid_stats(self):
tasks.kinit_admin(self.master)
self.master.run_command(["ipa", "subid-stats"])