Crash Course
This is a crash course for SSSD’s test framework. The course consists of multiple task that show the fundamental features and API. First, try to find the solution for the task by yourself using the information present in the documentation and inside the hints. Then display the task’s solution and compare it with yours.
Prepare the environment
See Running tests to se how to prepare the environment and run the tests.
Is everything working?
You should be ready to execute the tests, if you setup the environment
correctly. Go to the system tests directory (src/tests/system
) of SSSD
repository and run the tests from this course with:
$ pytest --mh-config=./mhc.yaml --mh-log-path=./log -v ./docs/course/test_course.py
Take the Course
You can begin by creating a file inside the tests
directory, for example
tests/test_course.py
and include the following imports:
from __future__ import annotations
import pytest
from sssd_test_framework.roles.client import Client
from sssd_test_framework.roles.generic import GenericADProvider, GenericProvider
from sssd_test_framework.roles.ipa import IPA
from sssd_test_framework.roles.ldap import LDAP
from sssd_test_framework.topology import KnownTopology, KnownTopologyGroup
Now try to run the file with pytest
:
pytest --mh-config=./mhc.yaml --mh-log-path=./log -v ./tests/test_course.py
Does it work? Good. Now, you can continue with the following tasks.
Tasks 1 to 14 will teach you how to write some basic tests for LDAP.
Tasks 15 - 26 requires you to write the same tests but for IPA. You will see that it is pretty much the same except some differences in primary group - IPA creates primary groups automatically.
Tasks 26 - 31 are about topology parametrization - writing single test for multiple backends.
Task 1
Write your first test for the LDAP topology. The test does not have to do anything, just define it and make sure you can run it successfully.
Display hints
Display solution
@pytest.mark.topology(KnownTopology.LDAP)
def test_ldap__skeleton(client: Client, ldap: LDAP):
"""
:title: Pytest-mh test skeleton for the LDAP topology that does nothing
:customerscenario: False
"""
pass
Task 2
Create a new test for LDAP topology.
Add new LDAP user named
tuser
.Start SSSD on the client.
Run
id
command on the clientCheck
id
result: check that the user exist and has correct name.
Display hints
Display solution
@pytest.mark.topology(KnownTopology.LDAP)
def test_ldap__id__name(client: Client, ldap: LDAP):
"""
:title: LDAP: Calling "id user" yields the expected user
:setup:
1. Add LDAP user "tuser"
2. Start SSSD
:steps:
1. Run "id tuser"
:expectedresults:
1. "tuser" is returned
:customerscenario: False
"""
ldap.user("tuser").add()
client.sssd.start()
result = client.tools.id("tuser")
assert result is not None
assert result.user.name == "tuser"
Task 3
Create a new test for LDAP topology.
Add new LDAP user named
tuser
with uid and gid set to10001
.Start SSSD on the client.
Run
id
command on the clientCheck
id
result: check that the user exist and has correct name, uid, gid.Also check that the primary group of the user does not exist.
Display hints
Display solution
@pytest.mark.topology(KnownTopology.LDAP)
def test_ldap__id__name_and_id(client: Client, ldap: LDAP):
"""
:title: LDAP: Calling "id user" yields the expected user, uid and gid
:setup:
1. Add LDAP user "tuser" with uid=10001, gid=10001
2. Start SSSD
:steps:
1. Run "id tuser"
:expectedresults:
1. "tuser" is returned, uid is 10001, gid is 10001
:customerscenario: False
"""
ldap.user("tuser").add(uid=10001, gid=10001)
client.sssd.start()
result = client.tools.id("tuser")
assert result is not None
assert result.user.name == "tuser"
assert result.user.id == 10001
assert result.group.name is None
assert result.group.id == 10001
Task 4
Create a new test for LDAP topology.
Add new LDAP user named
tuser
with uid and gid set to10001
.Add new LDAP group named
tuser
with gid set to10001
.Start SSSD on the client.
Run
id
command on the clientCheck
id
result: check that the user exist and has correct name, uid, primary group name and gid.
Display hints
Display solution
@pytest.mark.topology(KnownTopology.LDAP)
def test_ldap__id__primary_group(client: Client, ldap: LDAP):
"""
:title: LDAP: Calling "id user" yields the expected user and expected primary group
:setup:
1. Add LDAP user "tuser" with uid=10001, gid=10001
2. Add LDAP group "tuser" with gid 10001
3. Start SSSD
:steps:
1. Run "id tuser"
:expectedresults:
1. "tuser" is returned, user and group name is "tuser", uid and gid is 10001
:customerscenario: False
"""
ldap.user("tuser").add(uid=10001, gid=10001)
ldap.group("tuser").add(gid=10001)
client.sssd.start()
result = client.tools.id("tuser")
assert result is not None
assert result.user.name == "tuser"
assert result.user.id == 10001
assert result.group.name == "tuser"
assert result.group.id == 10001
Task 5
Create a new test for LDAP topology.
Add new LDAP user named
tuser
with uid and gid set to10001
.Add new LDAP group named
tuser
with gid set to10001
.Add new LDAP group named
users
with gid set to20001
.Add user
tuser
as a member of groupusers
Start SSSD on the client.
Run
id
command on the clientCheck
id
result: check that the user exist and has correct name, uid, primary group name and gid.Check that the user is member of
users
Display hints
Display solution
@pytest.mark.topology(KnownTopology.LDAP)
def test_ldap__id__one_supplementary_group(client: Client, ldap: LDAP):
"""
:title: LDAP: Calling "id user" yields the expected user and one expected supplementary groups
:setup:
1. Add LDAP user "tuser" with uid=10001, gid=10001
2. Add LDAP group "tuser" with gid 10001
3. Add LDAP group "users" with gid 20001
4. Make user "tuser" member of "users"
5. Start SSSD
:steps:
1. Run "id tuser"
:expectedresults:
1. "tuser" is returned and the user is member of "users"
:customerscenario: False
"""
u = ldap.user("tuser").add(uid=10001, gid=10001)
ldap.group("tuser").add(gid=10001)
ldap.group("users").add(gid=20001).add_member(u)
client.sssd.start()
result = client.tools.id("tuser")
assert result is not None
assert result.user.name == "tuser"
assert result.user.id == 10001
assert result.group.name == "tuser"
assert result.group.id == 10001
assert result.memberof("users")
See also
The memberof method allows you to use multiple input types. Including group name (string), group id (int) and list of names or ids.
Task 6
Create a new test for LDAP topology.
Add new LDAP user named
tuser
with uid and gid set to10001
.Add new LDAP group named
tuser
with gid set to10001
.Add two LDAP groups named
users
andadmins
without any gid set.Add user
tuser
as a member of groupsusers
andadmins
Start SSSD on the client.
Run
id
command on the clientCheck
id
result: check that the user exist and has correct name, uid, primary group name and gid.Check that the user is member of both
users
andadmins
Display hints
Display solution
@pytest.mark.topology(KnownTopology.LDAP)
def test_ldap__id__two_supplementary_groups(client: Client, ldap: LDAP):
"""
:title: LDAP: Calling "id user" yields the expected user and two expected supplementary groups
:setup:
1. Add LDAP user "tuser" with uid=10001, gid=10001
2. Add LDAP group "tuser" with gid 10001
3. Add LDAP group "users"
4. Add LDAP group "admins"
5. Make user "tuser" member of "users" and "admins"
6. Start SSSD
:steps:
1. Run "id tuser"
:expectedresults:
1. "tuser" is returned and the user is member of "users" and "admins"
:customerscenario: False
"""
u = ldap.user("tuser").add(uid=10001, gid=10001)
ldap.group("tuser").add(gid=10001)
ldap.group("users").add().add_member(u)
ldap.group("admins").add().add_member(u)
client.sssd.start()
result = client.tools.id("tuser")
assert result is not None
assert result.user.name == "tuser"
assert result.user.id == 10001
assert result.group.name == "tuser"
assert result.group.id == 10001
assert result.memberof(["users", "admins"])
Note
If you omit uid or gid attribute on user or group then the id is automatically generated by the framework. This is useful for cases where the id is not important.
Task 7
Create a new test for LDAP topology.
Add new LDAP user named
tuser
with password set toSecret123
.Start SSSD on the client.
Test that the user can authenticate via
su
with the password.
Display solution
@pytest.mark.topology(KnownTopology.LDAP)
def test_ldap__su(client: Client, ldap: LDAP):
"""
:title: LDAP: Authenticate user with password using "su"
:setup:
1. Add LDAP user "tuser" with password "Secret123"
2. Start SSSD
:steps:
1. Run "su tuser" with correct password
:expectedresults:
1. Authentication is successful
:customerscenario: False
"""
ldap.user("tuser").add(password="Secret123")
client.sssd.start()
assert client.auth.su.password("tuser", "Secret123")
Note
The password parameter defaults to Secret123
so it can be omitted.
However, it is a good practice to set it explicitly when you test
authentication to help understand the test case.
Task 8
Create a new test for LDAP topology.
Add new LDAP user named
tuser
with password set toSecret123
.Start SSSD on the client.
Test that the user can authenticate via
ssh
with the password.
Display solution
@pytest.mark.topology(KnownTopology.LDAP)
def test_ldap__ssh(client: Client, ldap: LDAP):
"""
:title: LDAP: Authenticate user with password using "ssh"
:setup:
1. Add LDAP user "tuser" with password "Secret123"
2. Start SSSD
:steps:
1. Run "ssh tuser@localhost" with correct password
:expectedresults:
1. Authentication is successful
:customerscenario: False
"""
ldap.user("tuser").add(password="Secret123")
client.sssd.start()
assert client.auth.ssh.password("tuser", "Secret123")
Task 9
Create a new test for LDAP topology.
Parametrize a test case argument with two values:
su
andssh
Add new LDAP user named
tuser
with password set toSecret123
.Start SSSD on the client.
Test that the user can authenticate via
su
andssh
with the password, use the parametrized value to determine which method should be used.
Display solution
@pytest.mark.topology(KnownTopology.LDAP)
@pytest.mark.parametrize("method", ["su", "ssh"])
def test_ldap__password_authentication(client: Client, ldap: LDAP, method: str):
"""
:title: LDAP: Authenticate user with password using "@method"
:setup:
1. Add LDAP user "tuser" with password "Secret123"
2. Start SSSD
:steps:
1. Try authenticate the user with password using @method
:expectedresults:
1. Authentication is successful
:customerscenario: False
"""
ldap.user("tuser").add(password="Secret123")
client.sssd.start()
assert client.auth.parametrize(method).password("tuser", "Secret123")
Note
This produces two test runs: one for su
authentication and one for
ssh
. It is better to parametrize the test instead of calling both
su
and ssh
in one test run so you can test only one thing at a
time if you ever need to debug failure.
Task 10
Create a new test for LDAP topology.
Add new LDAP user named
tuser
with password set toSecret123
.Add new sudo rule to LDAP that allows the user to run
/bin/ls
onALL
hosts.Select
sssd
authselect profile withwith-sudo
enabled.Enable sudo responder in SSSD.
Start SSSD on the client.
Check that
tuser
can run only/bin/ls
command and only asroot
.Check that running
/bin/ls
throughsudo
actually works fortuser
.
Display hints
Display solution
@pytest.mark.topology(KnownTopology.LDAP)
def test_ldap__sudo__passwd(client: Client, ldap: LDAP):
"""
:title: LDAP: User can run command via sudo when authentication is required
:setup:
1. Add LDAP user "tuser" with password "Secret123"
2. Create sudo rule that allows the user to run "/bin/ls" as root on all hosts
3. Enable SSSD sudo responder and configure sudo to use SSSD
4. Start SSSD
:steps:
1. Login as "tuser" and run "sudo -l" with user password
2. Login as "tuser" and run "sudo /bin/ls /root" with user password
:expectedresults:
1. The created rule is listed in the output
2. The command run successfully as root
:customerscenario: False
"""
u = ldap.user("tuser").add(password="Secret123")
ldap.sudorule("allow_ls").add(user=u, host="ALL", command="/bin/ls")
client.sssd.common.sudo()
client.sssd.start()
assert client.auth.sudo.list("tuser", "Secret123", expected=["(root) /bin/ls"])
assert client.auth.sudo.run("tuser", "Secret123", command="/bin/ls /root")
Note
You need to enable with-sudo
using authselect so sudo can read rules
from SSSD. You can use sssd_test_framework.utils.sssd.SSSDCommonConfiguration.sudo()
as a shortcut for selecting authselect profile and enabling the sudo responder.
Task 11
Create a new test for LDAP topology.
Add new LDAP user named
tuser
.Add new sudo rule to LDAP that allows the user to run
/bin/ls
onALL
hosts but without requiring authentication (nopasswd).Select
sssd
authselect profile withwith-sudo
enabled.Enable sudo responder in SSSD.
Start SSSD on the client.
Check that
tuser
can run only/bin/ls
command without a password and only asroot
.Check that running
/bin/ls
throughsudo
actually works fortuser
without a password.
Display hints
Display solution
@pytest.mark.topology(KnownTopology.LDAP)
def test_ldap__sudo__nopasswd(client: Client, ldap: LDAP):
"""
:title: LDAP: User can run command via sudo when authentication is not required
:setup:
1. Add LDAP user "tuser"
2. Create sudo rule that allows the user to run "/bin/ls" as root on all hosts, !authenticate option is set
3. Enable SSSD sudo responder and configure sudo to use SSSD
4. Start SSSD
:steps:
1. Login as "tuser" and run "sudo -l", no password is provided
2. Login as "tuser" and run "sudo /bin/ls /root", no password is provided
:expectedresults:
1. The created rule is listed in the output
2. The command run successfully as root
:customerscenario: False
"""
u = ldap.user("tuser").add()
ldap.sudorule("allow_ls").add(user=u, host="ALL", command="/bin/ls", nopasswd=True)
client.sssd.common.sudo()
client.sssd.start()
assert client.auth.sudo.list("tuser", expected=["(root) NOPASSWD: /bin/ls"])
assert client.auth.sudo.run("tuser", command="/bin/ls /root")
Task 12
Create a new test for LDAP topology.
Add new LDAP user named
tuser
.Set
use_fully_qualified_names
totrue
on the client.Start SSSD on the client.
Check that
tuser
does not exist.Check that
tuser@test
exists.
Display hints
Display solution
@pytest.mark.topology(KnownTopology.LDAP)
def test_ldap__id__required_fqn(client: Client, ldap: LDAP):
"""
:title: LDAP: Calling "id user@domain" yields the expected user
:setup:
1. Add LDAP user "tuser"
2. Set use_fully_qualified_names to true for the LDAP domain
3. Start SSSD
:steps:
1. Run "id tuser@domain"
:expectedresults:
1. "tuser" is returned
:customerscenario: False
"""
ldap.user("tuser").add()
client.sssd.domain["use_fully_qualified_names"] = "true"
client.sssd.start()
assert client.tools.id("tuser") is None
assert client.tools.id("tuser@test") is not None
Note
Changes to the configuration are automatically applied when calling
client.sssd.start()
. You can override this behavior by calling
client.sssd.start(apply_config=False)
.
Task 13
Create a new test for LDAP topology.
Add new LDAP user named
tuser
.Set
use_fully_qualified_name
totrue
on the client (intentionally create a typo in the option name).Start SSSD on the client.
Assert that an
Exception
was risen
Display hints
Display solution
@pytest.mark.topology(KnownTopology.LDAP)
def test_ldap__config_typo(client: Client, ldap: LDAP):
"""
:title: LDAP: Typo in SSSD option makes sssctl config-check fail
:setup:
1. Add LDAP user "tuser"
2. Set use_fully_qualified_name (not _names) to true for the LDAP domain
:steps:
1. Run sssctl config-check
:expectedresults:
1. The command fails
:customerscenario: False
Note that client.sssd.start() calls sssctl config-check prior starting SSSD.
"""
ldap.user("tuser").add()
with pytest.raises(Exception):
client.sssd.domain["use_fully_qualified_name"] = "true"
client.sssd.start()
Note
Starting SSSD with client.sssd.start()
automatically validates
configuration with sssctl config-check
. If the validation fails, it
raises an exception. You can override this behavior by calling
client.sssd.start(check_config=False)
.
Task 14
Create a new test for LDAP topology.
Add new LDAP user named
tuser
with uid and gid set to10001
.Add new LDAP group named
tuser
with gid set to10001
, use rfc2307bis schema.Add two LDAP groups named
users
andadmins
without any gid set, use rfc2307bis schema.Add user
tuser
as a member of groupsusers
andadmins
Set
ldap_schema
torfc2307bis
on the clientStart SSSD on the client.
Run
id
command on the clientCheck
id
result: check that the user exist and has correct name, uid, primary group name and gid.Check that the user is member of both
users
andadmins
Display hints
Display solution
@pytest.mark.topology(KnownTopology.LDAP)
def test_ldap__id__rfc2307bis(client: Client, ldap: LDAP):
"""
:title: LDAP: Calling "id user" yields the expected user and groups with rfc2307bis schema
:setup:
1. Add LDAP user "tuser" with uid=10001, gid=10001
2. Add LDAP group "tuser" with gid 10001 using rfc2307bis schema
3. Add LDAP group "users" using rfc2307bis schema
4. Add LDAP group "admins" using rfc2307bis schema
5. Make user "tuser" member of "users" and "admins"
6. Set ldap_schema = rfc2307bis for the LDAP domain
7. Start SSSD
:steps:
1. Run "id tuser"
:expectedresults:
1. "tuser" is returned and the user is member of "users" and "admins"
:customerscenario: False
"""
u = ldap.user("tuser").add(uid=10001, gid=10001)
ldap.group("tuser", rfc2307bis=True).add(gid=10001)
ldap.group("users", rfc2307bis=True).add().add_member(u)
ldap.group("admins", rfc2307bis=True).add().add_member(u)
client.sssd.domain["ldap_schema"] = "rfc2307bis"
client.sssd.start()
result = client.tools.id("tuser")
assert result is not None
assert result.user.name == "tuser"
assert result.user.id == 10001
assert result.group.name == "tuser"
assert result.group.id == 10001
assert result.memberof(["users", "admins"])
Task 15
Write your first test for the IPA topology. The test does not have to do anything, just define it and make sure you can run it successfully.
Display hints
Display solution
@pytest.mark.topology(KnownTopology.IPA)
def test_ipa__skeleton(client: Client, ipa: IPA):
"""
:title: Pytest-mh test skeleton for the IPA topology that does nothing
:customerscenario: False
"""
pass
Task 16
Create a new test for IPA topology.
Add new IPA user named
tuser
.Start SSSD on the client.
Run
id
command on the clientCheck
id
result: check that the user exist and has correct name.
Display hints
Display solution
@pytest.mark.topology(KnownTopology.IPA)
def test_ipa__id__name(client: Client, ipa: IPA):
"""
:title: IPA: Calling "id user" yields the expected user
:setup:
1. Add IPA user "tuser"
2. Start SSSD
:steps:
1. Run "id tuser"
:expectedresults:
1. "tuser" is returned
:customerscenario: False
"""
ipa.user("tuser").add()
client.sssd.start()
result = client.tools.id("tuser")
assert result is not None
assert result.user.name == "tuser"
Task 17
Create a new test for IPA topology.
Add new IPA user named
tuser
with uid and gid set to10001
.Start SSSD on the client.
Run
id
command on the clientCheck
id
result: check that the user exist and has correct name, uid, primary group name and gid.
Display hints
Display solution
@pytest.mark.topology(KnownTopology.IPA)
def test_ipa__id__primary_group(client: Client, ipa: IPA):
"""
:title: IPA: Calling "id user" yields the expected user and primary group
:setup:
1. Add IPA user "tuser" with uid=10001, gid=10001
2. Start SSSD
:steps:
1. Run "id tuser"
:expectedresults:
1. "tuser" is returned, uid is 10001, gid is 10001
:customerscenario: False
"""
ipa.user("tuser").add(uid=10001, gid=10001)
# Primary group is created automatically, we need to skip this step
# ipa.group('tuser').add(gid=10001)
client.sssd.start()
result = client.tools.id("tuser")
assert result is not None
assert result.user.name == "tuser"
assert result.user.id == 10001
assert result.group.name == "tuser"
assert result.group.id == 10001
Note
Unlike LDAP, IPA creates the primary group automatically therefore we do not have to add it ourselves.
Task 18
Create a new test for IPA topology.
Add new IPA user named
tuser
with uid and gid set to10001
.Add new IPA group named
users
with gid set to20001
.Add user
tuser
as a member of groupusers
Start SSSD on the client.
Run
id
command on the clientCheck
id
result: check that the user exist and has correct name, uid, primary group name and gid.Check that the user is member of
users
Display hints
Display solution
@pytest.mark.topology(KnownTopology.IPA)
def test_ipa__id__one_supplementary_group(client: Client, ipa: IPA):
"""
:title: IPA: Calling "id user" yields the expected user and one expected supplementary groups
:setup:
1. Add IPA user "tuser" with uid=10001, gid=10001
2. Add IPA group "users" with gid 20001
3. Make user "tuser" member of "users"
4. Start SSSD
:steps:
1. Run "id tuser"
:expectedresults:
1. "tuser" is returned and the user is member of "users"
:customerscenario: False
"""
u = ipa.user("tuser").add(uid=10001, gid=10001)
# Primary group is created automatically, we need to skip this step
# ipa.group('tuser').add(gid=10001)
ipa.group("users").add(gid=20001).add_member(u)
client.sssd.start()
result = client.tools.id("tuser")
assert result is not None
assert result.user.name == "tuser"
assert result.user.id == 10001
assert result.group.name == "tuser"
assert result.group.id == 10001
assert result.memberof("users")
Task 19
Create a new test for IPA topology.
Add new IPA user named
tuser
with uid and gid set to10001
.Add new IPA group named
users
without any gid set.Create a group object for IPA group
admins
that already exist (it is created by IPA installation)Add user
tuser
as a member of groupsusers
andadmins
Start SSSD on the client.
Run
id
command on the clientCheck
id
result: check that the user exist and has correct name, uid, primary group name and gid.Check that the user is member of both
users
andadmins
Display hints
Display solution
@pytest.mark.topology(KnownTopology.IPA)
def test_ipa__id__two_supplementary_groups(client: Client, ipa: IPA):
"""
:title: IPA: Calling "id user" yields the expected user and two expected supplementary groups
:setup:
1. Add IPA user "tuser" with uid=10001, gid=10001
2. Add IPA group "users"
3. Make user "tuser" member of "users" and "admins"
4. Start SSSD
:steps:
1. Run "id tuser"
:expectedresults:
1. "tuser" is returned and the user is member of "users" and "admins"
:customerscenario: False
"""
u = ipa.user("tuser").add(uid=10001, gid=10001)
# Primary group is created automatically, we need to skip this step
# ipa.group('tuser').add(gid=10001)
ipa.group("users").add().add_member(u)
# Group admins is already present in IPA so we just omit add() and use add_member() only
# ipa.group('admins').add().add_member(u)
ipa.group("admins").add_member(u)
client.sssd.start()
result = client.tools.id("tuser")
assert result is not None
assert result.user.name == "tuser"
assert result.user.id == 10001
assert result.group.name == "tuser"
assert result.group.id == 10001
assert result.memberof(["users", "admins"])
Task 20
Create a new test for IPA topology.
Add new IPA user named
tuser
with password set toSecret123
.Start SSSD on the client.
Test that the user can authenticate via
su
with the password.
Display solution
@pytest.mark.topology(KnownTopology.IPA)
def test_ipa__su(client: Client, ipa: IPA):
"""
:title: IPA: Authenticate user with password using "su"
:setup:
1. Add IPA user "tuser" with password "Secret123"
2. Start SSSD
:steps:
1. Run "su tuser" with correct password
:expectedresults:
1. Authentication is successful
:customerscenario: False
"""
ipa.user("tuser").add(password="Secret123")
client.sssd.start()
assert client.auth.su.password("tuser", "Secret123")
Task 21
Create a new test for IPA topology.
Add new IPA user named
tuser
with password set toSecret123
.Start SSSD on the client.
Test that the user can authenticate via
ssh
with the password.
Display solution
@pytest.mark.topology(KnownTopology.IPA)
def test_ipa__ssh(client: Client, ipa: IPA):
"""
:title: IPA: Authenticate user with password using "ssh"
:setup:
1. Add IPA user "tuser" with password "Secret123"
2. Start SSSD
:steps:
1. Run "ssh tuser@localhost" with correct password
:expectedresults:
1. Authentication is successful
:customerscenario: False
"""
ipa.user("tuser").add(password="Secret123")
client.sssd.start()
assert client.auth.ssh.password("tuser", "Secret123")
Task 22
Create a new test for IPA topology.
Parametrize a test case argument with two values:
su
andssh
Add new IPA user named
tuser
with password set toSecret123
.Start SSSD on the client.
Test that the user can authenticate via
su
andssh
with the password, use the parametrized value to determine which method should be used.
Display solution
@pytest.mark.topology(KnownTopology.IPA)
@pytest.mark.parametrize("method", ["su", "ssh"])
def test_ipa__password_authentication(client: Client, ipa: IPA, method: str):
"""
:title: IPA: Authenticate user with password using "@method"
:setup:
1. Add IPA user "tuser" with password "Secret123"
2. Start SSSD
:steps:
1. Try authenticate the user with password using @method
:expectedresults:
1. Authentication is successful
:customerscenario: False
"""
ipa.user("tuser").add(password="Secret123")
client.sssd.start()
assert client.auth.parametrize(method).password("tuser", "Secret123")
Task 23
Create a new test for IPA topology.
Add new IPA user named
tuser
with password set toSecret123
.Add new sudo rule to IPA that allows the user to run
/bin/ls
onALL
hosts.Select
sssd
authselect profile withwith-sudo
enabled.Enable sudo responder in SSSD.
Start SSSD on the client.
Check that
tuser
can run only/bin/ls
command and only asroot
.Check that running
/bin/ls
throughsudo
actually works fortuser
.
Display hints
Display solution
@pytest.mark.topology(KnownTopology.IPA)
def test_ipa__sudo__passwd(client: Client, ipa: IPA):
"""
:title: IPA: User can run command via sudo when authentication is required
:setup:
1. Add IPA user "tuser" with password "Secret123"
2. Create sudo rule that allows the user to run "/bin/ls" as root on all hosts
3. Enable SSSD sudo responder and configure sudo to use SSSD
4. Start SSSD
:steps:
1. Login as "tuser" and run "sudo -l" with user password
2. Login as "tuser" and run "sudo /bin/ls /root" with user password
:expectedresults:
1. The created rule is listed in the output
2. The command run successfully as root
:customerscenario: False
"""
u = ipa.user("tuser").add(password="Secret123")
ipa.sudorule("allow_ls").add(user=u, host="ALL", command="/bin/ls")
client.sssd.common.sudo()
client.sssd.start()
assert client.auth.sudo.list("tuser", "Secret123", expected=["(root) /bin/ls"])
assert client.auth.sudo.run("tuser", "Secret123", command="/bin/ls /root")
Task 24
Create a new test for IPA topology.
Add new IPA user named
tuser
.Add new sudo rule to IPA that allows the user to run
/bin/ls
onALL
hosts but without requiring authentication (nopasswd).Select
sssd
authselect profile withwith-sudo
enabled.Enable sudo responder in SSSD.
Start SSSD on the client.
Check that
tuser
can run only/bin/ls
command without a password and only asroot
.Check that running
/bin/ls
throughsudo
actually works fortuser
without a password.
Display hints
Display solution
@pytest.mark.topology(KnownTopology.IPA)
def test_ipa__sudo__nopasswd(client: Client, ipa: IPA):
"""
:title: IPA: User can run command via sudo when authentication is not required
:setup:
1. Add IPA user "tuser"
2. Create sudo rule that allows the user to run "/bin/ls" as root on all hosts, !authenticate option is set
3. Enable SSSD sudo responder and configure sudo to use SSSD
4. Start SSSD
:steps:
1. Login as "tuser" and run "sudo -l", no password is provided
2. Login as "tuser" and run "sudo /bin/ls /root", no password is provided
:expectedresults:
1. The created rule is listed in the output
2. The command run successfully as root
:customerscenario: False
"""
u = ipa.user("tuser").add()
ipa.sudorule("allow_ls").add(user=u, host="ALL", command="/bin/ls", nopasswd=True)
client.sssd.common.sudo()
client.sssd.start()
assert client.auth.sudo.list("tuser", expected=["(root) NOPASSWD: /bin/ls"])
assert client.auth.sudo.run("tuser", command="/bin/ls /root")
Task 25
Create a new test for IPA topology.
Add new IPA user named
tuser
.Set
use_fully_qualified_names
totrue
on the client.Start SSSD on the client.
Check that
tuser
does not exist.Check that
tuser@test
exists.
Display hints
Display solution
@pytest.mark.topology(KnownTopology.IPA)
def test_ipa__id__required_fqn(client: Client, ipa: IPA):
"""
:title: IPA: Calling "id user@domain" yields the expected user
:setup:
1. Add IPA user "tuser"
2. Set use_fully_qualified_names to true for the IPA domain
3. Start SSSD
:steps:
1. Run "id tuser@domain"
:expectedresults:
1. "tuser" is returned
:customerscenario: False
"""
ipa.user("tuser").add()
client.sssd.domain["use_fully_qualified_names"] = "true"
client.sssd.start()
assert client.tools.id("tuser") is None
assert client.tools.id("tuser@test") is not None
Task 26
Create a new test for IPA topology.
Add new IPA user named
tuser
.Set
use_fully_qualified_name
totrue
on the client (intentionally create a typo in the option name).Start SSSD on the client.
Assert that an
Exception
was risen
Display hints
Display solution
@pytest.mark.topology(KnownTopology.IPA)
def test_ipa__config_typo(client: Client, ipa: IPA):
"""
:title: IPA: Typo in SSSD option makes sssctl config-check fail
:setup:
1. Add IPA user "tuser"
2. Set use_fully_qualified_name (not _names) to true for the IPA domain
:steps:
1. Run sssctl config-check
:expectedresults:
1. The command fails
:customerscenario: False
Note that client.sssd.start() calls sssctl config-check prior starting SSSD.
"""
ipa.user("tuser").add()
with pytest.raises(Exception):
client.sssd.domain["use_fully_qualified_name"] = "true"
client.sssd.start()
Task 27
Create a new parametrized test for LDAP, IPA, Samba and AD topology.
Add new user named
tuser
.Add new groups
tgroup_1
andtgroup_2
Add the user
tuser
as a member oftgroup_1
andtgroup_2
Start SSSD on the client.
Run
id
command on the clientCheck
id
result: check that the user exist and has correct name.Check that the user is member of
tgroup_1
andtgroup_2
Display hints
Display solution
@pytest.mark.topology(KnownTopologyGroup.AnyProvider)
def test_id__supplementary_groups(client: Client, provider: GenericProvider):
"""
:title: Calling "id user" yields the expected user and supplementary groups
:setup:
1. Add user "tuser"
2. Add group "tgroup_1"
3. Add group "tgroup_2"
4. Make user "tuser" member of "tgroup_1" and "tgroup_2"
5. Start SSSD
:steps:
1. Run "id tuser"
:expectedresults:
1. "tuser" is returned and the user is member of "tgroup_1" and "tgroup_2"
:customerscenario: False
"""
u = provider.user("tuser").add()
provider.group("tgroup_1").add().add_member(u)
provider.group("tgroup_2").add().add_member(u)
client.sssd.start()
result = client.tools.id("tuser")
assert result is not None
assert result.user.name == "tuser"
assert result.memberof(["tgroup_1", "tgroup_2"])
Note
We can write single test that can be run on multiple topologies. This is
achieved by using well-defined API that is implemented by all providers.
However, there are some distinctions that you need to be aware of - for
example LDAP does not create primary group automatically, IPA creates it
automatically and Samba and AD uses Domain Users
as the primary
group.
Task 28
Create a new parametrized test for Samba and AD topology.
Add new user named
tuser
.Start SSSD on the client.
Run
id
command on the clientCheck
id
result: check that the user exist and has correct name.Check that the user is member of
domain users
(Active Directory built-in group)
Display hints
Display solution
@pytest.mark.topology(KnownTopologyGroup.AnyAD)
def test_ad__id__domain_users(client: Client, provider: GenericADProvider):
"""
:title: AD: The primary user group is "Domain Users"
:setup:
1. Add user "tuser"
2. Start SSSD
:steps:
1. Run "id tuser"
:expectedresults:
1. "tuser" is returned and the primary group is "Domain Users" (case insensitive)
:customerscenario: False
"""
provider.user("tuser").add()
client.sssd.start()
result = client.tools.id("tuser")
assert result is not None
assert result.user.name == "tuser"
assert result.group.name is not None
assert result.group.name.lower() == "domain users"
Task 29
Create a new parametrized test for LDAP and IPA topology.
Add new user named
tuser
with uid and gid set to10001
.Create user’s primary group object only if the topology is LDAP
Start SSSD on the client.
Run
id
command on the clientCheck
id
result: check that the user exist and has correct name, uid, primary group name and gid.
Display hints
Display solution
@pytest.mark.topology(KnownTopology.LDAP)
@pytest.mark.topology(KnownTopology.IPA)
def test_id__primary_group(client: Client, provider: GenericProvider):
"""
:title: Calling "id user" yields the expected user and expected primary group
:setup:
1. Add user "tuser" with uid=10001, gid=10001
2. Add group "tuser" with gid 10001
3. Start SSSD
:steps:
1. Run "id tuser"
:expectedresults:
1. "tuser" is returned, user and group name is "tuser", uid and gid is 10001
:customerscenario: False
"""
provider.user("tuser").add(uid=10001, gid=10001)
if isinstance(provider, LDAP):
provider.group("tuser").add(gid=10001)
client.sssd.start()
result = client.tools.id("tuser")
assert result is not None
assert result.user.name == "tuser"
assert result.user.id == 10001
assert result.group.name == "tuser"
assert result.group.id == 10001
Task 30
Create a new test for LDAP, IPA, Samba and AD topology.
Add new user named
tuser
.Add new sudo rule
defaults
and set!authenticate
optionAdd new sudo rule to that
ALL
users onALL
hosts runALL
commands.Select
sssd
authselect profile withwith-sudo
enabled.Enable sudo responder in SSSD.
Start SSSD on the client.
Check that
tuser
can runALL
commands without a password but only asroot
.Check that running
/bin/ls
throughsudo
actually works fortuser
without a password.
Display hints
Display solution
@pytest.mark.topology(KnownTopologyGroup.AnyProvider)
def test_sudo__defaults_nopasswd(client: Client, provider: GenericProvider):
"""
:title: User can run command via sudo when authentication is not required in defaults
:setup:
1. Add user "tuser"
2. Create sudo rule "defaults" with sudoOption set to !authenticate
3. Create sudo rule that allows the all users to run all commands as root on all hosts
4. Enable SSSD sudo responder and configure sudo to use SSSD
5. Start SSSD
:steps:
1. Login as "tuser" and run "sudo -l", no password is provided
2. Login as "tuser" and run "sudo /bin/ls /root", no password is provided
:expectedresults:
1. The created rule is listed in the output
2. The command run successfully as root
:customerscenario: False
"""
provider.user("tuser").add()
provider.sudorule("defaults").add(nopasswd=True)
provider.sudorule("allow_all").add(user="ALL", host="ALL", command="ALL")
client.sssd.common.sudo()
client.sssd.start()
assert client.auth.sudo.list("tuser", expected=["(root) ALL"])
assert client.auth.sudo.run("tuser", command="/bin/ls /root")
Task 31
Create a new parametrized test for LDAP, IPA, Samba and AD topology.
Parametrize a test case argument with two values:
su
andssh
Add new user named
tuser
with password set toSecret123
.Start SSSD on the client.
Test that the user can authenticate via
su
andssh
with the password, use the parametrized value to determine which method should be used.
Display solution
@pytest.mark.topology(KnownTopologyGroup.AnyProvider)
@pytest.mark.parametrize("method", ["su", "ssh"])
def test_authentication__password(client: Client, provider: GenericProvider, method: str):
"""
:title: Authenticate user with password using "@method"
:setup:
1. Add user "tuser" with password "Secret123"
2. Start SSSD
:steps:
1. Try authenticate the user with password using @method
:expectedresults:
1. Authentication is successful
:customerscenario: False
"""
provider.user("tuser").add(password="Secret123")
client.sssd.start()
assert client.auth.parametrize(method).password("tuser", "Secret123")