openpam.h revision 294192
1/*-
2 * Copyright (c) 2002-2003 Networks Associates Technology, Inc.
3 * Copyright (c) 2004-2011 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 * $Id: openpam.h 648 2013-03-05 17:54:27Z 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_NUM_FEATURES
190};
191
192int
193openpam_set_feature(int _feature, int _onoff);
194
195int
196openpam_get_feature(int _feature, int *_onoff);
197
198/*
199 * Log levels
200 */
201enum {
202	PAM_LOG_LIBDEBUG = -1,
203	PAM_LOG_DEBUG,
204	PAM_LOG_VERBOSE,
205	PAM_LOG_NOTICE,
206	PAM_LOG_ERROR
207};
208
209/*
210 * Log to syslog
211 */
212void
213_openpam_log(int _level,
214	const char *_func,
215	const char *_fmt,
216	...)
217	OPENPAM_FORMAT ((__printf__, 3, 4))
218	OPENPAM_NONNULL((3));
219
220#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
221#define openpam_log(lvl, ...) \
222	_openpam_log((lvl), __func__, __VA_ARGS__)
223#elif defined(__GNUC__) && (__GNUC__ >= 3)
224#define openpam_log(lvl, ...) \
225	_openpam_log((lvl), __func__, __VA_ARGS__)
226#elif defined(__GNUC__) && (__GNUC__ >= 2) && (__GNUC_MINOR__ >= 95)
227#define openpam_log(lvl, fmt...) \
228	_openpam_log((lvl), __func__, ##fmt)
229#elif defined(__GNUC__) && defined(__FUNCTION__)
230#define openpam_log(lvl, fmt...) \
231	_openpam_log((lvl), __FUNCTION__, ##fmt)
232#else
233void
234openpam_log(int _level,
235	const char *_format,
236	...)
237	OPENPAM_FORMAT ((__printf__, 2, 3))
238	OPENPAM_NONNULL((2));
239#endif
240
241/*
242 * Generic conversation function
243 */
244struct pam_message;
245struct pam_response;
246int openpam_ttyconv(int _n,
247	const struct pam_message **_msg,
248	struct pam_response **_resp,
249	void *_data);
250
251extern int openpam_ttyconv_timeout;
252
253/*
254 * Null conversation function
255 */
256int openpam_nullconv(int _n,
257	const struct pam_message **_msg,
258	struct pam_response **_resp,
259	void *_data);
260
261/*
262 * PAM primitives
263 */
264enum {
265	PAM_SM_AUTHENTICATE,
266	PAM_SM_SETCRED,
267	PAM_SM_ACCT_MGMT,
268	PAM_SM_OPEN_SESSION,
269	PAM_SM_CLOSE_SESSION,
270	PAM_SM_CHAUTHTOK,
271	/* keep this last */
272	PAM_NUM_PRIMITIVES
273};
274
275/*
276 * Dummy service module function
277 */
278#define PAM_SM_DUMMY(type)						\
279PAM_EXTERN int								\
280pam_sm_##type(pam_handle_t *pamh, int flags,				\
281    int argc, const char *argv[])					\
282{									\
283									\
284	(void)pamh;							\
285	(void)flags;							\
286	(void)argc;							\
287	(void)argv;							\
288	return (PAM_IGNORE);						\
289}
290
291/*
292 * PAM service module functions match this typedef
293 */
294struct pam_handle;
295typedef int (*pam_func_t)(struct pam_handle *, int, int, const char **);
296
297/*
298 * A struct that describes a module.
299 */
300typedef struct pam_module pam_module_t;
301struct pam_module {
302	char		*path;
303	pam_func_t	 func[PAM_NUM_PRIMITIVES];
304	void		*dlh;
305};
306
307/*
308 * Source-code compatibility with Linux-PAM modules
309 */
310#if defined(PAM_SM_AUTH) || defined(PAM_SM_ACCOUNT) || \
311	defined(PAM_SM_SESSION) || defined(PAM_SM_PASSWORD)
312# define LINUX_PAM_MODULE
313#endif
314
315#if defined(LINUX_PAM_MODULE) && !defined(PAM_SM_AUTH)
316# define _PAM_SM_AUTHENTICATE	0
317# define _PAM_SM_SETCRED	0
318#else
319# undef PAM_SM_AUTH
320# define PAM_SM_AUTH
321# define _PAM_SM_AUTHENTICATE	pam_sm_authenticate
322# define _PAM_SM_SETCRED	pam_sm_setcred
323#endif
324
325#if defined(LINUX_PAM_MODULE) && !defined(PAM_SM_ACCOUNT)
326# define _PAM_SM_ACCT_MGMT	0
327#else
328# undef PAM_SM_ACCOUNT
329# define PAM_SM_ACCOUNT
330# define _PAM_SM_ACCT_MGMT	pam_sm_acct_mgmt
331#endif
332
333#if defined(LINUX_PAM_MODULE) && !defined(PAM_SM_SESSION)
334# define _PAM_SM_OPEN_SESSION	0
335# define _PAM_SM_CLOSE_SESSION	0
336#else
337# undef PAM_SM_SESSION
338# define PAM_SM_SESSION
339# define _PAM_SM_OPEN_SESSION	pam_sm_open_session
340# define _PAM_SM_CLOSE_SESSION	pam_sm_close_session
341#endif
342
343#if defined(LINUX_PAM_MODULE) && !defined(PAM_SM_PASSWORD)
344# define _PAM_SM_CHAUTHTOK	0
345#else
346# undef PAM_SM_PASSWORD
347# define PAM_SM_PASSWORD
348# define _PAM_SM_CHAUTHTOK	pam_sm_chauthtok
349#endif
350
351/*
352 * Infrastructure for static modules using GCC linker sets.
353 * You are not expected to understand this.
354 */
355#if !defined(PAM_SOEXT)
356# define PAM_SOEXT ".so"
357#endif
358
359#if defined(OPENPAM_STATIC_MODULES)
360# if !defined(__GNUC__)
361#  error "Don't know how to build static modules on non-GNU compilers"
362# endif
363/* gcc, static linking */
364# include <sys/cdefs.h>
365# include <linker_set.h>
366# define PAM_EXTERN static
367# define PAM_MODULE_ENTRY(name)						\
368	static char _pam_name[] = name PAM_SOEXT;			\
369	static struct pam_module _pam_module = {			\
370		.path = _pam_name,					\
371		.func = {						\
372			[PAM_SM_AUTHENTICATE] = _PAM_SM_AUTHENTICATE,	\
373			[PAM_SM_SETCRED] = _PAM_SM_SETCRED,		\
374			[PAM_SM_ACCT_MGMT] = _PAM_SM_ACCT_MGMT,		\
375			[PAM_SM_OPEN_SESSION] = _PAM_SM_OPEN_SESSION,	\
376			[PAM_SM_CLOSE_SESSION] = _PAM_SM_CLOSE_SESSION, \
377			[PAM_SM_CHAUTHTOK] = _PAM_SM_CHAUTHTOK		\
378		},							\
379	};								\
380	DATA_SET(_openpam_static_modules, _pam_module)
381#else
382/* normal case */
383# define PAM_EXTERN
384# define PAM_MODULE_ENTRY(name)
385#endif
386
387#ifdef __cplusplus
388}
389#endif
390
391#endif /* !SECURITY_OPENPAM_H_INCLUDED */
392