openpam.h revision 228692
191094Sdes/*-
2115619Sdes * Copyright (c) 2002-2003 Networks Associates Technology, Inc.
3228692Sdes * Copyright (c) 2004-2011 Dag-Erling Sm��rgrav
491094Sdes * All rights reserved.
591094Sdes *
691094Sdes * This software was developed for the FreeBSD Project by ThinkSec AS and
799158Sdes * Network Associates Laboratories, the Security Research Division of
899158Sdes * Network Associates, Inc.  under DARPA/SPAWAR contract N66001-01-C-8035
999158Sdes * ("CBOSS"), as part of the DARPA CHATS research program.
1091094Sdes *
1191094Sdes * Redistribution and use in source and binary forms, with or without
1291094Sdes * modification, are permitted provided that the following conditions
1391094Sdes * are met:
1491094Sdes * 1. Redistributions of source code must retain the above copyright
1591094Sdes *    notice, this list of conditions and the following disclaimer.
1691094Sdes * 2. Redistributions in binary form must reproduce the above copyright
1791094Sdes *    notice, this list of conditions and the following disclaimer in the
1891094Sdes *    documentation and/or other materials provided with the distribution.
1991094Sdes * 3. The name of the author may not be used to endorse or promote
2091094Sdes *    products derived from this software without specific prior written
2191094Sdes *    permission.
2291094Sdes *
2391094Sdes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
2491094Sdes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2591094Sdes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2691094Sdes * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2791094Sdes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2891094Sdes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2991094Sdes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3091094Sdes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3191094Sdes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3291094Sdes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3391094Sdes * SUCH DAMAGE.
3491094Sdes *
35228692Sdes * $Id: openpam.h 455 2011-10-29 18:31:11Z des $
3691094Sdes */
3791094Sdes
38174832Sdes#ifndef SECURITY_OPENPAM_H_INCLUDED
39174832Sdes#define SECURITY_OPENPAM_H_INCLUDED
4091094Sdes
4191094Sdes/*
4291094Sdes * Annoying but necessary header pollution
4391094Sdes */
4491094Sdes#include <stdarg.h>
4591094Sdes
46174832Sdes#include <security/openpam_attr.h>
47174832Sdes
4891094Sdes#ifdef __cplusplus
4991094Sdesextern "C" {
5091094Sdes#endif
5191094Sdes
5294209Sdesstruct passwd;
5394209Sdes
5491094Sdes/*
5591094Sdes * API extensions
5691094Sdes */
5794209Sdesint
5894209Sdesopenpam_borrow_cred(pam_handle_t *_pamh,
59174832Sdes	const struct passwd *_pwd)
60174832Sdes	OPENPAM_NONNULL((1,2));
6194209Sdes
62228692Sdesint
63228692Sdesopenpam_subst(const pam_handle_t *_pamh,
64228692Sdes	char *_buf,
65228692Sdes	size_t *_bufsize,
66228692Sdes	const char *_template);
67228692Sdes
6894209Sdesvoid
6994209Sdesopenpam_free_data(pam_handle_t *_pamh,
7094209Sdes	void *_data,
7194209Sdes	int _status);
7294209Sdes
73141098Sdesvoid
74141098Sdesopenpam_free_envlist(char **_envlist);
75141098Sdes
7691100Sdesconst char *
7791100Sdesopenpam_get_option(pam_handle_t *_pamh,
7891100Sdes	const char *_option);
7991100Sdes
8091094Sdesint
81174832Sdesopenpam_restore_cred(pam_handle_t *_pamh)
82174832Sdes	OPENPAM_NONNULL((1));
8394209Sdes
8494209Sdesint
8591100Sdesopenpam_set_option(pam_handle_t *_pamh,
8691100Sdes	const char *_option,
8791100Sdes	const char *_value);
8891100Sdes
8991100Sdesint
90174832Sdespam_error(const pam_handle_t *_pamh,
9191094Sdes	const char *_fmt,
92174832Sdes	...)
93174832Sdes	OPENPAM_FORMAT ((__printf__, 2, 3))
94174832Sdes	OPENPAM_NONNULL((1,2));
9591094Sdes
9691094Sdesint
9791094Sdespam_get_authtok(pam_handle_t *_pamh,
9893982Sdes	int _item,
9991094Sdes	const char **_authtok,
100174832Sdes	const char *_prompt)
101174832Sdes	OPENPAM_NONNULL((1,3));
10291094Sdes
10391094Sdesint
104174832Sdespam_info(const pam_handle_t *_pamh,
10591094Sdes	const char *_fmt,
106174832Sdes	...)
107174832Sdes	OPENPAM_FORMAT ((__printf__, 2, 3))
108174832Sdes	OPENPAM_NONNULL((1,2));
10991094Sdes
11091094Sdesint
111174832Sdespam_prompt(const pam_handle_t *_pamh,
11291094Sdes	int _style,
11391094Sdes	char **_resp,
11491094Sdes	const char *_fmt,
115174832Sdes	...)
116174832Sdes	OPENPAM_FORMAT ((__printf__, 4, 5))
117174832Sdes	OPENPAM_NONNULL((1,4));
11891094Sdes
11991094Sdesint
12091094Sdespam_setenv(pam_handle_t *_pamh,
12191094Sdes	const char *_name,
12291094Sdes	const char *_value,
123174832Sdes	int _overwrite)
124174832Sdes	OPENPAM_NONNULL((1,2,3));
12591094Sdes
12691094Sdesint
127174832Sdespam_vinfo(const pam_handle_t *_pamh,
12891094Sdes	const char *_fmt,
129174832Sdes	va_list _ap)
130174832Sdes	OPENPAM_FORMAT ((__printf__, 2, 0))
131174832Sdes	OPENPAM_NONNULL((1,2));
13291094Sdes
13391094Sdesint
134174832Sdespam_verror(const pam_handle_t *_pamh,
13591094Sdes	const char *_fmt,
136174832Sdes	va_list _ap)
137174832Sdes	OPENPAM_FORMAT ((__printf__, 2, 0))
138174832Sdes	OPENPAM_NONNULL((1,2));
13991094Sdes
14091094Sdesint
141174832Sdespam_vprompt(const pam_handle_t *_pamh,
14291094Sdes	int _style,
14391094Sdes	char **_resp,
14491094Sdes	const char *_fmt,
145174832Sdes	va_list _ap)
146174832Sdes	OPENPAM_FORMAT ((__printf__, 4, 0))
147174832Sdes	OPENPAM_NONNULL((1,4));
14891094Sdes
14991094Sdes/*
150115619Sdes * Read cooked lines.
151117610Sdes * Checking for _IOFBF is a fairly reliable way to detect the presence
152117610Sdes * of <stdio.h>, as SUSv3 requires it to be defined there.
153115619Sdes */
154117610Sdes#ifdef _IOFBF
155115619Sdeschar *
156115619Sdesopenpam_readline(FILE *_f,
157115619Sdes	int *_lineno,
158174832Sdes	size_t *_lenp)
159174832Sdes	OPENPAM_NONNULL((1));
160115619Sdes#endif
161115619Sdes
162115619Sdes/*
16391094Sdes * Log levels
16491094Sdes */
16591094Sdesenum {
16691094Sdes	PAM_LOG_DEBUG,
16791094Sdes	PAM_LOG_VERBOSE,
16891094Sdes	PAM_LOG_NOTICE,
16991094Sdes	PAM_LOG_ERROR
17091094Sdes};
17191094Sdes
17291094Sdes/*
17391094Sdes * Log to syslog
17491094Sdes */
17593982Sdesvoid
17693982Sdes_openpam_log(int _level,
17791094Sdes	const char *_func,
17891094Sdes	const char *_fmt,
179125647Sdes	...)
180174832Sdes	OPENPAM_FORMAT ((__printf__, 3, 4))
181174832Sdes	OPENPAM_NONNULL((3));
18291094Sdes
18397241Sdes#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
18497241Sdes#define openpam_log(lvl, ...) \
18597241Sdes	_openpam_log((lvl), __func__, __VA_ARGS__)
18697241Sdes#elif defined(__GNUC__) && (__GNUC__ >= 3)
18797241Sdes#define openpam_log(lvl, ...) \
18897241Sdes	_openpam_log((lvl), __func__, __VA_ARGS__)
18993982Sdes#elif defined(__GNUC__) && (__GNUC__ >= 2) && (__GNUC_MINOR__ >= 95)
19094562Sdes#define openpam_log(lvl, fmt...) \
19194878Sdes	_openpam_log((lvl), __func__, ##fmt)
19293982Sdes#elif defined(__GNUC__) && defined(__FUNCTION__)
19391094Sdes#define openpam_log(lvl, fmt...) \
19493982Sdes	_openpam_log((lvl), __FUNCTION__, ##fmt)
19591094Sdes#else
19693982Sdesvoid
19793982Sdesopenpam_log(int _level,
19893982Sdes	const char *_format,
199174832Sdes 	...)
200174832Sdes 	OPENPAM_FORMAT ((__printf__, 2, 3))
201174832Sdes	OPENPAM_NONNULL((2));
20291094Sdes#endif
20391094Sdes
20491094Sdes/*
20591094Sdes * Generic conversation function
20691094Sdes */
20791094Sdesstruct pam_message;
20891094Sdesstruct pam_response;
20991094Sdesint openpam_ttyconv(int _n,
21091094Sdes	const struct pam_message **_msg,
21191094Sdes	struct pam_response **_resp,
21291094Sdes	void *_data);
21391094Sdes
214117610Sdesextern int openpam_ttyconv_timeout;
215117610Sdes
21691094Sdes/*
21795908Sdes * Null conversation function
21895908Sdes */
21995908Sdesint openpam_nullconv(int _n,
22095908Sdes	const struct pam_message **_msg,
22195908Sdes	struct pam_response **_resp,
22295908Sdes	void *_data);
22395908Sdes
22495908Sdes/*
22591094Sdes * PAM primitives
22691094Sdes */
22791094Sdesenum {
22891094Sdes	PAM_SM_AUTHENTICATE,
22991094Sdes	PAM_SM_SETCRED,
23091094Sdes	PAM_SM_ACCT_MGMT,
23191094Sdes	PAM_SM_OPEN_SESSION,
23291094Sdes	PAM_SM_CLOSE_SESSION,
23391094Sdes	PAM_SM_CHAUTHTOK,
23491094Sdes	/* keep this last */
23591094Sdes	PAM_NUM_PRIMITIVES
23691094Sdes};
23791094Sdes
23891094Sdes/*
23991094Sdes * Dummy service module function
24091094Sdes */
24191094Sdes#define PAM_SM_DUMMY(type)						\
24291094SdesPAM_EXTERN int								\
24391094Sdespam_sm_##type(pam_handle_t *pamh, int flags,				\
24491094Sdes    int argc, const char *argv[])					\
24591094Sdes{									\
246174832Sdes									\
247174832Sdes	(void)pamh;							\
248174832Sdes	(void)flags;							\
249174832Sdes	(void)argc;							\
250174832Sdes	(void)argv;							\
25191094Sdes	return (PAM_IGNORE);						\
25291094Sdes}
25391094Sdes
25491094Sdes/*
25591094Sdes * PAM service module functions match this typedef
25691094Sdes */
25791094Sdesstruct pam_handle;
25891094Sdestypedef int (*pam_func_t)(struct pam_handle *, int, int, const char **);
25991094Sdes
26091094Sdes/*
26191094Sdes * A struct that describes a module.
26291094Sdes */
26391094Sdestypedef struct pam_module pam_module_t;
26491094Sdesstruct pam_module {
26591684Sdes	char		*path;
26691094Sdes	pam_func_t	 func[PAM_NUM_PRIMITIVES];
26791094Sdes	void		*dlh;
26891094Sdes};
26991094Sdes
27091094Sdes/*
27194532Sdes * Source-code compatibility with Linux-PAM modules
27294532Sdes */
27394532Sdes#if defined(PAM_SM_AUTH) || defined(PAM_SM_ACCOUNT) || \
27494532Sdes	defined(PAM_SM_SESSION) || defined(PAM_SM_PASSWORD)
275174832Sdes# define LINUX_PAM_MODULE
27694532Sdes#endif
277174832Sdes
27894532Sdes#if defined(LINUX_PAM_MODULE) && !defined(PAM_SM_AUTH)
279174832Sdes# define _PAM_SM_AUTHENTICATE	0
280174832Sdes# define _PAM_SM_SETCRED	0
28194532Sdes#else
282174832Sdes# undef PAM_SM_AUTH
283174832Sdes# define PAM_SM_AUTH
284174832Sdes# define _PAM_SM_AUTHENTICATE	pam_sm_authenticate
285174832Sdes# define _PAM_SM_SETCRED	pam_sm_setcred
28694532Sdes#endif
287174832Sdes
28894532Sdes#if defined(LINUX_PAM_MODULE) && !defined(PAM_SM_ACCOUNT)
289174832Sdes# define _PAM_SM_ACCT_MGMT	0
29094532Sdes#else
291174832Sdes# undef PAM_SM_ACCOUNT
292174832Sdes# define PAM_SM_ACCOUNT
293174832Sdes# define _PAM_SM_ACCT_MGMT	pam_sm_acct_mgmt
29494532Sdes#endif
295174832Sdes
29694532Sdes#if defined(LINUX_PAM_MODULE) && !defined(PAM_SM_SESSION)
297174832Sdes# define _PAM_SM_OPEN_SESSION	0
298174832Sdes# define _PAM_SM_CLOSE_SESSION	0
29994532Sdes#else
300174832Sdes# undef PAM_SM_SESSION
301174832Sdes# define PAM_SM_SESSION
302174832Sdes# define _PAM_SM_OPEN_SESSION	pam_sm_open_session
303174832Sdes# define _PAM_SM_CLOSE_SESSION	pam_sm_close_session
30494532Sdes#endif
305174832Sdes
30694532Sdes#if defined(LINUX_PAM_MODULE) && !defined(PAM_SM_PASSWORD)
307174832Sdes# define _PAM_SM_CHAUTHTOK	0
30894532Sdes#else
309174832Sdes# undef PAM_SM_PASSWORD
310174832Sdes# define PAM_SM_PASSWORD
311174832Sdes# define _PAM_SM_CHAUTHTOK	pam_sm_chauthtok
31294532Sdes#endif
31394532Sdes
31494532Sdes/*
31591094Sdes * Infrastructure for static modules using GCC linker sets.
31691094Sdes * You are not expected to understand this.
31791094Sdes */
318188720Sdes#if !defined(PAM_SOEXT)
319174832Sdes# define PAM_SOEXT ".so"
32091094Sdes#endif
321174832Sdes
322188720Sdes#if defined(OPENPAM_STATIC_MODULES)
323188720Sdes# if !defined(__GNUC__)
324188720Sdes#  error "Don't know how to build static modules on non-GNU compilers"
325188720Sdes# endif
32691094Sdes/* gcc, static linking */
327174832Sdes# include <sys/cdefs.h>
328174832Sdes# include <linker_set.h>
329174832Sdes# define PAM_EXTERN static
330174832Sdes# define PAM_MODULE_ENTRY(name)						\
331174832Sdes	static char _pam_name[] = name PAM_SOEXT;			\
332174832Sdes	static struct pam_module _pam_module = {			\
333174832Sdes		.path = _pam_name,					\
334174832Sdes		.func = {						\
335174832Sdes			[PAM_SM_AUTHENTICATE] = _PAM_SM_AUTHENTICATE,	\
336174832Sdes			[PAM_SM_SETCRED] = _PAM_SM_SETCRED,		\
337174832Sdes			[PAM_SM_ACCT_MGMT] = _PAM_SM_ACCT_MGMT,		\
338174832Sdes			[PAM_SM_OPEN_SESSION] = _PAM_SM_OPEN_SESSION,	\
339174832Sdes			[PAM_SM_CLOSE_SESSION] = _PAM_SM_CLOSE_SESSION, \
340174832Sdes			[PAM_SM_CHAUTHTOK] = _PAM_SM_CHAUTHTOK		\
341174832Sdes		},							\
342174832Sdes	};								\
343174832Sdes	DATA_SET(_openpam_static_modules, _pam_module)
34491094Sdes#else
34591094Sdes/* normal case */
346174832Sdes# define PAM_EXTERN
347174832Sdes# define PAM_MODULE_ENTRY(name)
34891094Sdes#endif
34991094Sdes
35091094Sdes#ifdef __cplusplus
35191094Sdes}
35291094Sdes#endif
35391094Sdes
354174832Sdes#endif /* !SECURITY_OPENPAM_H_INCLUDED */
355