[SCM] pam wrapper repository - branch master updated
Andreas Schneider
asn at samba.org
Thu Jun 24 19:13:53 UTC 2021
The branch, master has been updated
via 88b9921 cmake: Silence warning with gcc version >= 8
via 1330009 python: Export pam_setcred flags, to be used in python testcase objects
via 6ada64a libpamtest: Add a new keyword parameter to reuse the PAM handle
via dd5608b python: Store the pam handle in the python test object
via b0ff06b python: Store the pam env in the python test object
from 0e28e3e tests: Correctly implement free_vlist()
https://git.samba.org/?p=pam_wrapper.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit 88b9921bd106ad3d06062e42fd76898525a9d542
Author: Samuel Cabrero <scabrero at suse.de>
Date: Mon Jun 21 12:46:20 2021 +0200
cmake: Silence warning with gcc version >= 8
src/python/pypamtest.c:1149:17: warning[-Wcast-function-type]: cast between
incompatible function types from ‘PyObject * (*)(PyObject *, PyObject *,
PyObject *)’ {aka ‘struct _object * (*)(struct _object *, struct _object *,
struct _object *)’} to ‘PyObject * (*)(PyObject *, PyObject *)’
{aka ‘struct _object * (*)(struct _object *, struct _object *)’}
Signed-off-by: Samuel Cabrero <scabrero at suse.de>
Reviewed-by: Andreas Schneider <asn at samba.org>
commit 1330009d5277e7e4673112be0ff9de9cf0e1a618
Author: Samuel Cabrero <scabrero at samba.org>
Date: Fri Jun 18 15:38:31 2021 +0200
python: Export pam_setcred flags, to be used in python testcase objects
Signed-off-by: Samuel Cabrero <scabrero at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
commit 6ada64a7ab52c07417bc012a200ac6e9fa5d5c2f
Author: Samuel Cabrero <scabrero at samba.org>
Date: Fri Jun 18 10:36:17 2021 +0200
libpamtest: Add a new keyword parameter to reuse the PAM handle
Add a new keyword parameter to pass and reuse a PAM handle obtained by a
previous run having a test object of type PAMTEST_KEEPHANDLE.
Signed-off-by: Samuel Cabrero <scabrero at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
commit dd5608b36a5f6d7121a8ba6590de1eacd0cc48b3
Author: Samuel Cabrero <scabrero at samba.org>
Date: Fri Jun 18 09:21:12 2021 +0200
python: Store the pam handle in the python test object
There was no way to get the PAM handler from a PAMTEST_KEEPHANDLE test
object.
The PAM handle is stored in the pam_handle member of the test object.
Signed-off-by: Samuel Cabrero <scabrero at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
commit b0ff06ba02a3c08fd4a60aacf716bc97efec9588
Author: Samuel Cabrero <scabrero at samba.org>
Date: Fri Jun 18 09:19:25 2021 +0200
python: Store the pam env in the python test object
There was no way to retrieve the PAM environment from a
PAMTEST_GETENVLIST test object.
The PAM environment is stored as a dictionary in the pam_env member of
the test object.
Signed-off-by: Samuel Cabrero <scabrero at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
-----------------------------------------------------------------------
Summary of changes:
include/libpamtest.h | 22 ++++--
src/libpamtest.c | 19 +++--
src/python/CMakeLists.txt | 4 +
src/python/pypamtest.c | 192 +++++++++++++++++++++++++++++++++++++++++++---
tests/test_pam_wrapper.c | 30 ++++----
5 files changed, 229 insertions(+), 38 deletions(-)
Changeset truncated at 500 lines:
diff --git a/include/libpamtest.h b/include/libpamtest.h
index 3fa69c7..4ebe83f 100644
--- a/include/libpamtest.h
+++ b/include/libpamtest.h
@@ -156,6 +156,8 @@ struct pamtest_conv_data {
* @param[in] test_cases List of libpamtest test cases. Must end with
* PAMTEST_CASE_SENTINEL
*
+ * @param[in] pam_handle The PAM handle to use to run the tests
+ *
* @code
* int main(void) {
* int rc;
@@ -175,10 +177,11 @@ enum pamtest_err run_pamtest_conv(const char *service,
const char *user,
pam_conv_fn conv_fn,
void *conv_userdata,
- struct pam_testcase test_cases[]);
+ struct pam_testcase test_cases[],
+ pam_handle_t *pam_handle);
#else
#define run_pamtest_conv(service, user, conv_fn, conv_data, test_cases) \
- _pamtest_conv(service, user, conv_fn, conv_data, test_cases, sizeof(test_cases)/sizeof(test_cases[0])
+ _pamtest_conv(service, user, conv_fn, conv_data, test_cases, sizeof(test_cases)/sizeof(test_cases[0], pam_handle)
#endif
#ifdef DOXYGEN
@@ -196,6 +199,8 @@ enum pamtest_err run_pamtest_conv(const char *service,
* @param[in] test_cases List of libpamtest test cases. Must end with
* PAMTEST_CASE_SENTINEL
*
+ * @param[in] pam_handle The PAM handle to use to run the tests
+ *
* @code
* int main(void) {
* int rc;
@@ -214,10 +219,11 @@ enum pamtest_err run_pamtest_conv(const char *service,
enum pamtest_err run_pamtest(const char *service,
const char *user,
struct pamtest_conv_data *conv_data,
- struct pam_testcase test_cases[]);
+ struct pam_testcase test_cases[],
+ pam_handle_t *pam_handle);
#else
-#define run_pamtest(service, user, conv_data, test_cases) \
- _pamtest(service, user, conv_data, test_cases, sizeof(test_cases)/sizeof(test_cases[0]))
+#define run_pamtest(service, user, conv_data, test_cases, pam_handle) \
+ _pamtest(service, user, conv_data, test_cases, sizeof(test_cases)/sizeof(test_cases[0]), pam_handle)
#endif
#ifdef DOXYGEN
@@ -262,13 +268,15 @@ enum pamtest_err _pamtest_conv(const char *service,
pam_conv_fn conv_fn,
void *conv_userdata,
struct pam_testcase test_cases[],
- size_t num_test_cases);
+ size_t num_test_cases,
+ pam_handle_t *pam_handle);
enum pamtest_err _pamtest(const char *service,
const char *user,
struct pamtest_conv_data *conv_data,
struct pam_testcase test_cases[],
- size_t num_test_cases);
+ size_t num_test_cases,
+ pam_handle_t *pam_handle);
const struct pam_testcase *_pamtest_failed_case(struct pam_testcase test_cases[],
size_t num_test_cases);
diff --git a/src/libpamtest.c b/src/libpamtest.c
index 4474736..6033d5a 100644
--- a/src/libpamtest.c
+++ b/src/libpamtest.c
@@ -66,7 +66,8 @@ enum pamtest_err _pamtest_conv(const char *service,
pam_conv_fn conv_fn,
void *conv_userdata,
struct pam_testcase test_cases[],
- size_t num_test_cases)
+ size_t num_test_cases,
+ pam_handle_t *pam_handle)
{
int rv;
pam_handle_t *ph;
@@ -82,9 +83,13 @@ enum pamtest_err _pamtest_conv(const char *service,
return PAMTEST_ERR_INTERNAL;
}
- rv = pam_start(service, user, &conv, &ph);
- if (rv != PAM_SUCCESS) {
- return PAMTEST_ERR_START;
+ if (pam_handle == NULL) {
+ rv = pam_start(service, user, &conv, &ph);
+ if (rv != PAM_SUCCESS) {
+ return PAMTEST_ERR_START;
+ }
+ } else {
+ ph = pam_handle;
}
for (tcindex = 0; tcindex < num_test_cases; tcindex++) {
@@ -322,7 +327,8 @@ enum pamtest_err _pamtest(const char *service,
const char *user,
struct pamtest_conv_data *conv_data,
struct pam_testcase test_cases[],
- size_t num_test_cases)
+ size_t num_test_cases,
+ pam_handle_t *pam_handle)
{
struct pamtest_conv_ctx cctx = {
.data = conv_data,
@@ -332,5 +338,6 @@ enum pamtest_err _pamtest(const char *service,
pamtest_simple_conv,
&cctx,
test_cases,
- num_test_cases);
+ num_test_cases,
+ pam_handle);
}
diff --git a/src/python/CMakeLists.txt b/src/python/CMakeLists.txt
index 3394a84..e8730d9 100644
--- a/src/python/CMakeLists.txt
+++ b/src/python/CMakeLists.txt
@@ -2,3 +2,7 @@ project(pypamtest C)
add_subdirectory(python2)
add_subdirectory(python3)
+
+set_source_files_properties(pypamtest.c
+ DIRECTORY python2 python3
+ PROPERTIES COMPILE_OPTIONS "-Wno-cast-function-type")
diff --git a/src/python/pypamtest.c b/src/python/pypamtest.c
index 8de05e9..008a85f 100644
--- a/src/python/pypamtest.c
+++ b/src/python/pypamtest.c
@@ -58,8 +58,14 @@ typedef struct {
enum pamtest_ops pam_operation;
int expected_rv;
int flags;
+
+ PyObject *pam_handle;
+ PyObject *pam_env;
} TestCaseObject;
+#define PyTestCase_AsTestCaseObject(py_obj) \
+ (TestCaseObject *)(py_obj)
+
/**********************************************************
*** module-specific exceptions
**********************************************************/
@@ -461,6 +467,22 @@ static PyMemberDef pypamtest_test_case_members[] = {
discard_const_p(char, "Additional flags for the PAM operation"),
},
+ {
+ discard_const_p(char, "pam_handle"),
+ T_OBJECT_EX,
+ offsetof(TestCaseObject, pam_handle),
+ READONLY,
+ discard_const_p(char, "Pam handle"),
+ },
+
+ {
+ discard_const_p(char, "pam_env"),
+ T_OBJECT_EX,
+ offsetof(TestCaseObject, pam_env),
+ READONLY,
+ discard_const_p(char, "Pam env"),
+ },
+
{ NULL, 0, 0, 0, NULL } /* Sentinel */
};
@@ -773,6 +795,8 @@ static int py_testcase_to_cstruct(PyObject *py_test, struct pam_testcase *test)
int rc;
long value;
+ memset(test, 0, sizeof(struct pam_testcase));
+
rc = py_testcase_get(py_test, "pam_operation", &value);
if (rc != 0) {
return rc;
@@ -903,6 +927,84 @@ static int py_tc_list_to_cstruct_list(PyObject *py_test_list,
return 0;
}
+static int cstruct_to_py_testcase(PyObject *pytest, struct pam_testcase *ctest)
+{
+ TestCaseObject *t = PyTestCase_AsTestCaseObject(pytest);
+ size_t i;
+ int rc;
+
+ switch (t->pam_operation) {
+ case PAMTEST_GETENVLIST:
+ if (ctest->case_out.envlist == NULL) {
+ break;
+ }
+
+ t->pam_env = PyDict_New();
+ if (t->pam_env == NULL) {
+ return ENOMEM;
+ }
+ for (i = 0; ctest->case_out.envlist[i] != NULL; i++) {
+ char *key = NULL;
+ char *val = NULL;
+ key = strdup(ctest->case_out.envlist[i]);
+ if (key == NULL) {
+ return ENOMEM;
+ }
+ val = strrchr(key, '=');
+ if (val == NULL) {
+ PyErr_Format(PyExc_IOError,
+ "Failed to parse PAM environment "
+ "variable");
+ free(key);
+ return EINVAL;
+ }
+ *val = '\0';
+ rc = PyDict_SetItem(t->pam_env,
+ PyUnicode_FromString(key),
+ PyUnicode_FromString(val + 1));
+ free(key);
+ if (rc == -1) {
+ return rc;
+ }
+ }
+ break;
+ case PAMTEST_KEEPHANDLE:
+ t->pam_handle = PyCapsule_New(ctest->case_out.ph, NULL, NULL);
+ if (t->pam_handle == NULL) {
+ return ENOMEM;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static int cstruct_list_to_py_tc_list(PyObject *py_test_list,
+ Py_ssize_t num_tests,
+ struct pam_testcase *test_list)
+{
+ Py_ssize_t i;
+ PyObject *py_test = NULL;
+ int rc;
+
+ for (i = 0; i < num_tests; i++) {
+ py_test = PySequence_GetItem(py_test_list, i);
+ if (py_test == NULL) {
+ return EIO;
+ }
+
+ rc = cstruct_to_py_testcase(py_test, &test_list[i]);
+ Py_DECREF(py_test);
+ if (rc != 0) {
+ return EIO;
+ }
+ }
+
+ return 0;
+}
+
PyDoc_STRVAR(RunPamTest__doc__,
"Run PAM tests\n\n"
"This function runs PAM test cases and reports result\n"
@@ -917,7 +1019,9 @@ PyDoc_STRVAR(RunPamTest__doc__,
"conversation for PAM_PROMPT_ECHO_ON input.\n"
);
-static PyObject *pypamtest_run_pamtest(PyObject *module, PyObject *args)
+static PyObject *pypamtest_run_pamtest(PyObject *module,
+ PyObject *args,
+ PyObject *kwargs)
{
int ok;
int rc;
@@ -926,21 +1030,33 @@ static PyObject *pypamtest_run_pamtest(PyObject *module, PyObject *args)
PyObject *py_test_list;
PyObject *py_echo_off = NULL;
PyObject *py_echo_on = NULL;
+ PyObject *py_pam_handle = NULL;
Py_ssize_t num_tests;
struct pam_testcase *test_list;
enum pamtest_err perr;
struct pamtest_conv_data conv_data;
+ pam_handle_t *pam_handle = NULL;
TestResultObject *result = NULL;
+ const char * const kwnames[] = { "username",
+ "service",
+ "tests",
+ "echo_off",
+ "echo_on",
+ "handle",
+ NULL };
(void) module; /* unused */
- ok = PyArg_ParseTuple(args,
- discard_const_p(char, "ssO|OO"),
- &username,
- &service,
- &py_test_list,
- &py_echo_off,
- &py_echo_on);
+ ok = PyArg_ParseTupleAndKeywords(args,
+ kwargs,
+ discard_const_p(char, "ssO|OOO"),
+ discard_const_p(char *, kwnames),
+ &username,
+ &service,
+ &py_test_list,
+ &py_echo_off,
+ &py_echo_on,
+ &py_pam_handle);
if (!ok) {
return NULL;
}
@@ -976,7 +1092,23 @@ static PyObject *pypamtest_run_pamtest(PyObject *module, PyObject *args)
return NULL;
}
- perr = _pamtest(service, username, &conv_data, test_list, num_tests);
+ if (py_pam_handle != NULL) {
+ pam_handle = (pam_handle_t *)PyCapsule_GetPointer(py_pam_handle,
+ NULL);
+ if (pam_handle == NULL) {
+ PyMem_Free(test_list);
+ PyErr_Format(PyExc_IOError,
+ "Failed to get the pam handle pointer");
+ return NULL;
+ }
+ }
+
+ perr = _pamtest(service,
+ username,
+ &conv_data,
+ test_list,
+ num_tests,
+ pam_handle);
if (perr != PAMTEST_ERR_OK) {
free_conv_data(&conv_data);
set_pypamtest_exception(PyExc_PamTestError,
@@ -986,6 +1118,18 @@ static PyObject *pypamtest_run_pamtest(PyObject *module, PyObject *args)
PyMem_Free(test_list);
return NULL;
}
+
+ rc = cstruct_list_to_py_tc_list(py_test_list, num_tests, test_list);
+ if (rc != 0) {
+ if (rc == ENOMEM) {
+ PyErr_NoMemory();
+ return NULL;
+ } else {
+ PyErr_Format(PyExc_IOError,
+ "Cannot convert C structure to python");
+ return NULL;
+ }
+ }
PyMem_Free(test_list);
result = construct_test_conv_result(conv_data.out_info,
@@ -1003,7 +1147,7 @@ static PyMethodDef pypamtest_module_methods[] = {
{
discard_const_p(char, "run_pamtest"),
(PyCFunction) pypamtest_run_pamtest,
- METH_VARARGS,
+ METH_VARARGS | METH_KEYWORDS,
RunPamTest__doc__,
},
@@ -1115,6 +1259,34 @@ PyMODINIT_FUNC initpypamtest(void)
RETURN_ON_ERROR;
}
+ ret = PyModule_AddIntConstant(m,
+ "PAMTEST_FLAG_DELETE_CRED",
+ PAM_DELETE_CRED);
+ if (ret == -1) {
+ RETURN_ON_ERROR;
+ }
+
+ ret = PyModule_AddIntConstant(m,
+ "PAMTEST_FLAG_ESTABLISH_CRED",
+ PAM_ESTABLISH_CRED);
+ if (ret == -1) {
+ RETURN_ON_ERROR;
+ }
+
+ ret = PyModule_AddIntConstant(m,
+ "PAMTEST_FLAG_REINITIALIZE_CRED",
+ PAM_REINITIALIZE_CRED);
+ if (ret == -1) {
+ RETURN_ON_ERROR;
+ }
+
+ ret = PyModule_AddIntConstant(m,
+ "PAMTEST_FLAG_REFRESH_CRED",
+ PAM_REFRESH_CRED);
+ if (ret == -1) {
+ RETURN_ON_ERROR;
+ }
+
pypam_object.type_obj = &pypamtest_test_case;
if (PyType_Ready(pypam_object.type_obj) < 0) {
RETURN_ON_ERROR;
diff --git a/tests/test_pam_wrapper.c b/tests/test_pam_wrapper.c
index 7e8b9ee..1e0c292 100644
--- a/tests/test_pam_wrapper.c
+++ b/tests/test_pam_wrapper.c
@@ -267,7 +267,7 @@ static void test_pam_authenticate(void **state)
ZERO_STRUCT(conv_data);
conv_data.in_echo_off = trinity_authtoks;
- perr = run_pamtest("matrix", "trinity", &conv_data, tests);
+ perr = run_pamtest("matrix", "trinity", &conv_data, tests, NULL);
assert_int_equal(perr, PAMTEST_ERR_OK);
}
@@ -287,7 +287,7 @@ static void test_pam_authenticate_null_password(void **state)
ZERO_STRUCT(conv_data);
conv_data.in_echo_off = empty_authtoks;
- perr = run_pamtest("matrix", "trinity", &conv_data, tests);
+ perr = run_pamtest("matrix", "trinity", &conv_data, tests, NULL);
assert_int_equal(perr, PAMTEST_ERR_OK);
}
@@ -308,7 +308,7 @@ static void test_pam_authenticate_err(void **state)
ZERO_STRUCT(conv_data);
conv_data.in_echo_off = trinity_authtoks;
- perr = run_pamtest("matrix", "trinity", &conv_data, tests);
+ perr = run_pamtest("matrix", "trinity", &conv_data, tests, NULL);
assert_int_equal(perr, PAMTEST_ERR_OK);
}
@@ -321,7 +321,7 @@ static void test_pam_acct(void **state)
(void) state; /* unused */
- perr = run_pamtest("matrix", "trinity", NULL, tests);
+ perr = run_pamtest("matrix", "trinity", NULL, tests, NULL);
assert_int_equal(perr, PAMTEST_ERR_OK);
}
@@ -334,7 +334,7 @@ static void test_pam_acct_err(void **state)
(void) state; /* unused */
- perr = run_pamtest("matrix", "neo", NULL, tests);
+ perr = run_pamtest("matrix", "neo", NULL, tests, NULL);
assert_int_equal(perr, PAMTEST_ERR_OK);
}
@@ -458,7 +458,7 @@ static void test_pam_session(void **state)
(void) state; /* unused */
- perr = run_pamtest("matrix", "trinity", NULL, tests);
+ perr = run_pamtest("matrix", "trinity", NULL, tests, NULL);
assert_int_equal(perr, PAMTEST_ERR_OK);
v = string_in_list(tests[1].case_out.envlist, "HOMEDIR");
@@ -500,7 +500,7 @@ static void test_pam_chauthtok(void **state)
ZERO_STRUCT(conv_data);
conv_data.in_echo_off = trinity_new_authtoks;
- perr = run_pamtest("matrix", "trinity", &conv_data, tests);
+ perr = run_pamtest("matrix", "trinity", &conv_data, tests, NULL);
assert_int_equal(perr, PAMTEST_ERR_OK);
}
@@ -523,7 +523,7 @@ static void test_pam_chauthtok_prelim_failed(void **state)
ZERO_STRUCT(conv_data);
conv_data.in_echo_off = trinity_new_authtoks;
- perr = run_pamtest("matrix", "trinity", &conv_data, tests);
+ perr = run_pamtest("matrix", "trinity", &conv_data, tests, NULL);
assert_int_equal(perr, PAMTEST_ERR_OK);
}
@@ -546,7 +546,7 @@ static void test_pam_chauthtok_diff_passwords(void **state)
ZERO_STRUCT(conv_data);
conv_data.in_echo_off = trinity_new_authtoks;
- perr = run_pamtest("matrix", "trinity", &conv_data, tests);
+ perr = run_pamtest("matrix", "trinity", &conv_data, tests, NULL);
assert_int_equal(perr, PAMTEST_ERR_OK);
}
@@ -562,7 +562,7 @@ static void test_pam_setcred(void **state)
(void) state; /* unused */
- perr = run_pamtest("matrix", "trinity", NULL, tests);
+ perr = run_pamtest("matrix", "trinity", NULL, tests, NULL);
assert_int_equal(perr, PAMTEST_ERR_OK);
/* environment is clean before setcred */
--
pam wrapper repository
More information about the samba-cvs
mailing list