Skip to content

Commit

Permalink
Add option to disable SELinux and enable forking in authtest
Browse files Browse the repository at this point in the history
SSSD currently has a mutex when calling pam in threaded
more so it is effectively serialized. Add an option to call
PAM using fork() instead to run the authentications
simultaneously.

There is a lock in libsemanage which can cause failures
so disable the SELinux provicer as a workaround for that.

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
  • Loading branch information
rcritten authored and antoniotorresm committed Jul 18, 2022
1 parent 5fc34c5 commit 68b224a
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 6 deletions.
13 changes: 13 additions & 0 deletions src/ipaperftest/core/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -504,3 +504,16 @@ def getLevelName(level):
New-ADUser -SamAccountName $name -Name $name -AccountPassword $password -Enabled $True
}}
"""

ANSIBLE_AUTHENTICATIONTEST_NOSELINUX_CONFIG_PLAYBOOK = """
---
- name: Disable SELinux in SSSD
hosts: ipaclients
tasks:
- name: "Disable SELinux provider"
become: yes
lineinfile:
path: /etc/sssd/sssd.conf
line: selinux_provider = none
insertafter: id_provider = ipa
"""
3 changes: 3 additions & 0 deletions src/ipaperftest/core/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@ def run(self, ctx):
@click.option("--threads", default=10, help="Threads to run per client during AuthenticationTest.")
@click.option("--ad-threads", default=0, help="Active Directory login threads "
"to run per client during AuthenticationTest.")
@click.option("--disable-selinux", default=False, is_flag=True,
help="Disable the SSSD SELinux provider in all clients, enable forking in pamtest")
@click.option("--command", help="Command to execute during APITest.")
@click.option(
"--results-format",
Expand Down Expand Up @@ -171,6 +173,7 @@ def main(
amount=1,
threads=10,
ad_threads=0,
disable_selinux=False,
replicas=0,
results_format="json",
results_output_file=None,
Expand Down
10 changes: 9 additions & 1 deletion src/ipaperftest/plugins/authenticationtest.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
ANSIBLE_AUTHENTICATIONTEST_AD_SERVER_CONFIG_PLAYBOOK,
ANSIBLE_AUTHENTICATIONTEST_AD_SERVER_ESTABLISH_TRUST_PLAYBOOK,
ANSIBLE_AUTHENTICATIONTEST_AD_SERVER_CREATE_USERS_PLAYBOOK,
ANSIBLE_AUTHENTICATIONTEST_NOSELINUX_CONFIG_PLAYBOOK,
ANSIBLE_COUNT_IPA_HOSTS_PLAYBOOK)
from ipaperftest.plugins.registry import registry

Expand Down Expand Up @@ -180,6 +181,12 @@ def run(self, ctx):
error="Failed to convert host-find output to int. "
"Value was: %s" % host_find_output)

if ctx.params["disable_selinux"]:
self.run_ansible_playbook_from_template(
ANSIBLE_AUTHENTICATIONTEST_NOSELINUX_CONFIG_PLAYBOOK,
"authenticationtest_no_selinux", {}, ctx
)

# Client authentications will be triggered at now + 1min per 20 clients
client_auth_time = (
int(time.time()) + max(int(len(self.provider.hosts.keys()) / 20), 1) * 60
Expand All @@ -197,7 +204,8 @@ def run(self, ctx):
sleep_time += 20
cmds = [
"sleep $(( {} - $(date +%s) ))".format(str(client_auth_time)),
"sudo pamtest --threads {} --ad-threads {} -o pamtest.log".format(
"sudo pamtest {} --threads {} --ad-threads {} -o pamtest.log".format(
'-f' if ctx.params["disable_selinux"] else '',
str(ctx.params["threads"]),
str(ctx.params["ad_threads"])
),
Expand Down
43 changes: 38 additions & 5 deletions src/pamtest.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
#include <sys/utsname.h>
#include <errno.h>
#include <string.h>
#include <sys/wait.h>


/* The only global, the name of the PAM service */
char * pam_service = NULL;
Expand Down Expand Up @@ -109,23 +111,30 @@ int main(int argc, const char **argv)
char **ad_usernames = NULL;
int c, i;
int ret = 0;
int dofork = 0;
int status = 0;
struct utsname uinfo;
poptContext pctx;
struct poptOption popts[] = {
{"outfile", 'o', POPT_ARG_STRING, NULL, 'o', NULL, "FILE"},
{"service", 's', POPT_ARG_STRING, NULL, 's', NULL, "SERVICE"},
{"threads", 't', POPT_ARG_INT, &threads, 0, NULL, NULL},
{"ad-threads", 'a', POPT_ARG_INT, &ad_logins, 0, NULL, NULL},
{"fork", 'f', POPT_ARG_NONE, NULL, 'f', NULL, NULL},
POPT_AUTOHELP
POPT_TABLEEND
};
pid_t pid;

pctx = poptGetContext("thread", argc, argv, popts, 0);
if (pctx == NULL) {
return -1;
}
while ((c = poptGetNextOpt(pctx)) > 0) {
switch (c) {
case 'f':
dofork = 1;
break;
case 'o':
logfile = poptGetOptArg(pctx);
break;
Expand Down Expand Up @@ -200,7 +209,6 @@ int main(int argc, const char **argv)

for (i = 0; i < ipa_logins; i++) {
asprintf(&usernames[i], "user%d%s", i, uinfo.nodename);
index[i] = pthread_create(&ptr[i], NULL, (void *) call_pam, usernames[i]);
}

for (i = 0; i < ad_logins; i++) {
Expand All @@ -209,13 +217,38 @@ int main(int argc, const char **argv)
char host[10];
memcpy(host, uinfo.nodename, 9);
asprintf(&ad_usernames[i], "user%03d%s@ad.test", i, host);
index[ipa_logins + i] = pthread_create(&ptr[ipa_logins + i], NULL, (void *) call_pam, ad_usernames[i]);
}

for (i = 0; i < threads; i++) {
pthread_join(ptr[i], NULL);
}
if (dofork) {
for (i = 0; i < ipa_logins; i++) {
pid = fork();
switch(pid) {
case -1: /* failure */
fprintf(stderr, "fork() error: %s\n", strerror(errno));
exit(1);
break;
case 0: /* child */
call_pam(usernames[i]);
exit(0);
break;
default: /* parent */
break;
}
}
waitpid(-1, &status, 0);
} else { // threads
for (i = 0; i < ipa_logins; i++) {
index[i] = pthread_create(&ptr[i], NULL, (void *) call_pam, usernames[i]);
}

for (i = 0; i < ad_logins; i++) {
index[ipa_logins + i] = pthread_create(&ptr[ipa_logins + i], NULL, (void *) call_pam, ad_usernames[i]);
}

for (i = 0; i < threads; i++) {
pthread_join(ptr[i], NULL);
}
}
for (i = 0; i < ad_logins; i++) {
free(ad_usernames[i]);
}
Expand Down

0 comments on commit 68b224a

Please sign in to comment.