aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Hrozek <jakub.hrozek@posteo.se>2015-09-20 07:22:35 +0200
committerJakub Hrozek <jhrozek@redhat.com>2015-09-29 14:31:15 +0200
commit1c5af7897bd915c4f5da4bb7fd28d86b72c10e2c (patch)
treee968e4c47b0370d5ceeab572275662f3bfbc3a19
parent774467d3fed623001c6334c2d6be7077d6a380f5 (diff)
downloadpam_wrapper-1c5af7897bd915c4f5da4bb7fd28d86b72c10e2c.tar.gz
pam_wrapper-1c5af7897bd915c4f5da4bb7fd28d86b72c10e2c.tar.xz
pam_wrapper-1c5af7897bd915c4f5da4bb7fd28d86b72c10e2c.zip
pwrap: wrap pam_acct
-rw-r--r--src/pam_wrapper.c21
-rw-r--r--tests/pam_example.c136
-rw-r--r--tests/passdb3
-rw-r--r--tests/services/pwrap_pam.in8
-rw-r--r--tests/test_pam_wrapper.c51
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);