1/*-
2 * Copyright (c) 2002-2003 Networks Associates Technology, Inc.
3 * Copyright (c) 2004-2015 Dag-Erling Sm��rgrav
4 * All rights reserved.
5 *
6 * This software was developed for the FreeBSD Project by ThinkSec AS and
7 * Network Associates Laboratories, the Security Research Division of
8 * Network Associates, Inc.  under DARPA/SPAWAR contract N66001-01-C-8035
9 * ("CBOSS"), as part of the DARPA CHATS research program.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 *    notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 *    notice, this list of conditions and the following disclaimer in the
18 *    documentation and/or other materials provided with the distribution.
19 * 3. The name of the author may not be used to endorse or promote
20 *    products derived from this software without specific prior written
21 *    permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 *
35 * $OpenPAM: openpam.h 938 2017-04-30 21:34:42Z des $
36 */
37
38#ifndef SECURITY_OPENPAM_H_INCLUDED
39#define SECURITY_OPENPAM_H_INCLUDED
40
41/*
42 * Annoying but necessary header pollution
43 */
44#include <stdarg.h>
45
46#include <security/openpam_attr.h>
47
48#ifdef __cplusplus
49extern "C" {
50#endif
51
52struct passwd;
53
54/*
55 * API extensions
56 */
57int
58openpam_borrow_cred(pam_handle_t *_pamh,
59	const struct passwd *_pwd)
60	OPENPAM_NONNULL((1,2));
61
62int
63openpam_subst(const pam_handle_t *_pamh,
64	char *_buf,
65	size_t *_bufsize,
66	const char *_template);
67
68void
69openpam_free_data(pam_handle_t *_pamh,
70	void *_data,
71	int _status);
72
73void
74openpam_free_envlist(char **_envlist);
75
76const char *
77openpam_get_option(pam_handle_t *_pamh,
78	const char *_option);
79
80int
81openpam_restore_cred(pam_handle_t *_pamh)
82	OPENPAM_NONNULL((1));
83
84int
85openpam_set_option(pam_handle_t *_pamh,
86	const char *_option,
87	const char *_value);
88
89int
90pam_error(const pam_handle_t *_pamh,
91	const char *_fmt,
92	...)
93	OPENPAM_FORMAT ((__printf__, 2, 3))
94	OPENPAM_NONNULL((1,2));
95
96int
97pam_get_authtok(pam_handle_t *_pamh,
98	int _item,
99	const char **_authtok,
100	const char *_prompt)
101	OPENPAM_NONNULL((1,3));
102
103int
104pam_info(const pam_handle_t *_pamh,
105	const char *_fmt,
106	...)
107	OPENPAM_FORMAT ((__printf__, 2, 3))
108	OPENPAM_NONNULL((1,2));
109
110int
111pam_prompt(const pam_handle_t *_pamh,
112	int _style,
113	char **_resp,
114	const char *_fmt,
115	...)
116	OPENPAM_FORMAT ((__printf__, 4, 5))
117	OPENPAM_NONNULL((1,4));
118
119int
120pam_setenv(pam_handle_t *_pamh,
121	const char *_name,
122	const char *_value,
123	int _overwrite)
124	OPENPAM_NONNULL((1,2,3));
125
126int
127pam_vinfo(const pam_handle_t *_pamh,
128	const char *_fmt,
129	va_list _ap)
130	OPENPAM_FORMAT ((__printf__, 2, 0))
131	OPENPAM_NONNULL((1,2));
132
133int
134pam_verror(const pam_handle_t *_pamh,
135	const char *_fmt,
136	va_list _ap)
137	OPENPAM_FORMAT ((__printf__, 2, 0))
138	OPENPAM_NONNULL((1,2));
139
140int
141pam_vprompt(const pam_handle_t *_pamh,
142	int _style,
143	char **_resp,
144	const char *_fmt,
145	va_list _ap)
146	OPENPAM_FORMAT ((__printf__, 4, 0))
147	OPENPAM_NONNULL((1,4));
148
149/*
150 * Read cooked lines.
151 * Checking for _IOFBF is a fairly reliable way to detect the presence
152 * of <stdio.h>, as SUSv3 requires it to be defined there.
153 */
154#ifdef _IOFBF
155char *
156openpam_readline(FILE *_f,
157	int *_lineno,
158	size_t *_lenp)
159	OPENPAM_NONNULL((1));
160
161char **
162openpam_readlinev(FILE *_f,
163	int *_lineno,
164	int *_lenp)
165	OPENPAM_NONNULL((1));
166
167char *
168openpam_readword(FILE *_f,
169	int *_lineno,
170	size_t *_lenp)
171	OPENPAM_NONNULL((1));
172#endif
173
174int
175openpam_straddch(char **_str,
176	size_t *_sizep,
177	size_t *_lenp,
178	int ch)
179	OPENPAM_NONNULL((1));
180
181/*
182 * Enable / disable optional features
183 */
184enum {
185	OPENPAM_RESTRICT_SERVICE_NAME,
186	OPENPAM_VERIFY_POLICY_FILE,
187	OPENPAM_RESTRICT_MODULE_NAME,
188	OPENPAM_VERIFY_MODULE_FILE,
189	OPENPAM_FALLBACK_TO_OTHER,
190	OPENPAM_NUM_FEATURES
191};
192
193int
194openpam_set_feature(int _feature, int _onoff);
195
196int
197openpam_get_feature(int _feature, int *_onoff);
198
199/*
200 * Log levels
201 */
202enum {
203	PAM_LOG_LIBDEBUG = -1,
204	PAM_LOG_DEBUG,
205	PAM_LOG_VERBOSE,
206	PAM_LOG_NOTICE,
207	PAM_LOG_ERROR
208};
209
210/*
211 * Log to syslog
212 */
213void
214_openpam_log(int _level,
215	const char *_func,
216	const char *_fmt,
217	...)
218	OPENPAM_FORMAT ((__printf__, 3, 4))
219	OPENPAM_NONNULL((3));
220
221#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
222#define openpam_log(lvl, ...) \
223	_openpam_log((lvl), __func__, __VA_ARGS__)
224#elif defined(__GNUC__) && (__GNUC__ >= 3)
225#define openpam_log(lvl, ...) \
226	_openpam_log((lvl), __func__, __VA_ARGS__)
227#elif defined(__GNUC__) && (__GNUC__ >= 2) && (__GNUC_MINOR__ >= 95)
228#define openpam_log(lvl, fmt...) \
229	_openpam_log((lvl), __func__, ##fmt)
230#elif defined(__GNUC__) && defined(__FUNCTION__)
231#define openpam_log(lvl, fmt...) \
232	_openpam_log((lvl), __FUNCTION__, ##fmt)
233#else
234void
235openpam_log(int _level,
236	const char *_format,
237	...)
238	OPENPAM_FORMAT ((__printf__, 2, 3))
239	OPENPAM_NONNULL((2));
240#endif
241
242/*
243 * Generic conversation function
244 */
245struct pam_message;
246struct pam_response;
247int openpam_ttyconv(int _n,
248	const struct pam_message **_msg,
249	struct pam_response **_resp,
250	void *_data);
251
252extern int openpam_ttyconv_timeout;
253
254/*
255 * Null conversation function
256 */
257int openpam_nullconv(int _n,
258	const struct pam_message **_msg,
259	struct pam_response **_resp,
260	void *_data);
261
262/*
263 * PAM primitives
264 */
265enum {
266	PAM_SM_AUTHENTICATE,
267	PAM_SM_SETCRED,
268	PAM_SM_ACCT_MGMT,
269	PAM_SM_OPEN_SESSION,
270	PAM_SM_CLOSE_SESSION,
271	PAM_SM_CHAUTHTOK,
272	/* keep this last */
273	PAM_NUM_PRIMITIVES
274};
275
276/*
277 * Dummy service module function
278 */
279#define PAM_SM_DUMMY(type)						\
280PAM_EXTERN int								\
281pam_sm_##type(pam_handle_t *pamh, int flags,				\
282    int argc, const char *argv[])					\
283{									\
284									\
285	(void)pamh;							\
286	(void)flags;							\
287	(void)argc;							\
288	(void)argv;							\
289	return (PAM_IGNORE);						\
290}
291
292/*
293 * PAM service module functions match this typedef
294 */
295struct pam_handle;
296typedef int (*pam_func_t)(struct pam_handle *, int, int, const char **);
297
298/*
299 * A struct that describes a module.
300 */
301typedef struct pam_module pam_module_t;
302struct pam_module {
303	char		*path;
304	pam_func_t	 func[PAM_NUM_PRIMITIVES];
305	void		*dlh;
306};
307
308/*
309 * Source-code compatibility with Linux-PAM modules
310 */
311#if defined(PAM_SM_AUTH) || defined(PAM_SM_ACCOUNT) || \
312	defined(PAM_SM_SESSION) || defined(PAM_SM_PASSWORD)
313# define LINUX_PAM_MODULE
314#endif
315
316#if defined(LINUX_PAM_MODULE) && !defined(PAM_SM_AUTH)
317# define _PAM_SM_AUTHENTICATE	0
318# define _PAM_SM_SETCRED	0
319#else
320# undef PAM_SM_AUTH
321# define PAM_SM_AUTH
322# define _PAM_SM_AUTHENTICATE	pam_sm_authenticate
323# define _PAM_SM_SETCRED	pam_sm_setcred
324#endif
325
326#if defined(LINUX_PAM_MODULE) && !defined(PAM_SM_ACCOUNT)
327# define _PAM_SM_ACCT_MGMT	0
328#else
329# undef PAM_SM_ACCOUNT
330# define PAM_SM_ACCOUNT
331# define _PAM_SM_ACCT_MGMT	pam_sm_acct_mgmt
332#endif
333
334#if defined(LINUX_PAM_MODULE) && !defined(PAM_SM_SESSION)
335# define _PAM_SM_OPEN_SESSION	0
336# define _PAM_SM_CLOSE_SESSION	0
337#else
338# undef PAM_SM_SESSION
339# define PAM_SM_SESSION
340# define _PAM_SM_OPEN_SESSION	pam_sm_open_session
341# define _PAM_SM_CLOSE_SESSION	pam_sm_close_session
342#endif
343
344#if defined(LINUX_PAM_MODULE) && !defined(PAM_SM_PASSWORD)
345# define _PAM_SM_CHAUTHTOK	0
346#else
347# undef PAM_SM_PASSWORD
348# define PAM_SM_PASSWORD
349# define _PAM_SM_CHAUTHTOK	pam_sm_chauthtok
350#endif
351
352/*
353 * Infrastructure for static modules using GCC linker sets.
354 * You are not expected to understand this.
355 */
356#if !defined(PAM_SOEXT)
357# define PAM_SOEXT ".so"
358#endif
359
360#if defined(OPENPAM_STATIC_MODULES)
361# if !defined(__GNUC__)
362#  error "Don't know how to build static modules on non-GNU compilers"
363# endif
364/* gcc, static linking */
365# include <sys/cdefs.h>
366# include <linker_set.h>
367# define PAM_EXTERN static
368# define PAM_MODULE_ENTRY(name)						\
369	static char _pam_name[] = name PAM_SOEXT;			\
370	static struct pam_module _pam_module = {			\
371		.path = _pam_name,					\
372		.func = {						\
373			[PAM_SM_AUTHENTICATE] = _PAM_SM_AUTHENTICATE,	\
374			[PAM_SM_SETCRED] = _PAM_SM_SETCRED,		\
375			[PAM_SM_ACCT_MGMT] = _PAM_SM_ACCT_MGMT,		\
376			[PAM_SM_OPEN_SESSION] = _PAM_SM_OPEN_SESSION,	\
377			[PAM_SM_CLOSE_SESSION] = _PAM_SM_CLOSE_SESSION, \
378			[PAM_SM_CHAUTHTOK] = _PAM_SM_CHAUTHTOK		\
379		},							\
380	};								\
381	DATA_SET(_openpam_static_modules, _pam_module)
382#else
383/* normal case */
384# define PAM_EXTERN
385# define PAM_MODULE_ENTRY(name)
386#endif
387
388#ifdef __cplusplus
389}
390#endif
391
392#endif /* !SECURITY_OPENPAM_H_INCLUDED */
393