191094Sdes/*-
2115619Sdes * Copyright (c) 2002-2003 Networks Associates Technology, Inc.
3348980Sdes * Copyright (c) 2004-2015 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 *
35348980Sdes * $OpenPAM: openpam.h 938 2017-04-30 21:34:42Z 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));
160236109Sdes
161236109Sdeschar **
162236109Sdesopenpam_readlinev(FILE *_f,
163236109Sdes	int *_lineno,
164236109Sdes	int *_lenp)
165236109Sdes	OPENPAM_NONNULL((1));
166236109Sdes
167236109Sdeschar *
168236109Sdesopenpam_readword(FILE *_f,
169236109Sdes	int *_lineno,
170236109Sdes	size_t *_lenp)
171236109Sdes	OPENPAM_NONNULL((1));
172115619Sdes#endif
173115619Sdes
174236109Sdesint
175236109Sdesopenpam_straddch(char **_str,
176236109Sdes	size_t *_sizep,
177236109Sdes	size_t *_lenp,
178236109Sdes	int ch)
179236109Sdes	OPENPAM_NONNULL((1));
180236109Sdes
181115619Sdes/*
182236109Sdes * Enable / disable optional features
183236109Sdes */
184236109Sdesenum {
185236109Sdes	OPENPAM_RESTRICT_SERVICE_NAME,
186236109Sdes	OPENPAM_VERIFY_POLICY_FILE,
187236109Sdes	OPENPAM_RESTRICT_MODULE_NAME,
188236109Sdes	OPENPAM_VERIFY_MODULE_FILE,
189348980Sdes	OPENPAM_FALLBACK_TO_OTHER,
190236109Sdes	OPENPAM_NUM_FEATURES
191236109Sdes};
192236109Sdes
193236109Sdesint
194236109Sdesopenpam_set_feature(int _feature, int _onoff);
195236109Sdes
196236109Sdesint
197236109Sdesopenpam_get_feature(int _feature, int *_onoff);
198236109Sdes
199236109Sdes/*
20091094Sdes * Log levels
20191094Sdes */
20291094Sdesenum {
203236109Sdes	PAM_LOG_LIBDEBUG = -1,
20491094Sdes	PAM_LOG_DEBUG,
20591094Sdes	PAM_LOG_VERBOSE,
20691094Sdes	PAM_LOG_NOTICE,
20791094Sdes	PAM_LOG_ERROR
20891094Sdes};
20991094Sdes
21091094Sdes/*
21191094Sdes * Log to syslog
21291094Sdes */
21393982Sdesvoid
21493982Sdes_openpam_log(int _level,
21591094Sdes	const char *_func,
21691094Sdes	const char *_fmt,
217125647Sdes	...)
218174832Sdes	OPENPAM_FORMAT ((__printf__, 3, 4))
219174832Sdes	OPENPAM_NONNULL((3));
22091094Sdes
22197241Sdes#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
22297241Sdes#define openpam_log(lvl, ...) \
22397241Sdes	_openpam_log((lvl), __func__, __VA_ARGS__)
22497241Sdes#elif defined(__GNUC__) && (__GNUC__ >= 3)
22597241Sdes#define openpam_log(lvl, ...) \
22697241Sdes	_openpam_log((lvl), __func__, __VA_ARGS__)
22793982Sdes#elif defined(__GNUC__) && (__GNUC__ >= 2) && (__GNUC_MINOR__ >= 95)
22894562Sdes#define openpam_log(lvl, fmt...) \
22994878Sdes	_openpam_log((lvl), __func__, ##fmt)
23093982Sdes#elif defined(__GNUC__) && defined(__FUNCTION__)
23191094Sdes#define openpam_log(lvl, fmt...) \
23293982Sdes	_openpam_log((lvl), __FUNCTION__, ##fmt)
23391094Sdes#else
23493982Sdesvoid
23593982Sdesopenpam_log(int _level,
23693982Sdes	const char *_format,
237236109Sdes	...)
238236109Sdes	OPENPAM_FORMAT ((__printf__, 2, 3))
239174832Sdes	OPENPAM_NONNULL((2));
24091094Sdes#endif
24191094Sdes
24291094Sdes/*
24391094Sdes * Generic conversation function
24491094Sdes */
24591094Sdesstruct pam_message;
24691094Sdesstruct pam_response;
24791094Sdesint openpam_ttyconv(int _n,
24891094Sdes	const struct pam_message **_msg,
24991094Sdes	struct pam_response **_resp,
25091094Sdes	void *_data);
25191094Sdes
252117610Sdesextern int openpam_ttyconv_timeout;
253117610Sdes
25491094Sdes/*
25595908Sdes * Null conversation function
25695908Sdes */
25795908Sdesint openpam_nullconv(int _n,
25895908Sdes	const struct pam_message **_msg,
25995908Sdes	struct pam_response **_resp,
26095908Sdes	void *_data);
26195908Sdes
26295908Sdes/*
26391094Sdes * PAM primitives
26491094Sdes */
26591094Sdesenum {
26691094Sdes	PAM_SM_AUTHENTICATE,
26791094Sdes	PAM_SM_SETCRED,
26891094Sdes	PAM_SM_ACCT_MGMT,
26991094Sdes	PAM_SM_OPEN_SESSION,
27091094Sdes	PAM_SM_CLOSE_SESSION,
27191094Sdes	PAM_SM_CHAUTHTOK,
27291094Sdes	/* keep this last */
27391094Sdes	PAM_NUM_PRIMITIVES
27491094Sdes};
27591094Sdes
27691094Sdes/*
27791094Sdes * Dummy service module function
27891094Sdes */
27991094Sdes#define PAM_SM_DUMMY(type)						\
28091094SdesPAM_EXTERN int								\
28191094Sdespam_sm_##type(pam_handle_t *pamh, int flags,				\
28291094Sdes    int argc, const char *argv[])					\
28391094Sdes{									\
284174832Sdes									\
285174832Sdes	(void)pamh;							\
286174832Sdes	(void)flags;							\
287174832Sdes	(void)argc;							\
288174832Sdes	(void)argv;							\
28991094Sdes	return (PAM_IGNORE);						\
29091094Sdes}
29191094Sdes
29291094Sdes/*
29391094Sdes * PAM service module functions match this typedef
29491094Sdes */
29591094Sdesstruct pam_handle;
29691094Sdestypedef int (*pam_func_t)(struct pam_handle *, int, int, const char **);
29791094Sdes
29891094Sdes/*
29991094Sdes * A struct that describes a module.
30091094Sdes */
30191094Sdestypedef struct pam_module pam_module_t;
30291094Sdesstruct pam_module {
30391684Sdes	char		*path;
30491094Sdes	pam_func_t	 func[PAM_NUM_PRIMITIVES];
30591094Sdes	void		*dlh;
30691094Sdes};
30791094Sdes
30891094Sdes/*
30994532Sdes * Source-code compatibility with Linux-PAM modules
31094532Sdes */
31194532Sdes#if defined(PAM_SM_AUTH) || defined(PAM_SM_ACCOUNT) || \
31294532Sdes	defined(PAM_SM_SESSION) || defined(PAM_SM_PASSWORD)
313174832Sdes# define LINUX_PAM_MODULE
31494532Sdes#endif
315174832Sdes
31694532Sdes#if defined(LINUX_PAM_MODULE) && !defined(PAM_SM_AUTH)
317174832Sdes# define _PAM_SM_AUTHENTICATE	0
318174832Sdes# define _PAM_SM_SETCRED	0
31994532Sdes#else
320174832Sdes# undef PAM_SM_AUTH
321174832Sdes# define PAM_SM_AUTH
322174832Sdes# define _PAM_SM_AUTHENTICATE	pam_sm_authenticate
323174832Sdes# define _PAM_SM_SETCRED	pam_sm_setcred
32494532Sdes#endif
325174832Sdes
32694532Sdes#if defined(LINUX_PAM_MODULE) && !defined(PAM_SM_ACCOUNT)
327174832Sdes# define _PAM_SM_ACCT_MGMT	0
32894532Sdes#else
329174832Sdes# undef PAM_SM_ACCOUNT
330174832Sdes# define PAM_SM_ACCOUNT
331174832Sdes# define _PAM_SM_ACCT_MGMT	pam_sm_acct_mgmt
33294532Sdes#endif
333174832Sdes
33494532Sdes#if defined(LINUX_PAM_MODULE) && !defined(PAM_SM_SESSION)
335174832Sdes# define _PAM_SM_OPEN_SESSION	0
336174832Sdes# define _PAM_SM_CLOSE_SESSION	0
33794532Sdes#else
338174832Sdes# undef PAM_SM_SESSION
339174832Sdes# define PAM_SM_SESSION
340174832Sdes# define _PAM_SM_OPEN_SESSION	pam_sm_open_session
341174832Sdes# define _PAM_SM_CLOSE_SESSION	pam_sm_close_session
34294532Sdes#endif
343174832Sdes
34494532Sdes#if defined(LINUX_PAM_MODULE) && !defined(PAM_SM_PASSWORD)
345174832Sdes# define _PAM_SM_CHAUTHTOK	0
34694532Sdes#else
347174832Sdes# undef PAM_SM_PASSWORD
348174832Sdes# define PAM_SM_PASSWORD
349174832Sdes# define _PAM_SM_CHAUTHTOK	pam_sm_chauthtok
35094532Sdes#endif
35194532Sdes
35294532Sdes/*
35391094Sdes * Infrastructure for static modules using GCC linker sets.
35491094Sdes * You are not expected to understand this.
35591094Sdes */
356188720Sdes#if !defined(PAM_SOEXT)
357174832Sdes# define PAM_SOEXT ".so"
35891094Sdes#endif
359174832Sdes
360188720Sdes#if defined(OPENPAM_STATIC_MODULES)
361188720Sdes# if !defined(__GNUC__)
362188720Sdes#  error "Don't know how to build static modules on non-GNU compilers"
363188720Sdes# endif
36491094Sdes/* gcc, static linking */
365174832Sdes# include <sys/cdefs.h>
366174832Sdes# include <linker_set.h>
367174832Sdes# define PAM_EXTERN static
368174832Sdes# define PAM_MODULE_ENTRY(name)						\
369174832Sdes	static char _pam_name[] = name PAM_SOEXT;			\
370174832Sdes	static struct pam_module _pam_module = {			\
371174832Sdes		.path = _pam_name,					\
372174832Sdes		.func = {						\
373174832Sdes			[PAM_SM_AUTHENTICATE] = _PAM_SM_AUTHENTICATE,	\
374174832Sdes			[PAM_SM_SETCRED] = _PAM_SM_SETCRED,		\
375174832Sdes			[PAM_SM_ACCT_MGMT] = _PAM_SM_ACCT_MGMT,		\
376174832Sdes			[PAM_SM_OPEN_SESSION] = _PAM_SM_OPEN_SESSION,	\
377174832Sdes			[PAM_SM_CLOSE_SESSION] = _PAM_SM_CLOSE_SESSION, \
378174832Sdes			[PAM_SM_CHAUTHTOK] = _PAM_SM_CHAUTHTOK		\
379174832Sdes		},							\
380174832Sdes	};								\
381174832Sdes	DATA_SET(_openpam_static_modules, _pam_module)
38291094Sdes#else
38391094Sdes/* normal case */
384174832Sdes# define PAM_EXTERN
385174832Sdes# define PAM_MODULE_ENTRY(name)
38691094Sdes#endif
38791094Sdes
38891094Sdes#ifdef __cplusplus
38991094Sdes}
39091094Sdes#endif
39191094Sdes
392174832Sdes#endif /* !SECURITY_OPENPAM_H_INCLUDED */
393