From e4d59ce3f04d60c02a028ce33c66266aafeeb0e0 Mon Sep 17 00:00:00 2001 From: d-w-moore Date: Wed, 3 Jun 2026 11:25:08 -0400 Subject: [PATCH 1/8] [_777] bats wrapper for running original pam_interactive test script --- .../test/scripts/test011_pam_interactive.bats | 46 +++++++++++++++++++ .../single_node/test_script_parameters | 1 + 2 files changed, 47 insertions(+) create mode 100755 irods/test/scripts/test011_pam_interactive.bats diff --git a/irods/test/scripts/test011_pam_interactive.bats b/irods/test/scripts/test011_pam_interactive.bats new file mode 100755 index 000000000..b5b269b11 --- /dev/null +++ b/irods/test/scripts/test011_pam_interactive.bats @@ -0,0 +1,46 @@ +#!/usr/bin/env bats + +# The tests in this BATS module must be run as a (passwordless) sudo-enabled user. +# It is also required that the python irodsclient be installed under irods' ~/.local environment. + +. $BATS_TEST_DIRNAME/test_support_functions + +setup() { + [ -f /tmp/test011_flag ] || { + rm -fr ~/.irods + /prc/test_harness/utility/iinit.py host localhost \ + port 1247 \ + zone tempZone \ + user rods \ + password rods \ + + ## Because iRODS 5+ negotiates for SSL automatically: + CLIENT_JSON=~/.irods/irods_environment.json + jq '.irods_client_server_policy="CS_NEG_REFUSE"' >$CLIENT_JSON.$$ <$CLIENT_JSON && \ + mv $CLIENT_JSON.$$ $CLIENT_JSON + + sudo apt install irods-auth-plugin-pam-interactive-{client,server} + + setup_pam_login_for_user "rods" alice + + # Tests require only the irods_environment.json + rm -f ~/.irods/.irodsA + + ## Switch over to scheme to be tested. + jq '.irods_authentication_scheme="pam_interactive"' >$CLIENT_JSON.$$ <$CLIENT_JSON && \ + mv $CLIENT_JSON.$$ $CLIENT_JSON + } + touch /tmp/test011_flag +} + +original_test_suite() +{ + local USER="alice" + local PASSWORD="rods" + sudo chpasswd <<<"$USER:$PASSWORD" + python -m unittest irods.test.pam_interactive_test_must_run_manually +} + +@test "original_pam_interactive_tests" { + original_test_suite +} diff --git a/test_harness/single_node/test_script_parameters b/test_harness/single_node/test_script_parameters index 4b94d58e6..b4b2d5940 100644 --- a/test_harness/single_node/test_script_parameters +++ b/test_harness/single_node/test_script_parameters @@ -21,6 +21,7 @@ declare -A wrappers=( [test008_prc_write_irodsA_utility_in_native_mode.bats]=../login_auth_test.sh [test009_test_special_characters_in_pam_passwords_auth_framework.bats]=../login_auth_test.sh [test010_issue_362_rogue_chars_in_pam_password.bats]=../login_auth_test.sh + [test011_pam_interactive.bats]=../login_auth_test.sh ) # keys for Image and User refer to the basename after resolution to a wrapper if one is used From d134e0dcc8fa02db7b3697f5486a60cc3014d131 Mon Sep 17 00:00:00 2001 From: d-w-moore Date: Thu, 18 Jun 2026 14:53:16 -0400 Subject: [PATCH 2/8] changes for test012 --- .../test012_pam_interactive_multistep.bats | 47 +++++++++++++++++++ irods/test/scripts/test_support_functions | 6 ++- .../single_node/docker_container_driver.sh | 9 +++- .../single_node/test_script_parameters | 1 + 4 files changed, 61 insertions(+), 2 deletions(-) create mode 100755 irods/test/scripts/test012_pam_interactive_multistep.bats diff --git a/irods/test/scripts/test012_pam_interactive_multistep.bats b/irods/test/scripts/test012_pam_interactive_multistep.bats new file mode 100755 index 000000000..7378a1c7b --- /dev/null +++ b/irods/test/scripts/test012_pam_interactive_multistep.bats @@ -0,0 +1,47 @@ +#!/usr/bin/env bats + +# The tests in this BATS module must be run as a (passwordless) sudo-enabled user. +# It is also required that the python irodsclient be installed under irods' ~/.local environment. + +. $BATS_TEST_DIRNAME/test_support_functions + +setup() { + [ -f /tmp/test012_flag ] || { + rm -fr ~/.irods + /prc/test_harness/utility/iinit.py host localhost \ + port 1247 \ + zone tempZone \ + user rods \ + password rods \ + + ## Because iRODS 5+ negotiates for SSL automatically: + CLIENT_JSON=~/.irods/irods_environment.json + jq '.irods_client_server_policy="CS_NEG_REFUSE"' >$CLIENT_JSON.$$ <$CLIENT_JSON && \ + mv $CLIENT_JSON.$$ $CLIENT_JSON + + sudo apt install irods-auth-plugin-pam-interactive-{client,server} + + setup_pam_login_for_user "rods" alice + + # Tests require only the irods_environment.json + rm -f ~/.irods/.irodsA + + ## Switch over to scheme to be tested. + jq '.irods_authentication_scheme="pam_interactive"' >$CLIENT_JSON.$$ <$CLIENT_JSON && \ + mv $CLIENT_JSON.$$ $CLIENT_JSON + } + touch /tmp/test012_flag +} + +original_test_suite() +{ +: +# local USER="alice" +# local PASSWORD="rods" +# sudo chpasswd <<<"$USER:$PASSWORD" +# python -m unittest irods.test.pam_interactive_test_must_run_manually +} + +@test "original_pam_interactive_tests" { + original_test_suite +} diff --git a/irods/test/scripts/test_support_functions b/irods/test/scripts/test_support_functions index a7e40bfe4..04e85748e 100644 --- a/irods/test/scripts/test_support_functions +++ b/irods/test/scripts/test_support_functions @@ -182,12 +182,16 @@ call_irodsctl() { add_irods_to_system_pam_configuration() { local tempfile=/tmp/irods-pam-config.$$ - cat <<-EOF >$tempfile + if [ -z "$IRODS_PAM_CONFIG_SOURCE_PATH" ]; then + cat <<-EOF >$tempfile auth required pam_env.so auth sufficient pam_unix.so auth requisite pam_succeed_if.so uid >= 500 quiet auth required pam_deny.so EOF + else + cp IRODS_PAM_CONFIG_SOURCE_PATH /tmp/irods-pam-config.$$ + fi sudo chown root.root $tempfile sudo mv $tempfile /etc/pam.d/irods } diff --git a/test_harness/single_node/docker_container_driver.sh b/test_harness/single_node/docker_container_driver.sh index 996f54778..98229636c 100755 --- a/test_harness/single_node/docker_container_driver.sh +++ b/test_harness/single_node/docker_container_driver.sh @@ -26,6 +26,7 @@ usage() { $0 [options] /external/path/to/script" echo 'Options : + -e SETTINGS set in docker environment: argument is a list of env settings (format: VAR=VAL) separated by spaces -V (extra verbosity). Prints out useful stuff including VERSION information -u USERNAME run test in container as this USERNAME -i invoke container with -i and -t @@ -60,6 +61,12 @@ while [[ $1 = -* ]]; do elif [ "$1" = -r ]; then REMOVE_OPTION="$2" shift 2 + elif [ "$1" = -e ]; then + ENV_VARS="$2" + ENV_VAR_ARRAY=( $ENV_VARS ) + ENV_VARS="${ENV_VAR_ARRAY[*]/#/-e }" + shift 2 + #echo "[$ENV_VARS]" >&2 elif [ "$1" = -w ]; then EXPLICIT_WORKDIR="$2" shift 2 @@ -126,7 +133,7 @@ INNER_MOUNT=/prc # Start the container. echo image="[$image]" -CONTAINER=$($DOCKER run -d -v "$reporoot:$INNER_MOUNT:ro" $INTERACTIVE_OPTION $REMOVE_OPTION \ +CONTAINER=$($DOCKER run -d $ENV_VARS -v "$reporoot:$INNER_MOUNT:ro" $INTERACTIVE_OPTION $REMOVE_OPTION \ -e "IRODS_CONTROL_PATH=$IRODS_CONTROL_PATH" $image) # Wait for iRODS and database to start up. diff --git a/test_harness/single_node/test_script_parameters b/test_harness/single_node/test_script_parameters index b4b2d5940..f7b977296 100644 --- a/test_harness/single_node/test_script_parameters +++ b/test_harness/single_node/test_script_parameters @@ -22,6 +22,7 @@ declare -A wrappers=( [test009_test_special_characters_in_pam_passwords_auth_framework.bats]=../login_auth_test.sh [test010_issue_362_rogue_chars_in_pam_password.bats]=../login_auth_test.sh [test011_pam_interactive.bats]=../login_auth_test.sh + [test012_pam_interactive_multistep.bats]=../login_auth_test.sh ) # keys for Image and User refer to the basename after resolution to a wrapper if one is used From 38cdec45719de7953d4cbaaa1110748434d5ae66 Mon Sep 17 00:00:00 2001 From: d-w-moore Date: Mon, 22 Jun 2026 02:12:01 -0400 Subject: [PATCH 3/8] experimental chgs for 777 --- .../scripts/files_for_test012/pam_interactive | 17 ++++++++++++++++ .../test012_pam_interactive_multistep.bats | 10 +++++++++- irods/test/scripts/test_support_functions | 20 +++++++++---------- .../single_node/docker_container_driver.sh | 2 +- 4 files changed, 36 insertions(+), 13 deletions(-) create mode 100644 irods/test/scripts/files_for_test012/pam_interactive diff --git a/irods/test/scripts/files_for_test012/pam_interactive b/irods/test/scripts/files_for_test012/pam_interactive new file mode 100644 index 000000000..40a3a8b6e --- /dev/null +++ b/irods/test/scripts/files_for_test012/pam_interactive @@ -0,0 +1,17 @@ +# This file is for testing PAM authentication with iRODS +# using the pam_interactive authentication scheme. + +# Prompt for the first password, from /etc/shadow. +auth required pam_unix.so + +# This is a custom PAM module that clears the success token. Without +# this, the "auth" lines which follow are skipped. +auth required /t012/pam_clear_token.so + +# Prompt for the second password, from the user database file created +# earlier. The use of "crypt=crypt" is required for this to work. It +# tells the module that the passwords are encrypted. +auth required pam_userdb.so db=/t012/pam_userdb crypt=crypt + +# Do the normal user account stuff. +account required pam_unix.so diff --git a/irods/test/scripts/test012_pam_interactive_multistep.bats b/irods/test/scripts/test012_pam_interactive_multistep.bats index 7378a1c7b..53b85edf1 100755 --- a/irods/test/scripts/test012_pam_interactive_multistep.bats +++ b/irods/test/scripts/test012_pam_interactive_multistep.bats @@ -3,6 +3,9 @@ # The tests in this BATS module must be run as a (passwordless) sudo-enabled user. # It is also required that the python irodsclient be installed under irods' ~/.local environment. +SKIP_WRITING_PAM_CONFIG_FILE="" +SKIP_IINIT_FOR_PASSWORD=yes + . $BATS_TEST_DIRNAME/test_support_functions setup() { @@ -14,6 +17,9 @@ setup() { user rods \ password rods \ + apt update + apt install -y db-util libpam0g-dev + ## Because iRODS 5+ negotiates for SSL automatically: CLIENT_JSON=~/.irods/irods_environment.json jq '.irods_client_server_policy="CS_NEG_REFUSE"' >$CLIENT_JSON.$$ <$CLIENT_JSON && \ @@ -21,7 +27,9 @@ setup() { sudo apt install irods-auth-plugin-pam-interactive-{client,server} - setup_pam_login_for_user "rods" alice + setup_pam_login_for_user "rods" $TESTUSER + sudo cp $BATS_TEST_DIRNAME/files_for_test012/pam_interactive /etc/pam.d/irods + sudo mkdir /t012 ; gcc -o /t012/pam_clear_token.so -fno-stack-protector -shared -fPIC $BATS_TEST_DIRNAME/files_for_test012/pam_clear_token.c # Tests require only the irods_environment.json rm -f ~/.irods/.irodsA diff --git a/irods/test/scripts/test_support_functions b/irods/test/scripts/test_support_functions index 04e85748e..51a8d239b 100644 --- a/irods/test/scripts/test_support_functions +++ b/irods/test/scripts/test_support_functions @@ -182,18 +182,16 @@ call_irodsctl() { add_irods_to_system_pam_configuration() { local tempfile=/tmp/irods-pam-config.$$ - if [ -z "$IRODS_PAM_CONFIG_SOURCE_PATH" ]; then - cat <<-EOF >$tempfile - auth required pam_env.so - auth sufficient pam_unix.so - auth requisite pam_succeed_if.so uid >= 500 quiet - auth required pam_deny.so - EOF - else - cp IRODS_PAM_CONFIG_SOURCE_PATH /tmp/irods-pam-config.$$ + if [ -n "$SKIP_WRITING_PAM_CONFIG_FILE" ]; then + cat <<-EOF >$tempfile + auth required pam_env.so + auth sufficient pam_unix.so + auth requisite pam_succeed_if.so uid >= 500 quiet + auth required pam_deny.so + EOF + sudo chown root.root $tempfile + sudo mv $tempfile /etc/pam.d/irods fi - sudo chown root.root $tempfile - sudo mv $tempfile /etc/pam.d/irods } setup_preconnect_preference() { diff --git a/test_harness/single_node/docker_container_driver.sh b/test_harness/single_node/docker_container_driver.sh index 98229636c..569a2ec23 100755 --- a/test_harness/single_node/docker_container_driver.sh +++ b/test_harness/single_node/docker_container_driver.sh @@ -133,7 +133,7 @@ INNER_MOUNT=/prc # Start the container. echo image="[$image]" -CONTAINER=$($DOCKER run -d $ENV_VARS -v "$reporoot:$INNER_MOUNT:ro" $INTERACTIVE_OPTION $REMOVE_OPTION \ +CONTAINER=$($DOCKER run $ENV_VARS -d -v "$reporoot:$INNER_MOUNT:ro" $INTERACTIVE_OPTION $REMOVE_OPTION \ -e "IRODS_CONTROL_PATH=$IRODS_CONTROL_PATH" $image) # Wait for iRODS and database to start up. From 8518ac384e27b6a10fb1e7b69e9cd94459dd55ea Mon Sep 17 00:00:00 2001 From: d-w-moore Date: Mon, 22 Jun 2026 07:55:26 -0400 Subject: [PATCH 4/8] generate pam_userdb --- .../test012_pam_interactive_multistep.bats | 8 ++++++-- irods/test/scripts/test_support_functions | 18 ++++++++---------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/irods/test/scripts/test012_pam_interactive_multistep.bats b/irods/test/scripts/test012_pam_interactive_multistep.bats index 53b85edf1..c1e2a0723 100755 --- a/irods/test/scripts/test012_pam_interactive_multistep.bats +++ b/irods/test/scripts/test012_pam_interactive_multistep.bats @@ -3,7 +3,6 @@ # The tests in this BATS module must be run as a (passwordless) sudo-enabled user. # It is also required that the python irodsclient be installed under irods' ~/.local environment. -SKIP_WRITING_PAM_CONFIG_FILE="" SKIP_IINIT_FOR_PASSWORD=yes . $BATS_TEST_DIRNAME/test_support_functions @@ -29,7 +28,12 @@ setup() { setup_pam_login_for_user "rods" $TESTUSER sudo cp $BATS_TEST_DIRNAME/files_for_test012/pam_interactive /etc/pam.d/irods - sudo mkdir /t012 ; gcc -o /t012/pam_clear_token.so -fno-stack-protector -shared -fPIC $BATS_TEST_DIRNAME/files_for_test012/pam_clear_token.c + sudo mkdir /t012 && gcc -o /t012/pam_clear_token.so -fno-stack-protector -shared -fPIC $BATS_TEST_DIRNAME/files_for_test012/pam_clear_token.c + + db_file=/t012/pam_userdb.db + sudo db_load -T -t hash "$db_file" <<<"alice"$'\n'"otherrods" + sudo chown root:root "$db_file" + sudo chmod 600 "$db_file" # Tests require only the irods_environment.json rm -f ~/.irods/.irodsA diff --git a/irods/test/scripts/test_support_functions b/irods/test/scripts/test_support_functions index 51a8d239b..a7e40bfe4 100644 --- a/irods/test/scripts/test_support_functions +++ b/irods/test/scripts/test_support_functions @@ -182,16 +182,14 @@ call_irodsctl() { add_irods_to_system_pam_configuration() { local tempfile=/tmp/irods-pam-config.$$ - if [ -n "$SKIP_WRITING_PAM_CONFIG_FILE" ]; then - cat <<-EOF >$tempfile - auth required pam_env.so - auth sufficient pam_unix.so - auth requisite pam_succeed_if.so uid >= 500 quiet - auth required pam_deny.so - EOF - sudo chown root.root $tempfile - sudo mv $tempfile /etc/pam.d/irods - fi + cat <<-EOF >$tempfile + auth required pam_env.so + auth sufficient pam_unix.so + auth requisite pam_succeed_if.so uid >= 500 quiet + auth required pam_deny.so + EOF + sudo chown root.root $tempfile + sudo mv $tempfile /etc/pam.d/irods } setup_preconnect_preference() { From fc04465bf1655093038a7842f3fb053e6ca03b61 Mon Sep 17 00:00:00 2001 From: d-w-moore Date: Mon, 22 Jun 2026 08:34:16 -0400 Subject: [PATCH 5/8] write complete test --- .../test012_pam_interactive_multistep.bats | 40 ++++++++++++++----- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/irods/test/scripts/test012_pam_interactive_multistep.bats b/irods/test/scripts/test012_pam_interactive_multistep.bats index c1e2a0723..d5ab52749 100755 --- a/irods/test/scripts/test012_pam_interactive_multistep.bats +++ b/irods/test/scripts/test012_pam_interactive_multistep.bats @@ -45,15 +45,35 @@ setup() { touch /tmp/test012_flag } -original_test_suite() -{ -: -# local USER="alice" -# local PASSWORD="rods" -# sudo chpasswd <<<"$USER:$PASSWORD" -# python -m unittest irods.test.pam_interactive_test_must_run_manually -} +@test "pam_interactive_test_multistep_with_correct_passwords" { +python -c" +from unittest.mock import patch +import getpass + +import irods + +class clbl: + def __call__(self): + return lambda: 'hello\n' + +def getpass_new_callable(answers=()): + class iterate_answers: + def __init__(self,answers = answers ): self.answers = answers; self.count = 0 + def __call__(self): + count = self.count + self.count += 1 + return self.answers[count] + return lambda : iterate_answers() + +home = None + +with patch('getpass.getpass', new_callable=getpass_new_callable(answers=['rods','otherrods'])): + sess = make_session(test_server_version=False) + home = self.sess.collections.get(f'/{sess.zone}/home/{sess.username}') -@test "original_pam_interactive_tests" { - original_test_suite +if home is None: + exit(2) +if '/alice' not in home.path + exit(1) +" } From 401ab6bd6d5f6661a4ea2442574a4e7a8d691910 Mon Sep 17 00:00:00 2001 From: d-w-moore Date: Wed, 22 Jul 2026 07:10:55 -0400 Subject: [PATCH 6/8] debug corrections --- .../test012_pam_interactive_multistep.bats | 26 +++++++++++-------- .../single_node/docker_container_driver.sh | 12 ++++++--- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/irods/test/scripts/test012_pam_interactive_multistep.bats b/irods/test/scripts/test012_pam_interactive_multistep.bats index d5ab52749..7b8b2de21 100755 --- a/irods/test/scripts/test012_pam_interactive_multistep.bats +++ b/irods/test/scripts/test012_pam_interactive_multistep.bats @@ -7,6 +7,9 @@ SKIP_IINIT_FOR_PASSWORD=yes . $BATS_TEST_DIRNAME/test_support_functions +export TESTUSER=alice +export SECOND_PASSWORD=otherrods + setup() { [ -f /tmp/test012_flag ] || { rm -fr ~/.irods @@ -26,12 +29,12 @@ setup() { sudo apt install irods-auth-plugin-pam-interactive-{client,server} - setup_pam_login_for_user "rods" $TESTUSER + setup_pam_login_for_user "${FIRST_PASSWORD}" $TESTUSER sudo cp $BATS_TEST_DIRNAME/files_for_test012/pam_interactive /etc/pam.d/irods sudo mkdir /t012 && gcc -o /t012/pam_clear_token.so -fno-stack-protector -shared -fPIC $BATS_TEST_DIRNAME/files_for_test012/pam_clear_token.c db_file=/t012/pam_userdb.db - sudo db_load -T -t hash "$db_file" <<<"alice"$'\n'"otherrods" + sudo db_load -T -t hash "$db_file" <<<"${TESTUSER}"$'\n'"${SECOND_PASSWORD}" sudo chown root:root "$db_file" sudo chmod 600 "$db_file" @@ -46,15 +49,12 @@ setup() { } @test "pam_interactive_test_multistep_with_correct_passwords" { + python -c" -from unittest.mock import patch import getpass - import irods - -class clbl: - def __call__(self): - return lambda: 'hello\n' +import os +from unittest.mock import patch def getpass_new_callable(answers=()): class iterate_answers: @@ -67,13 +67,17 @@ def getpass_new_callable(answers=()): home = None -with patch('getpass.getpass', new_callable=getpass_new_callable(answers=['rods','otherrods'])): +with patch( + 'getpass.getpass', + new_callable=getpass_new_callable(answers=[os.environ['FIRST_PASSWORD'],os.environ['SECOND_PASSWORD']]) +): sess = make_session(test_server_version=False) - home = self.sess.collections.get(f'/{sess.zone}/home/{sess.username}') + home = sess.collections.get(f'/{sess.zone}/home/{sess.username}') if home is None: exit(2) -if '/alice' not in home.path +username = os.environ['TESTUSER'] +if not home.path.endswith(f'/{username}'): exit(1) " } diff --git a/test_harness/single_node/docker_container_driver.sh b/test_harness/single_node/docker_container_driver.sh index 569a2ec23..57a5f324d 100755 --- a/test_harness/single_node/docker_container_driver.sh +++ b/test_harness/single_node/docker_container_driver.sh @@ -12,6 +12,7 @@ # Options: +ENV_VARS=() IRODS_CONTROL_PATH="" KILL_TEST_CONTAINER=1 RUN_AS_USER="" @@ -26,6 +27,8 @@ usage() { $0 [options] /external/path/to/script" echo 'Options : + -E SETTING set in docker environment: argument is a single env setting like: "ENVVAR=" where + can may contain whitespace. "-E" may occur multiple times. -e SETTINGS set in docker environment: argument is a list of env settings (format: VAR=VAL) separated by spaces -V (extra verbosity). Prints out useful stuff including VERSION information -u USERNAME run test in container as this USERNAME @@ -61,12 +64,13 @@ while [[ $1 = -* ]]; do elif [ "$1" = -r ]; then REMOVE_OPTION="$2" shift 2 + elif [ "$1" = -E ]; then + ENV_VARS+=(-e "$2") + shift 2 elif [ "$1" = -e ]; then - ENV_VARS="$2" - ENV_VAR_ARRAY=( $ENV_VARS ) + ENV_VAR_ARRAY=($2) ENV_VARS="${ENV_VAR_ARRAY[*]/#/-e }" shift 2 - #echo "[$ENV_VARS]" >&2 elif [ "$1" = -w ]; then EXPLICIT_WORKDIR="$2" shift 2 @@ -133,7 +137,7 @@ INNER_MOUNT=/prc # Start the container. echo image="[$image]" -CONTAINER=$($DOCKER run $ENV_VARS -d -v "$reporoot:$INNER_MOUNT:ro" $INTERACTIVE_OPTION $REMOVE_OPTION \ +CONTAINER=$($DOCKER run "${ENV_VARS[@]}" -d -v "$reporoot:$INNER_MOUNT:ro" $INTERACTIVE_OPTION $REMOVE_OPTION \ -e "IRODS_CONTROL_PATH=$IRODS_CONTROL_PATH" $image) # Wait for iRODS and database to start up. From 8bebbd7f55d77acb68e8633ced375ca74b44d5f9 Mon Sep 17 00:00:00 2001 From: d-w-moore Date: Wed, 22 Jul 2026 08:27:24 -0400 Subject: [PATCH 7/8] add pam_clear_token.c --- .../files_for_test012/pam_clear_token.c | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 irods/test/scripts/files_for_test012/pam_clear_token.c diff --git a/irods/test/scripts/files_for_test012/pam_clear_token.c b/irods/test/scripts/files_for_test012/pam_clear_token.c new file mode 100644 index 000000000..8590287ce --- /dev/null +++ b/irods/test/scripts/files_for_test012/pam_clear_token.c @@ -0,0 +1,36 @@ +/* +To build, you need the PAM development library. Once installed, +run the following: + + gcc -fPIC -fno-stack-protector -o pam_clear_token.o -c main.c + gcc -shared -o pam_clear_token.so pam_clear_token.o +*/ + +#include +#include +#include + +#include + +PAM_EXTERN int pam_sm_authenticate(pam_handle_t* pamh, int flags, int argc, const char** argv) +{ + (void) flags; + (void) argc; + (void) argv; + + // Clear the current auth token. + pam_set_item(pamh, PAM_AUTHTOK, NULL); + pam_set_item(pamh, PAM_OLDAUTHTOK, NULL); + + return PAM_SUCCESS; +} + +PAM_EXTERN int pam_sm_setcred(pam_handle_t* pamh, int flags, int argc, const char** argv) +{ + (void) pamh; + (void) flags; + (void) argc; + (void) argv; + + return PAM_SUCCESS; +} From ef583b420a2bb8a8ba10b846f157834c1cbd0bdf Mon Sep 17 00:00:00 2001 From: d-w-moore Date: Wed, 22 Jul 2026 09:08:03 -0400 Subject: [PATCH 8/8] blocked --- .../test012_pam_interactive_multistep.bats | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/irods/test/scripts/test012_pam_interactive_multistep.bats b/irods/test/scripts/test012_pam_interactive_multistep.bats index 7b8b2de21..6b2757a9e 100755 --- a/irods/test/scripts/test012_pam_interactive_multistep.bats +++ b/irods/test/scripts/test012_pam_interactive_multistep.bats @@ -8,6 +8,7 @@ SKIP_IINIT_FOR_PASSWORD=yes . $BATS_TEST_DIRNAME/test_support_functions export TESTUSER=alice +export FIRST_PASSWORD=somerods export SECOND_PASSWORD=otherrods setup() { @@ -19,8 +20,8 @@ setup() { user rods \ password rods \ - apt update - apt install -y db-util libpam0g-dev + sudo apt update + sudo apt install -y db-util libpam0g-dev ## Because iRODS 5+ negotiates for SSL automatically: CLIENT_JSON=~/.irods/irods_environment.json @@ -31,7 +32,7 @@ setup() { setup_pam_login_for_user "${FIRST_PASSWORD}" $TESTUSER sudo cp $BATS_TEST_DIRNAME/files_for_test012/pam_interactive /etc/pam.d/irods - sudo mkdir /t012 && gcc -o /t012/pam_clear_token.so -fno-stack-protector -shared -fPIC $BATS_TEST_DIRNAME/files_for_test012/pam_clear_token.c + sudo mkdir /t012 && sudo gcc -o /t012/pam_clear_token.so -fno-stack-protector -shared -fPIC $BATS_TEST_DIRNAME/files_for_test012/pam_clear_token.c db_file=/t012/pam_userdb.db sudo db_load -T -t hash "$db_file" <<<"${TESTUSER}"$'\n'"${SECOND_PASSWORD}" @@ -49,7 +50,7 @@ setup() { } @test "pam_interactive_test_multistep_with_correct_passwords" { - +: python -c" import getpass import irods @@ -58,11 +59,15 @@ from unittest.mock import patch def getpass_new_callable(answers=()): class iterate_answers: - def __init__(self,answers = answers ): self.answers = answers; self.count = 0 - def __call__(self): - count = self.count - self.count += 1 - return self.answers[count] + def __init__(self,answers = answers): + self.answers = answers + self.count = 0 + def __call__(self,*_): + count = self.count + self.count += 1 + ans = self.answers[count] + print ('*** giving answer:', ans) + return ans return lambda : iterate_answers() home = None @@ -71,7 +76,7 @@ with patch( 'getpass.getpass', new_callable=getpass_new_callable(answers=[os.environ['FIRST_PASSWORD'],os.environ['SECOND_PASSWORD']]) ): - sess = make_session(test_server_version=False) + sess = irods.helpers.make_session(test_server_version=False) home = sess.collections.get(f'/{sess.zone}/home/{sess.username}') if home is None: