diff options
author | Jakub Hrozek <jakub.hrozek@posteo.se> | 2015-09-20 07:22:35 +0200 |
---|---|---|
committer | Jakub Hrozek <jhrozek@redhat.com> | 2015-09-29 14:31:15 +0200 |
commit | 1c5af7897bd915c4f5da4bb7fd28d86b72c10e2c (patch) | |
tree | e968e4c47b0370d5ceeab572275662f3bfbc3a19 | |
parent | 774467d3fed623001c6334c2d6be7077d6a380f5 (diff) | |
download | pam_wrapper-1c5af7897bd915c4f5da4bb7fd28d86b72c10e2c.tar.gz pam_wrapper-1c5af7897bd915c4f5da4bb7fd28d86b72c10e2c.tar.xz pam_wrapper-1c5af7897bd915c4f5da4bb7fd28d86b72c10e2c.zip |
pwrap: wrap pam_acct
-rw-r--r-- | src/pam_wrapper.c | 21 | ||||
-rw-r--r-- | tests/pam_example.c | 136 | ||||
-rw-r--r-- | tests/passdb | 3 | ||||
-rw-r--r-- | tests/services/pwrap_pam.in | 8 | ||||
-rw-r--r-- | tests/test_pam_wrapper.c | 51 |
5 files changed, 175 insertions, 44 deletions
diff --git a/src/pam_wrapper.c b/src/pam_wrapper.c index 4492104..95da2c7 100644 --- a/src/pam_wrapper.c +++ b/src/pam_wrapper.c @@ -179,6 +179,8 @@ typedef int (*__libpam_pam_end)(pam_handle_t *pamh, int pam_status); typedef int (*__libpam_pam_authenticate)(pam_handle_t *pamh, int flags); +typedef int (*__libpam_pam_acct_mgmt)(pam_handle_t *pamh, int flags); + #define PWRAP_SYMBOL_ENTRY(i) \ union { \ __libpam_##i f; \ @@ -189,6 +191,7 @@ struct pwrap_libpam_symbols { PWRAP_SYMBOL_ENTRY(pam_start); PWRAP_SYMBOL_ENTRY(pam_end); PWRAP_SYMBOL_ENTRY(pam_authenticate); + PWRAP_SYMBOL_ENTRY(pam_acct_mgmt); }; struct pwrap { @@ -320,6 +323,13 @@ static int libpam_pam_authenticate(pam_handle_t *pamh, int flags) return pwrap.libpam.symbols._libpam_pam_authenticate.f(pamh, flags); } +static int libpam_pam_acct_mgmt(pam_handle_t *pamh, int flags) +{ + pwrap_bind_symbol_libpam(pam_acct_mgmt); + + return pwrap.libpam.symbols._libpam_pam_acct_mgmt.f(pamh, flags); +} + /********************************************************* * PWRAP INIT *********************************************************/ @@ -668,6 +678,17 @@ int pam_authenticate(pam_handle_t *pamh, int flags) return pwrap_pam_authenticate(pamh, flags); } +static int pwrap_pam_acct_mgmt(pam_handle_t *pamh, int flags) +{ + PWRAP_LOG(PWRAP_LOG_TRACE, "pwrap_pam_acct_mgmt called"); + return libpam_pam_acct_mgmt(pamh, flags); +} + +int pam_acct_mgmt(pam_handle_t *pamh, int flags) +{ + return pwrap_pam_acct_mgmt(pamh, flags); +} + /**************************** * DESTRUCTOR ***************************/ diff --git a/tests/pam_example.c b/tests/pam_example.c index ec0ffc8..cd2eb80 100644 --- a/tests/pam_example.c +++ b/tests/pam_example.c @@ -6,6 +6,7 @@ #include <string.h> #include <unistd.h> #include <ctype.h> +#include <errno.h> #include <security/pam_modules.h> #include <security/pam_appl.h> @@ -26,29 +27,43 @@ } \ } while(0); -struct pam_items { +struct pam_lib_items { const char *username; - char *pam_password; + const char *service; + char *password; +}; +struct pam_example_mod_items { char *password; + char *service; +}; + +struct pam_example_ctx { + struct pam_lib_items pli; + struct pam_example_mod_items pmi; }; -static char *find_password(const char *username) + +static int pam_example_mod_items_get(const char *username, + struct pam_example_mod_items *pmi) { + int rv; const char *db; - char *passwd = NULL; FILE *fp = NULL; char buf[BUFSIZ]; char *file_user = NULL; char *file_password = NULL; + char *file_svc = NULL; db = getenv("PWRAP_PASSDB"); if (db == NULL) { + rv = EIO; goto fail; } fp = fopen(db, "r"); if (fp == NULL) { + rv = errno; goto fail; } @@ -63,10 +78,11 @@ static char *find_password(const char *username) continue; } - /* Find the user */ + /* Find the user, his password and allowed service */ NEXT_KEY(file_user, file_password); + NEXT_KEY(file_password, file_svc); - q = file_password; + q = file_svc; while(q[0] != '\n' && q[0] != '\0') { q++; } @@ -77,88 +93,123 @@ static char *find_password(const char *username) } if (strcmp(file_user, username) == 0) { - passwd = strdup(file_password); - if (passwd == NULL) { + pmi->password = strdup(file_password); + if (pmi->password == NULL) { + rv = errno; goto fail; } + + pmi->service = strdup(file_svc); + if (pmi->service == NULL) { + rv = errno; + goto fail; + } + break; } } - return passwd; + return 0; fail: - free(passwd); - if (fp) fclose(fp); - return NULL; + free(pmi->password); + free(pmi->service); + if (fp) { + fclose(fp); + } + return rv; } -static int get_info(pam_handle_t *pamh, struct pam_items *pi) +static void pam_example_mod_items_free(struct pam_example_mod_items *pmi) +{ + if (pmi == NULL) { + return; + } + + free(pmi->password); + free(pmi->service); +} + +static int pam_lib_items_get(pam_handle_t *pamh, + struct pam_lib_items *pli) { int rv; - rv = pam_get_item(pamh, PAM_USER, (const void **) &(pi->username)); + rv = pam_get_item(pamh, PAM_USER, (const void **) &(pli->username)); if (rv != PAM_SUCCESS) { return rv; } - if (pi->username == NULL) { + if (pli->username == NULL) { return PAM_BAD_ITEM; } - rv = pam_prompt(pamh, PAM_PROMPT_ECHO_OFF, - &pi->pam_password, "%s", "Password"); + rv = pam_get_item(pamh, PAM_SERVICE, (const void **) &(pli->service)); if (rv != PAM_SUCCESS) { return rv; } - if (pi->pam_password == NULL) { - return PAM_AUTHINFO_UNAVAIL; + rv = pam_prompt(pamh, PAM_PROMPT_ECHO_OFF, + &pli->password, "%s", "Password"); + if (rv != PAM_SUCCESS) { + return rv; } - pi->password = find_password(pi->username); - if (pi->password == NULL) { - return PAM_USER_UNKNOWN; + if (pli->password == NULL) { + return PAM_AUTHINFO_UNAVAIL; } return PAM_SUCCESS; } -static void pam_items_free(struct pam_items *pi) +static int pam_example_get(pam_handle_t *pamh, struct pam_example_ctx *pe_ctx) { - if (pi == NULL) { - return; - } + int rv; + + rv = pam_lib_items_get(pamh, &pe_ctx->pli); + if (rv != PAM_SUCCESS) { + return rv; + } + + rv = pam_example_mod_items_get(pe_ctx->pli.username, &pe_ctx->pmi); + if (rv != PAM_SUCCESS) { + return rv; + } + + return PAM_SUCCESS; +} - free(pi->password); +static void pam_example_free(struct pam_example_ctx *pe_ctx) +{ + pam_example_mod_items_free(&pe_ctx->pmi); } PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char *argv[]) { - struct pam_items pi; + struct pam_example_ctx pctx; int rv; (void) flags; /* unused */ (void) argc; /* unused */ (void) argv; /* unused */ - memset(&pi, 0, sizeof(struct pam_items)); + memset(&pctx, 0, sizeof(struct pam_example_ctx)); - rv = get_info(pamh, &pi); + rv = pam_example_get(pamh, &pctx); if (rv != PAM_SUCCESS) { goto done; } - if (strcmp(pi.pam_password, pi.password) == 0) { + if (strcmp(pctx.pli.password, pctx.pmi.password) == 0) { rv = PAM_SUCCESS; goto done; } rv = PAM_AUTH_ERR; done: - pam_items_free(&pi); + pam_example_free(&pctx); return rv; } @@ -178,12 +229,29 @@ PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char *argv[]) { - (void) pamh; /* unused */ + struct pam_example_ctx pctx; + int rv; + (void) flags; /* unused */ (void) argc; /* unused */ (void) argv; /* unused */ - return PAM_SUCCESS; + memset(&pctx, 0, sizeof(struct pam_example_ctx)); + + rv = pam_example_get(pamh, &pctx); + if (rv != PAM_SUCCESS) { + goto done; + } + + if (strcmp(pctx.pli.service, pctx.pmi.service) == 0) { + rv = PAM_SUCCESS; + goto done; + } + + rv = PAM_PERM_DENIED; +done: + pam_example_free(&pctx); + return rv; } PAM_EXTERN int diff --git a/tests/passdb b/tests/passdb index 05765ec..db7d3c9 100644 --- a/tests/passdb +++ b/tests/passdb @@ -1,2 +1,3 @@ # The format is username password -testuser secret +testuser secret pwrap_pam +testuser2 secret pwrap_wrong_svc diff --git a/tests/services/pwrap_pam.in b/tests/services/pwrap_pam.in index 9b4203c..9ebc0b4 100644 --- a/tests/services/pwrap_pam.in +++ b/tests/services/pwrap_pam.in @@ -1,5 +1,5 @@ -auth required @CMAKE_CURRENT_BINARY_DIR@/pam_success.so -account required @CMAKE_CURRENT_BINARY_DIR@/pam_success.so -password required @CMAKE_CURRENT_BINARY_DIR@/pam_success.so -session required @CMAKE_CURRENT_BINARY_DIR@/pam_success.so +auth required @CMAKE_CURRENT_BINARY_DIR@/pam_example.so +account required @CMAKE_CURRENT_BINARY_DIR@/pam_example.so +password required @CMAKE_CURRENT_BINARY_DIR@/pam_example.so +session required @CMAKE_CURRENT_BINARY_DIR@/pam_example.so diff --git a/tests/test_pam_wrapper.c b/tests/test_pam_wrapper.c index d7f21ed..3890dab 100644 --- a/tests/test_pam_wrapper.c +++ b/tests/test_pam_wrapper.c @@ -99,12 +99,25 @@ static int setup(void **state) return rv; } + test_ctx->conv.appdata_ptr = (void *) "secret"; + rv = pam_start("pwrap_pam", "testuser", + &test_ctx->conv, &test_ctx->ph); + assert_int_equal(rv, PAM_SUCCESS); + *state = test_ctx; return 0; } static int teardown(void **state) { + struct pwrap_test_ctx *test_ctx; + int rv; + + test_ctx = (struct pwrap_test_ctx *) *state; + + rv = pam_end(test_ctx->ph, PAM_SUCCESS); + assert_int_equal(rv, PAM_SUCCESS); + return teardown_simple(state); } @@ -115,11 +128,6 @@ static void test_pam_authenticate(void **state) test_ctx = (struct pwrap_test_ctx *) *state; - test_ctx->conv.appdata_ptr = (void *) "secret"; - rv = pam_start("pwrap_pam", "testuser", - &test_ctx->conv, &test_ctx->ph); - assert_int_equal(rv, PAM_SUCCESS); - rv = pam_authenticate(test_ctx->ph, 0); assert_int_equal(rv, PAM_SUCCESS); } @@ -140,6 +148,33 @@ static void test_pam_authenticate_err(void **state) assert_int_equal(rv, PAM_AUTH_ERR); } +static void test_pam_acct(void **state) +{ + int rv; + struct pwrap_test_ctx *test_ctx; + + test_ctx = (struct pwrap_test_ctx *) *state; + + rv = pam_acct_mgmt(test_ctx->ph, 0); + assert_int_equal(rv, PAM_SUCCESS); +} + +static void test_pam_acct_err(void **state) +{ + int rv; + struct pwrap_test_ctx *test_ctx; + + test_ctx = (struct pwrap_test_ctx *) *state; + + test_ctx->conv.appdata_ptr = (void *) "secret"; + rv = pam_start("pwrap_pam", "testuser2", + &test_ctx->conv, &test_ctx->ph); + assert_int_equal(rv, PAM_SUCCESS); + + rv = pam_acct_mgmt(test_ctx->ph, 0); + assert_int_equal(rv, PAM_PERM_DENIED); +} + int main(void) { int rc; @@ -152,8 +187,14 @@ int main(void) { setup, teardown), cmocka_unit_test_setup_teardown(test_pam_authenticate_err, + setup_simple, + teardown), + cmocka_unit_test_setup_teardown(test_pam_acct, setup, teardown), + cmocka_unit_test_setup_teardown(test_pam_acct_err, + setup_simple, + teardown), }; rc = cmocka_run_group_tests(init_tests, NULL, NULL); |