From 880d0f7e1979742584531c0789e01cda2d4d37e2 Mon Sep 17 00:00:00 2001 From: Ethan Ho <53266718+ethho@users.noreply.github.com> Date: Wed, 14 Feb 2024 12:48:07 -0600 Subject: [PATCH 1/6] Reproduce error message observed in prod --- docker/percona.dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docker/percona.dockerfile b/docker/percona.dockerfile index ad5798e..b319bbf 100644 --- a/docker/percona.dockerfile +++ b/docker/percona.dockerfile @@ -12,8 +12,8 @@ RUN \ # https://www.percona.com/blog/getting-percona-pam-to-work-with-percona-server-its-client-apps/ RUN \ - chgrp mysql /etc/shadow && \ - chmod g+r /etc/shadow && \ + # chgrp mysql /etc/shadow && \ + # chmod g+r /etc/shadow && \ useradd ap_user && \ echo "ap_user:password" | chpasswd USER mysql:mysql From d2e9cc6b9712896bb1b18bd2fd0c131bc5e673fd Mon Sep 17 00:00:00 2001 From: Ethan Ho <53266718+ethho@users.noreply.github.com> Date: Fri, 23 Feb 2024 13:14:24 -0600 Subject: [PATCH 2/6] account PAM interface calls acct_mgmt function in handler --- pam-oidc/src/lib.rs | 6 +++++ tests/test.sh | 55 +++++++++------------------------------------ 2 files changed, 17 insertions(+), 44 deletions(-) diff --git a/pam-oidc/src/lib.rs b/pam-oidc/src/lib.rs index 66663e7..1ca5c2b 100644 --- a/pam-oidc/src/lib.rs +++ b/pam-oidc/src/lib.rs @@ -148,23 +148,29 @@ impl PamServiceModule for PamCustom { } fn chauthtok(_pamh: Pam, _flags: PamFlags, _args: Vec) -> PamError { + info!("chauthtok called."); PamError::SUCCESS } fn open_session(_pamh: Pam, _flags: PamFlags, _args: Vec) -> PamError { + info!("open_session called."); PamError::SUCCESS } fn close_session(_pamh: Pam, _flags: PamFlags, _args: Vec) -> PamError { + info!("close_session called."); PamError::SUCCESS } fn setcred(_pamh: Pam, _flags: PamFlags, _args: Vec) -> PamError { + info!("setcred called."); PamError::SUCCESS } fn acct_mgmt(_pamh: Pam, _flags: PamFlags, _args: Vec) -> PamError { + info!("acct_mgmt called."); PamError::SUCCESS + // PamError::USER_UNKNOWN } } diff --git a/tests/test.sh b/tests/test.sh index 8057e37..1bb77cb 100755 --- a/tests/test.sh +++ b/tests/test.sh @@ -1,46 +1,13 @@ #!/bin/bash -# set -a && . .env && ./tests/test.sh mariadb && set +a -# set -a && . .env && ./tests/test.sh percona && set +a - -mariadb() { - set -e - ROOT_PASSWORD=simple - docker rm -f database - docker run --name database -de MYSQL_ROOT_PASSWORD=${ROOT_PASSWORD} mariadb:10.7 # does not work with latest and non-v1 - until docker exec -it database mysql -h 127.0.0.1 -uroot -p${ROOT_PASSWORD} -e "SELECT 1;" 1>/dev/null - do - echo waiting... - sleep 5 - done - docker exec -it database mysql -uroot -p${ROOT_PASSWORD} -e "INSTALL SONAME 'auth_pam_v1';" - docker cp ./config/service_example database:/etc/pam.d/oidc - docker cp ./pam-oidc/target/debug/libpam_oidc.so database:/lib/x86_64-linux-gnu/security/libpam_oidc.so - docker exec -it database mkdir /etc/datajoint - docker cp ./config/libpam_oidc.yaml database:/etc/datajoint/ - docker exec -it database mysql -uroot -p${ROOT_PASSWORD} -e "CREATE USER '${DJ_AUTH_USER}'@'%' IDENTIFIED VIA pam USING 'oidc';" - docker exec -it database mysql -h 127.0.0.1 -u${DJ_AUTH_USER} -p${DJ_AUTH_PASSWORD} -e "SELECT 'delegated to oidc' as login;" - docker exec -it database mysql -h 127.0.0.1 -u${DJ_AUTH_USER} -p${DJ_AUTH_PASSWORD} -e "SELECT 'delegated to oidc' as login;" - docker exec -it database mysql -h 127.0.0.1 -u${DJ_AUTH_USER} -pdeny -e "SELECT 'delegated to oidc' as login;" -} - -percona() { - set -e - ROOT_PASSWORD=simple - docker rm -f database - docker run --name database -de MYSQL_ROOT_PASSWORD=${ROOT_PASSWORD} --entrypoint bash percona:8 -c "echo 'plugin_load_add = auth_pam.so' >> /etc/my.cnf && /docker-entrypoint.sh mysqld" - until docker exec -it database mysql -h 127.0.0.1 -uroot -p${ROOT_PASSWORD} -e "SELECT 1;" 1>/dev/null - do - echo waiting... - sleep 5 - done - docker cp ./config/service_example database:/etc/pam.d/oidc - docker cp ./pam-oidc/target/debug/libpam_oidc.so database:/usr/lib64/security/libpam_oidc.so - docker exec -itu root database mkdir /etc/datajoint - docker cp ./config/libpam_oidc.yaml database:/etc/datajoint/ - docker exec -it database mysql -uroot -p${ROOT_PASSWORD} -e "CREATE USER '${DJ_AUTH_USER}'@'%' IDENTIFIED WITH auth_pam AS 'oidc';" - docker exec -it database mysql -h 127.0.0.1 -u${DJ_AUTH_USER} -p${DJ_AUTH_PASSWORD} -e "SELECT 'delegated to oidc' as login;" - docker exec -it database mysql -h 127.0.0.1 -u${DJ_AUTH_USER} -p${DJ_AUTH_PASSWORD} -e "SELECT 'delegated to oidc' as login;" - docker exec -it database mysql -h 127.0.0.1 -u${DJ_AUTH_USER} -pdeny -e "SELECT 'delegated to oidc' as login;" -} - +# Usage: +# ./tests/test.sh '' + +docker compose up --build -d --wait percona +docker compose exec percona mysql -hlocalhost -uroot -ppassword -e "CREATE USER 'demouser'@'%' IDENTIFIED WITH auth_pam AS 'oidc';" +docker compose exec percona mysql -hlocalhost -uroot -ppassword -e "SHOW PLUGINS;" | grep auth_pam +docker compose exec percona mysql -hlocalhost -udemouser -p"$1" -e "SELECT 1;" || echo "Failed to authenticate with real password" +docker compose exec percona mysql -hlocalhost -udemouser -p'bogus_password' -e "SELECT 1;" || echo "Failed to authenticate for bogus password" +sleep 3 +docker compose logs percona +docker compose down \ No newline at end of file From 8c6736d84cdafe468afa703b1d5eaac14af82770 Mon Sep 17 00:00:00 2001 From: Ethan Ho <53266718+ethho@users.noreply.github.com> Date: Fri, 23 Feb 2024 14:47:44 -0600 Subject: [PATCH 3/6] Debug messages in acct_mgmt --- config/service_example | 4 ++-- docker/percona.dockerfile | 6 ++++-- pam-oidc/src/lib.rs | 37 +++++++++++++++++++++++++++++++++++-- 3 files changed, 41 insertions(+), 6 deletions(-) diff --git a/config/service_example b/config/service_example index 2b86d8d..fa2c1c8 100644 --- a/config/service_example +++ b/config/service_example @@ -1,2 +1,2 @@ -auth sufficient libpam_oidc.so /etc/datajoint/libpam_oidc.yaml -account optional libpam_oidc.so +auth required libpam_oidc.so /etc/datajoint/libpam_oidc.yaml +account optional libpam_oidc.so /etc/datajoint/libpam_oidc.yaml diff --git a/docker/percona.dockerfile b/docker/percona.dockerfile index b319bbf..791178e 100644 --- a/docker/percona.dockerfile +++ b/docker/percona.dockerfile @@ -12,8 +12,10 @@ RUN \ # https://www.percona.com/blog/getting-percona-pam-to-work-with-percona-server-its-client-apps/ RUN \ - # chgrp mysql /etc/shadow && \ - # chmod g+r /etc/shadow && \ + groupadd shadow && \ + usermod -a -G shadow mysql && \ + chown root:shadow /etc/shadow && \ + chmod g+r /etc/shadow && \ useradd ap_user && \ echo "ap_user:password" | chpasswd USER mysql:mysql diff --git a/pam-oidc/src/lib.rs b/pam-oidc/src/lib.rs index 1ca5c2b..b9833db 100644 --- a/pam-oidc/src/lib.rs +++ b/pam-oidc/src/lib.rs @@ -169,8 +169,29 @@ impl PamServiceModule for PamCustom { fn acct_mgmt(_pamh: Pam, _flags: PamFlags, _args: Vec) -> PamError { info!("acct_mgmt called."); - PamError::SUCCESS - // PamError::USER_UNKNOWN + info!("_args: {:?}", _args); + info!("_flags: {:?}", _flags); + let config_file = &_args[0]; + let config: AppConfig = match load_config(config_file) { + Some(c) => c, + None => { + error!("Error loading config file at '{}'.", config_file); + return PamError::AUTH_ERR; + } + }; + + if config.account_succeed == "success" { + PamError::SUCCESS + } else if config.account_succeed == "user_unknown" { + PamError::USER_UNKNOWN + } else if config.account_succeed == "auth_err" { + PamError::AUTH_ERR + } else if config.account_succeed == "ignore" { + PamError::IGNORE + } else { + PamError::AUTH_ERR + } + } } @@ -201,6 +222,7 @@ struct AppConfig { token_min_size: i64, log_level: String, log_path: String, + account_succeed: String, } fn load_config(file: &str) -> Option { @@ -329,6 +351,17 @@ fn load_config(file: &str) -> Option { return None; } }, + account_succeed: match contents[0]["account.succeed"].as_str() { + Some(s) => s.to_string(), + None => { + eprintln!( + "[{}:{}] ERROR: Config file at '{file}' is missing 'account.succeed'.", + file!(), + line!() + ); + return None; + } + }, }; Some(conf) } From 1cd248f2175e8d217cae38bc5c71d3ec91b58c60 Mon Sep 17 00:00:00 2001 From: Ethan Ho <53266718+ethho@users.noreply.github.com> Date: Fri, 23 Feb 2024 15:51:23 -0600 Subject: [PATCH 4/6] Faster builds using debug --- docker/builder.dockerfile | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/docker/builder.dockerfile b/docker/builder.dockerfile index 94c6450..884e215 100644 --- a/docker/builder.dockerfile +++ b/docker/builder.dockerfile @@ -8,12 +8,18 @@ RUN \ ENV RUSTFLAGS="-C target-feature=-crt-static" WORKDIR /tmp/pam-oauth2 COPY pam-oidc /tmp/pam-oauth2/pam-oidc +# RUN \ +# cd pam-oidc && \ +# rustup target add x86_64-unknown-linux-gnu && \ +# rustup target add x86_64-unknown-linux-musl && \ +# rustup show && \ +# cargo build --release --target x86_64-unknown-linux-musl && \ +# cargo build --release --target x86_64-unknown-linux-gnu && \ +# cp target/x86_64-unknown-linux-musl/release/libpam_oidc.so /tmp/pam-oauth2/libpam_oidc_musl.so && \ +# cp target/x86_64-unknown-linux-gnu/release/libpam_oidc.so /tmp/pam-oauth2/libpam_oidc_gnu.so RUN \ cd pam-oidc && \ rustup target add x86_64-unknown-linux-gnu && \ - rustup target add x86_64-unknown-linux-musl && \ rustup show && \ - cargo build --release --target x86_64-unknown-linux-musl && \ - cargo build --release --target x86_64-unknown-linux-gnu && \ - cp target/x86_64-unknown-linux-musl/release/libpam_oidc.so /tmp/pam-oauth2/libpam_oidc_musl.so && \ - cp target/x86_64-unknown-linux-gnu/release/libpam_oidc.so /tmp/pam-oauth2/libpam_oidc_gnu.so + cargo build --target x86_64-unknown-linux-gnu && \ + cp target/x86_64-unknown-linux-gnu/debug/libpam_oidc.so /tmp/pam-oauth2/libpam_oidc_gnu.so \ No newline at end of file From 064414201c3fb6bc0491439562791962dde81dcb Mon Sep 17 00:00:00 2001 From: Ethan Ho <53266718+ethho@users.noreply.github.com> Date: Fri, 23 Feb 2024 15:59:54 -0600 Subject: [PATCH 5/6] Use cleartext-plugin in test client --- tests/test.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test.sh b/tests/test.sh index 1bb77cb..f286dfb 100755 --- a/tests/test.sh +++ b/tests/test.sh @@ -6,8 +6,8 @@ docker compose up --build -d --wait percona docker compose exec percona mysql -hlocalhost -uroot -ppassword -e "CREATE USER 'demouser'@'%' IDENTIFIED WITH auth_pam AS 'oidc';" docker compose exec percona mysql -hlocalhost -uroot -ppassword -e "SHOW PLUGINS;" | grep auth_pam -docker compose exec percona mysql -hlocalhost -udemouser -p"$1" -e "SELECT 1;" || echo "Failed to authenticate with real password" -docker compose exec percona mysql -hlocalhost -udemouser -p'bogus_password' -e "SELECT 1;" || echo "Failed to authenticate for bogus password" +docker compose exec percona mysql -hlocalhost -udemouser -p"$1" --enable-cleartext-plugin -e "SELECT 1;" || echo "Failed to authenticate with real password" +docker compose exec percona mysql -hlocalhost -udemouser -p'bogus_password' --enable-cleartext-plugin -e "SELECT 1;" || echo "Failed to authenticate for bogus password" sleep 3 docker compose logs percona docker compose down \ No newline at end of file From e0150ade31796cf045eb7b1d8daa883fa02e37ef Mon Sep 17 00:00:00 2001 From: Ethan Ho <53266718+ethho@users.noreply.github.com> Date: Fri, 23 Feb 2024 16:23:06 -0600 Subject: [PATCH 6/6] Reproduce issue with mysql-any-password https://dev.mysql.com/doc/refman/8.0/en/pam-pluggable-authentication.html#pam-pluggable-authentication-debugging --- config/mysql-any-password | 3 +++ docker/percona.dockerfile | 1 + tests/test.sh | 3 +-- 3 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 config/mysql-any-password diff --git a/config/mysql-any-password b/config/mysql-any-password new file mode 100644 index 0000000..2203b6a --- /dev/null +++ b/config/mysql-any-password @@ -0,0 +1,3 @@ +#%PAM-1.0 +auth required pam_permit.so +#account required pam_permit.so \ No newline at end of file diff --git a/docker/percona.dockerfile b/docker/percona.dockerfile index 791178e..6f62a4c 100644 --- a/docker/percona.dockerfile +++ b/docker/percona.dockerfile @@ -24,4 +24,5 @@ USER mysql:mysql COPY --from=builder /tmp/pam-oauth2/libpam_oidc_gnu.so /usr/lib64/security/libpam_oidc.so RUN echo 'plugin_load_add = auth_pam.so' >> /etc/my.cnf COPY config/pam_unix /etc/pam.d/mysqld +COPY config/mysql-any-password /etc/pam.d/mysql-any-password COPY config/service_example /etc/pam.d/oidc \ No newline at end of file diff --git a/tests/test.sh b/tests/test.sh index f286dfb..b47a2bf 100755 --- a/tests/test.sh +++ b/tests/test.sh @@ -4,8 +4,7 @@ # ./tests/test.sh '' docker compose up --build -d --wait percona -docker compose exec percona mysql -hlocalhost -uroot -ppassword -e "CREATE USER 'demouser'@'%' IDENTIFIED WITH auth_pam AS 'oidc';" -docker compose exec percona mysql -hlocalhost -uroot -ppassword -e "SHOW PLUGINS;" | grep auth_pam +docker compose exec percona mysql -hlocalhost -uroot -ppassword -e "CREATE USER 'demouser'@'%' IDENTIFIED WITH auth_pam AS 'mysql-any-password';" docker compose exec percona mysql -hlocalhost -udemouser -p"$1" --enable-cleartext-plugin -e "SELECT 1;" || echo "Failed to authenticate with real password" docker compose exec percona mysql -hlocalhost -udemouser -p'bogus_password' --enable-cleartext-plugin -e "SELECT 1;" || echo "Failed to authenticate for bogus password" sleep 3