docs-xml: some fixes to acl parameter documentation
[Samba.git] / third_party / pam_wrapper / libpamtest.h
blob4b4a50ecd5664694180e7b06d8376064ec4c9ac3
1 /*
2 * Copyright (c) 2015 Andreas Schneider <asn@samba.org>
3 * Copyright (c) 2015 Jakub Hrozek <jakub.hrozek@posteo.se>
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #ifndef __LIBPAMTEST_H_
20 #define __LIBPAMTEST_H_
22 #include <stddef.h>
23 #include <stdint.h>
24 #include <security/pam_appl.h>
26 /**
27 * @defgroup pamtest The pamtest API
29 * @{
32 /**
33 * @brief The enum which describes the operations performed by pamtest().
35 enum pamtest_ops {
36 /** run pam_authenticate to authenticate the account */
37 PAMTEST_AUTHENTICATE,
38 /** run pam_setcred() to establish/delete user credentials */
39 PAMTEST_SETCRED,
40 /** run pam_acct_mgmt() to validate the PAM account */
41 PAMTEST_ACCOUNT,
42 /** run pam_open_session() to start a PAM session */
43 PAMTEST_OPEN_SESSION,
44 /** run pam_close_session() to end a PAM session */
45 PAMTEST_CLOSE_SESSION,
46 /** run pam_chauthtok() to update the authentication token */
47 PAMTEST_CHAUTHTOK,
49 /**
50 * If this option is set the test will call pam_getenvlist() and copy
51 * the environment into case_out.envlist.
53 PAMTEST_GETENVLIST = 20,
54 /**
55 * This will prevent calling pam_end() and will just return the
56 * PAM handle in case_out.ph.
58 PAMTEST_KEEPHANDLE,
62 /**
63 * @brief The PAM testcase struction. Use the pam_test and pam_test_flags
64 * macros to fill them.
66 * @see run_pamtest()
68 struct pam_testcase {
69 enum pamtest_ops pam_operation; /* The pam operation to run */
70 int expected_rv; /* What we expect the op to return */
71 int flags; /* Extra flags to pass to the op */
73 int op_rv; /* What the op really returns */
75 union {
76 char **envlist; /* output of PAMTEST_ENVLIST */
77 pam_handle_t *ph; /* output of PAMTEST_KEEPHANDLE */
78 } case_out; /* depends on pam_operation, mostly unused */
81 /** Initializes a pam_tescase structure. */
82 #define pam_test(op, expected) { op, expected, 0, 0, { .envlist = NULL } }
83 /** Initializes a CMUnitTest structure with additional PAM flags. */
84 #define pam_test_flags(op, expected, flags) { op, expected, flags, 0, { .envlist = NULL } }
86 /**
87 * @brief The return code of the pamtest function
89 enum pamtest_err {
90 /** Testcases returns correspond with input */
91 PAMTEST_ERR_OK,
92 /** pam_start() failed */
93 PAMTEST_ERR_START,
94 /** A testcase failed. Use pamtest_failed_case */
95 PAMTEST_ERR_CASE,
96 /** Could not run a test case */
97 PAMTEST_ERR_OP,
98 /** pam_end failed */
99 PAMTEST_ERR_END,
100 /** Handled internally */
101 PAMTEST_ERR_KEEPHANDLE,
102 /** Internal error - bad input or similar */
103 PAMTEST_ERR_INTERNAL,
107 * @brief PAM conversation function, defined in pam_conv(3)
109 * This is just a typedef to use in our declarations. See man pam_conv(3)
110 * for more details.
112 typedef int (*pam_conv_fn)(int num_msg,
113 const struct pam_message **msg,
114 struct pam_response **resp,
115 void *appdata_ptr);
118 * @brief This structure should be used when using run_pamtest,
119 * which uses an internal conversation function.
121 struct pamtest_conv_data {
122 /** When the conversation function receives PAM_PROMPT_ECHO_OFF,
123 * it reads the auth token from the in_echo_off array and keeps
124 * an index internally.
126 const char **in_echo_off;
127 /** When the conversation function receives PAM_PROMPT_ECHO_ON,
128 * it reads the input from the in_echo_off array and keeps
129 * an index internally.
131 const char **in_echo_on;
132 /** Captures messages through PAM_ERROR_MSG. The test caller is
133 * responsible for allocating enough space in the array.
135 char **out_err;
136 /** Captures messages through PAM_TEXT_INFO. The test caller is
137 * responsible for allocating enough space in the array.
139 char **out_info;
142 #ifdef DOXYGEN
144 * @brief Run libpamtest test cases
146 * This is using the default libpamtest conversation function.
148 * @param[in] service The PAM service to use in the conversation
150 * @param[in] user The user to run conversation as
152 * @param[in] conv_fn Test-specific conversation function
154 * @param[in] conv_userdata Test-specific conversation data
156 * @param[in] test_cases List of libpamtest test cases. Must end with
157 * PAMTEST_CASE_SENTINEL
159 * @param[in] pam_handle The PAM handle to use to run the tests
161 * @code
162 * int main(void) {
163 * int rc;
164 * const struct pam_testcase tests[] = {
165 * pam_test(PAM_AUTHENTICATE, PAM_SUCCESS),
166 * };
168 * rc = run_pamtest(tests, NULL, NULL);
170 * return rc;
172 * @endcode
174 * @return PAMTEST_ERR_OK on success, else the error code matching the failure.
176 enum pamtest_err run_pamtest_conv(const char *service,
177 const char *user,
178 pam_conv_fn conv_fn,
179 void *conv_userdata,
180 struct pam_testcase test_cases[],
181 pam_handle_t *pam_handle);
182 #else
183 #define run_pamtest_conv(service, user, conv_fn, conv_data, test_cases, pam_handle) \
184 _pamtest_conv(service, user, conv_fn, conv_data, test_cases, sizeof(test_cases)/sizeof(test_cases[0], pam_handle)
185 #endif
187 #ifdef DOXYGEN
189 * @brief Run libpamtest test cases
191 * This is using the default libpamtest conversation function.
193 * @param[in] service The PAM service to use in the conversation
195 * @param[in] user The user to run conversation as
197 * @param[in] conv_data Test-specific conversation data
199 * @param[in] test_cases List of libpamtest test cases. Must end with
200 * PAMTEST_CASE_SENTINEL
202 * @param[in] pam_handle The PAM handle to use to run the tests
204 * @code
205 * int main(void) {
206 * int rc;
207 * const struct pam_testcase tests[] = {
208 * pam_test(PAM_AUTHENTICATE, PAM_SUCCESS),
209 * };
211 * rc = run_pamtest(tests, NULL, NULL);
213 * return rc;
215 * @endcode
217 * @return PAMTEST_ERR_OK on success, else the error code matching the failure.
219 enum pamtest_err run_pamtest(const char *service,
220 const char *user,
221 struct pamtest_conv_data *conv_data,
222 struct pam_testcase test_cases[],
223 pam_handle_t *pam_handle);
224 #else
225 #define run_pamtest(service, user, conv_data, test_cases, pam_handle) \
226 _pamtest(service, user, conv_data, test_cases, sizeof(test_cases)/sizeof(test_cases[0]), pam_handle)
227 #endif
229 #ifdef DOXYGEN
231 * @brief Helper you can call if run_pamtest() fails.
233 * If PAMTEST_ERR_CASE is returned by run_pamtest() you should call this
234 * function get a pointer to the failed test case.
236 * @param[in] test_cases The array of tests.
238 * @return a pointer to the array of test_cases[] that corresponds to the
239 * first test case where the expected error code doesn't match the real error
240 * code.
242 const struct pam_testcase *pamtest_failed_case(struct pam_testcase *test_cases);
243 #else
244 #define pamtest_failed_case(test_cases) \
245 _pamtest_failed_case(test_cases, sizeof(test_cases) / sizeof(test_cases[0]))
246 #endif
249 * @brief return a string representation of libpamtest error code.
251 * @param[in] perr libpamtest error code
253 * @return String representation of the perr argument. Never returns NULL.
255 const char *pamtest_strerror(enum pamtest_err perr);
258 * @brief This frees the string array returned by the PAMTEST_GETENVLIST test.
260 * @param[in] envlist The array to free.
262 void pamtest_free_env(char **envlist);
265 /* Internal function protypes */
266 enum pamtest_err _pamtest_conv(const char *service,
267 const char *user,
268 pam_conv_fn conv_fn,
269 void *conv_userdata,
270 struct pam_testcase test_cases[],
271 size_t num_test_cases,
272 pam_handle_t *pam_handle);
274 enum pamtest_err _pamtest(const char *service,
275 const char *user,
276 struct pamtest_conv_data *conv_data,
277 struct pam_testcase test_cases[],
278 size_t num_test_cases,
279 pam_handle_t *pam_handle);
281 const struct pam_testcase *_pamtest_failed_case(struct pam_testcase test_cases[],
282 size_t num_test_cases);
284 /** @} */
286 #endif /* __LIBPAMTEST_H_ */