openpam.h revision 188720
191094Sdes/*-
2115619Sdes * Copyright (c) 2002-2003 Networks Associates Technology, Inc.
3188720Sdes * Copyright (c) 2004-2008 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 *
35188720Sdes * $Id: openpam.h 418 2008-12-13 22:39:24Z 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
6294209Sdesvoid
6394209Sdesopenpam_free_data(pam_handle_t *_pamh,
6494209Sdes	void *_data,
6594209Sdes	int _status);
6694209Sdes
67141098Sdesvoid
68141098Sdesopenpam_free_envlist(char **_envlist);
69141098Sdes
7091100Sdesconst char *
7191100Sdesopenpam_get_option(pam_handle_t *_pamh,
7291100Sdes	const char *_option);
7391100Sdes
7491094Sdesint
75174832Sdesopenpam_restore_cred(pam_handle_t *_pamh)
76174832Sdes	OPENPAM_NONNULL((1));
7794209Sdes
7894209Sdesint
7991100Sdesopenpam_set_option(pam_handle_t *_pamh,
8091100Sdes	const char *_option,
8191100Sdes	const char *_value);
8291100Sdes
8391100Sdesint
84174832Sdespam_error(const pam_handle_t *_pamh,
8591094Sdes	const char *_fmt,
86174832Sdes	...)
87174832Sdes	OPENPAM_FORMAT ((__printf__, 2, 3))
88174832Sdes	OPENPAM_NONNULL((1,2));
8991094Sdes
9091094Sdesint
9191094Sdespam_get_authtok(pam_handle_t *_pamh,
9293982Sdes	int _item,
9391094Sdes	const char **_authtok,
94174832Sdes	const char *_prompt)
95174832Sdes	OPENPAM_NONNULL((1,3));
9691094Sdes
9791094Sdesint
98174832Sdespam_info(const pam_handle_t *_pamh,
9991094Sdes	const char *_fmt,
100174832Sdes	...)
101174832Sdes	OPENPAM_FORMAT ((__printf__, 2, 3))
102174832Sdes	OPENPAM_NONNULL((1,2));
10391094Sdes
10491094Sdesint
105174832Sdespam_prompt(const pam_handle_t *_pamh,
10691094Sdes	int _style,
10791094Sdes	char **_resp,
10891094Sdes	const char *_fmt,
109174832Sdes	...)
110174832Sdes	OPENPAM_FORMAT ((__printf__, 4, 5))
111174832Sdes	OPENPAM_NONNULL((1,4));
11291094Sdes
11391094Sdesint
11491094Sdespam_setenv(pam_handle_t *_pamh,
11591094Sdes	const char *_name,
11691094Sdes	const char *_value,
117174832Sdes	int _overwrite)
118174832Sdes	OPENPAM_NONNULL((1,2,3));
11991094Sdes
12091094Sdesint
121174832Sdespam_vinfo(const pam_handle_t *_pamh,
12291094Sdes	const char *_fmt,
123174832Sdes	va_list _ap)
124174832Sdes	OPENPAM_FORMAT ((__printf__, 2, 0))
125174832Sdes	OPENPAM_NONNULL((1,2));
12691094Sdes
12791094Sdesint
128174832Sdespam_verror(const pam_handle_t *_pamh,
12991094Sdes	const char *_fmt,
130174832Sdes	va_list _ap)
131174832Sdes	OPENPAM_FORMAT ((__printf__, 2, 0))
132174832Sdes	OPENPAM_NONNULL((1,2));
13391094Sdes
13491094Sdesint
135174832Sdespam_vprompt(const pam_handle_t *_pamh,
13691094Sdes	int _style,
13791094Sdes	char **_resp,
13891094Sdes	const char *_fmt,
139174832Sdes	va_list _ap)
140174832Sdes	OPENPAM_FORMAT ((__printf__, 4, 0))
141174832Sdes	OPENPAM_NONNULL((1,4));
14291094Sdes
14391094Sdes/*
144115619Sdes * Read cooked lines.
145117610Sdes * Checking for _IOFBF is a fairly reliable way to detect the presence
146117610Sdes * of <stdio.h>, as SUSv3 requires it to be defined there.
147115619Sdes */
148117610Sdes#ifdef _IOFBF
149115619Sdeschar *
150115619Sdesopenpam_readline(FILE *_f,
151115619Sdes	int *_lineno,
152174832Sdes	size_t *_lenp)
153174832Sdes	OPENPAM_NONNULL((1));
154115619Sdes#endif
155115619Sdes
156115619Sdes/*
15791094Sdes * Log levels
15891094Sdes */
15991094Sdesenum {
16091094Sdes	PAM_LOG_DEBUG,
16191094Sdes	PAM_LOG_VERBOSE,
16291094Sdes	PAM_LOG_NOTICE,
16391094Sdes	PAM_LOG_ERROR
16491094Sdes};
16591094Sdes
16691094Sdes/*
16791094Sdes * Log to syslog
16891094Sdes */
16993982Sdesvoid
17093982Sdes_openpam_log(int _level,
17191094Sdes	const char *_func,
17291094Sdes	const char *_fmt,
173125647Sdes	...)
174174832Sdes	OPENPAM_FORMAT ((__printf__, 3, 4))
175174832Sdes	OPENPAM_NONNULL((3));
17691094Sdes
17797241Sdes#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
17897241Sdes#define openpam_log(lvl, ...) \
17997241Sdes	_openpam_log((lvl), __func__, __VA_ARGS__)
18097241Sdes#elif defined(__GNUC__) && (__GNUC__ >= 3)
18197241Sdes#define openpam_log(lvl, ...) \
18297241Sdes	_openpam_log((lvl), __func__, __VA_ARGS__)
18393982Sdes#elif defined(__GNUC__) && (__GNUC__ >= 2) && (__GNUC_MINOR__ >= 95)
18494562Sdes#define openpam_log(lvl, fmt...) \
18594878Sdes	_openpam_log((lvl), __func__, ##fmt)
18693982Sdes#elif defined(__GNUC__) && defined(__FUNCTION__)
18791094Sdes#define openpam_log(lvl, fmt...) \
18893982Sdes	_openpam_log((lvl), __FUNCTION__, ##fmt)
18991094Sdes#else
19093982Sdesvoid
19193982Sdesopenpam_log(int _level,
19293982Sdes	const char *_format,
193174832Sdes 	...)
194174832Sdes 	OPENPAM_FORMAT ((__printf__, 2, 3))
195174832Sdes	OPENPAM_NONNULL((2));
19691094Sdes#endif
19791094Sdes
19891094Sdes/*
19991094Sdes * Generic conversation function
20091094Sdes */
20191094Sdesstruct pam_message;
20291094Sdesstruct pam_response;
20391094Sdesint openpam_ttyconv(int _n,
20491094Sdes	const struct pam_message **_msg,
20591094Sdes	struct pam_response **_resp,
20691094Sdes	void *_data);
20791094Sdes
208117610Sdesextern int openpam_ttyconv_timeout;
209117610Sdes
21091094Sdes/*
21195908Sdes * Null conversation function
21295908Sdes */
21395908Sdesint openpam_nullconv(int _n,
21495908Sdes	const struct pam_message **_msg,
21595908Sdes	struct pam_response **_resp,
21695908Sdes	void *_data);
21795908Sdes
21895908Sdes/*
21991094Sdes * PAM primitives
22091094Sdes */
22191094Sdesenum {
22291094Sdes	PAM_SM_AUTHENTICATE,
22391094Sdes	PAM_SM_SETCRED,
22491094Sdes	PAM_SM_ACCT_MGMT,
22591094Sdes	PAM_SM_OPEN_SESSION,
22691094Sdes	PAM_SM_CLOSE_SESSION,
22791094Sdes	PAM_SM_CHAUTHTOK,
22891094Sdes	/* keep this last */
22991094Sdes	PAM_NUM_PRIMITIVES
23091094Sdes};
23191094Sdes
23291094Sdes/*
23391094Sdes * Dummy service module function
23491094Sdes */
23591094Sdes#define PAM_SM_DUMMY(type)						\
23691094SdesPAM_EXTERN int								\
23791094Sdespam_sm_##type(pam_handle_t *pamh, int flags,				\
23891094Sdes    int argc, const char *argv[])					\
23991094Sdes{									\
240174832Sdes									\
241174832Sdes	(void)pamh;							\
242174832Sdes	(void)flags;							\
243174832Sdes	(void)argc;							\
244174832Sdes	(void)argv;							\
24591094Sdes	return (PAM_IGNORE);						\
24691094Sdes}
24791094Sdes
24891094Sdes/*
24991094Sdes * PAM service module functions match this typedef
25091094Sdes */
25191094Sdesstruct pam_handle;
25291094Sdestypedef int (*pam_func_t)(struct pam_handle *, int, int, const char **);
25391094Sdes
25491094Sdes/*
25591094Sdes * A struct that describes a module.
25691094Sdes */
25791094Sdestypedef struct pam_module pam_module_t;
25891094Sdesstruct pam_module {
25991684Sdes	char		*path;
26091094Sdes	pam_func_t	 func[PAM_NUM_PRIMITIVES];
26191094Sdes	void		*dlh;
26291094Sdes};
26391094Sdes
26491094Sdes/*
26594532Sdes * Source-code compatibility with Linux-PAM modules
26694532Sdes */
26794532Sdes#if defined(PAM_SM_AUTH) || defined(PAM_SM_ACCOUNT) || \
26894532Sdes	defined(PAM_SM_SESSION) || defined(PAM_SM_PASSWORD)
269174832Sdes# define LINUX_PAM_MODULE
27094532Sdes#endif
271174832Sdes
27294532Sdes#if defined(LINUX_PAM_MODULE) && !defined(PAM_SM_AUTH)
273174832Sdes# define _PAM_SM_AUTHENTICATE	0
274174832Sdes# define _PAM_SM_SETCRED	0
27594532Sdes#else
276174832Sdes# undef PAM_SM_AUTH
277174832Sdes# define PAM_SM_AUTH
278174832Sdes# define _PAM_SM_AUTHENTICATE	pam_sm_authenticate
279174832Sdes# define _PAM_SM_SETCRED	pam_sm_setcred
28094532Sdes#endif
281174832Sdes
28294532Sdes#if defined(LINUX_PAM_MODULE) && !defined(PAM_SM_ACCOUNT)
283174832Sdes# define _PAM_SM_ACCT_MGMT	0
28494532Sdes#else
285174832Sdes# undef PAM_SM_ACCOUNT
286174832Sdes# define PAM_SM_ACCOUNT
287174832Sdes# define _PAM_SM_ACCT_MGMT	pam_sm_acct_mgmt
28894532Sdes#endif
289174832Sdes
29094532Sdes#if defined(LINUX_PAM_MODULE) && !defined(PAM_SM_SESSION)
291174832Sdes# define _PAM_SM_OPEN_SESSION	0
292174832Sdes# define _PAM_SM_CLOSE_SESSION	0
29394532Sdes#else
294174832Sdes# undef PAM_SM_SESSION
295174832Sdes# define PAM_SM_SESSION
296174832Sdes# define _PAM_SM_OPEN_SESSION	pam_sm_open_session
297174832Sdes# define _PAM_SM_CLOSE_SESSION	pam_sm_close_session
29894532Sdes#endif
299174832Sdes
30094532Sdes#if defined(LINUX_PAM_MODULE) && !defined(PAM_SM_PASSWORD)
301174832Sdes# define _PAM_SM_CHAUTHTOK	0
30294532Sdes#else
303174832Sdes# undef PAM_SM_PASSWORD
304174832Sdes# define PAM_SM_PASSWORD
305174832Sdes# define _PAM_SM_CHAUTHTOK	pam_sm_chauthtok
30694532Sdes#endif
30794532Sdes
30894532Sdes/*
30991094Sdes * Infrastructure for static modules using GCC linker sets.
31091094Sdes * You are not expected to understand this.
31191094Sdes */
312188720Sdes#if !defined(PAM_SOEXT)
313174832Sdes# define PAM_SOEXT ".so"
31491094Sdes#endif
315174832Sdes
316188720Sdes#if defined(OPENPAM_STATIC_MODULES)
317188720Sdes# if !defined(__GNUC__)
318188720Sdes#  error "Don't know how to build static modules on non-GNU compilers"
319188720Sdes# endif
32091094Sdes/* gcc, static linking */
321174832Sdes# include <sys/cdefs.h>
322174832Sdes# include <linker_set.h>
323174832Sdes# define PAM_EXTERN static
324174832Sdes# define PAM_MODULE_ENTRY(name)						\
325174832Sdes	static char _pam_name[] = name PAM_SOEXT;			\
326174832Sdes	static struct pam_module _pam_module = {			\
327174832Sdes		.path = _pam_name,					\
328174832Sdes		.func = {						\
329174832Sdes			[PAM_SM_AUTHENTICATE] = _PAM_SM_AUTHENTICATE,	\
330174832Sdes			[PAM_SM_SETCRED] = _PAM_SM_SETCRED,		\
331174832Sdes			[PAM_SM_ACCT_MGMT] = _PAM_SM_ACCT_MGMT,		\
332174832Sdes			[PAM_SM_OPEN_SESSION] = _PAM_SM_OPEN_SESSION,	\
333174832Sdes			[PAM_SM_CLOSE_SESSION] = _PAM_SM_CLOSE_SESSION, \
334174832Sdes			[PAM_SM_CHAUTHTOK] = _PAM_SM_CHAUTHTOK		\
335174832Sdes		},							\
336174832Sdes	};								\
337174832Sdes	DATA_SET(_openpam_static_modules, _pam_module)
33891094Sdes#else
33991094Sdes/* normal case */
340174832Sdes# define PAM_EXTERN
341174832Sdes# define PAM_MODULE_ENTRY(name)
34291094Sdes#endif
34391094Sdes
34491094Sdes#ifdef __cplusplus
34591094Sdes}
34691094Sdes#endif
34791094Sdes
348174832Sdes#endif /* !SECURITY_OPENPAM_H_INCLUDED */
349