diff --git a/src/ipaperftest/core/constants.py b/src/ipaperftest/core/constants.py index 9aa8cde..522cfb3 100644 --- a/src/ipaperftest/core/constants.py +++ b/src/ipaperftest/core/constants.py @@ -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 +""" diff --git a/src/ipaperftest/core/main.py b/src/ipaperftest/core/main.py index 8b0a171..37e989f 100644 --- a/src/ipaperftest/core/main.py +++ b/src/ipaperftest/core/main.py @@ -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", @@ -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, diff --git a/src/ipaperftest/plugins/authenticationtest.py b/src/ipaperftest/plugins/authenticationtest.py index 6ab34ba..344f075 100644 --- a/src/ipaperftest/plugins/authenticationtest.py +++ b/src/ipaperftest/plugins/authenticationtest.py @@ -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 @@ -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 @@ -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"]) ), diff --git a/src/pamtest.c b/src/pamtest.c index 50eaf6e..3eb7f36 100644 --- a/src/pamtest.c +++ b/src/pamtest.c @@ -15,6 +15,8 @@ #include #include #include +#include + /* The only global, the name of the PAM service */ char * pam_service = NULL; @@ -109,6 +111,8 @@ 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[] = { @@ -116,9 +120,11 @@ int main(int argc, const char **argv) {"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) { @@ -126,6 +132,9 @@ int main(int argc, const char **argv) } while ((c = poptGetNextOpt(pctx)) > 0) { switch (c) { + case 'f': + dofork = 1; + break; case 'o': logfile = poptGetOptArg(pctx); break; @@ -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++) { @@ -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]); }