Home | History | Annotate | Line # | Download | only in security
      1 /*	$NetBSD: openpam.h,v 1.12 2023/06/30 21:46:20 christos Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 2002-2003 Networks Associates Technology, Inc.
      5  * Copyright (c) 2004-2015 Dag-Erling Smrgrav
      6  * All rights reserved.
      7  *
      8  * This software was developed for the FreeBSD Project by ThinkSec AS and
      9  * Network Associates Laboratories, the Security Research Division of
     10  * Network Associates, Inc.  under DARPA/SPAWAR contract N66001-01-C-8035
     11  * ("CBOSS"), as part of the DARPA CHATS research program.
     12  *
     13  * Redistribution and use in source and binary forms, with or without
     14  * modification, are permitted provided that the following conditions
     15  * are met:
     16  * 1. Redistributions of source code must retain the above copyright
     17  *    notice, this list of conditions and the following disclaimer.
     18  * 2. Redistributions in binary form must reproduce the above copyright
     19  *    notice, this list of conditions and the following disclaimer in the
     20  *    documentation and/or other materials provided with the distribution.
     21  * 3. The name of the author may not be used to endorse or promote
     22  *    products derived from this software without specific prior written
     23  *    permission.
     24  *
     25  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     27  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     28  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     29  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     30  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     31  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     32  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     34  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     35  * SUCH DAMAGE.
     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
     49 extern "C" {
     50 #endif
     51 
     52 struct passwd;
     53 
     54 /*
     55  * API extensions
     56  */
     57 int
     58 openpam_borrow_cred(pam_handle_t *_pamh,
     59 	const struct passwd *_pwd)
     60 	OPENPAM_NONNULL((1,2));
     61 
     62 int
     63 openpam_subst(const pam_handle_t *_pamh,
     64 	char *_buf,
     65 	size_t *_bufsize,
     66 	const char *_template);
     67 
     68 void
     69 openpam_free_data(pam_handle_t *_pamh,
     70 	void *_data,
     71 	int _status);
     72 
     73 void
     74 openpam_free_envlist(char **_envlist);
     75 
     76 const char *
     77 openpam_get_option(pam_handle_t *_pamh,
     78 	const char *_option);
     79 
     80 int
     81 openpam_restore_cred(pam_handle_t *_pamh)
     82 	OPENPAM_NONNULL((1));
     83 
     84 int
     85 openpam_set_option(pam_handle_t *_pamh,
     86 	const char *_option,
     87 	const char *_value);
     88 
     89 int
     90 pam_error(const pam_handle_t *_pamh,
     91 	const char *_fmt,
     92 	...)
     93 	OPENPAM_FORMAT ((__syslog__, 2, 3))
     94 	OPENPAM_NONNULL((1,2));
     95 
     96 int
     97 pam_get_authtok(pam_handle_t *_pamh,
     98 	int _item,
     99 	const char **_authtok,
    100 	const char *_prompt)
    101 	OPENPAM_NONNULL((1,3));
    102 
    103 int
    104 pam_info(const pam_handle_t *_pamh,
    105 	const char *_fmt,
    106 	...)
    107 	OPENPAM_FORMAT ((__syslog__, 2, 3))
    108 	OPENPAM_NONNULL((1,2));
    109 
    110 int
    111 pam_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 
    119 int
    120 pam_setenv(pam_handle_t *_pamh,
    121 	const char *_name,
    122 	const char *_value,
    123 	int _overwrite)
    124 	OPENPAM_NONNULL((1,2,3));
    125 
    126 int
    127 pam_vinfo(const pam_handle_t *_pamh,
    128 	const char *_fmt,
    129 	va_list _ap)
    130 	OPENPAM_FORMAT ((__syslog__, 2, 0))
    131 	OPENPAM_NONNULL((1,2));
    132 
    133 int
    134 pam_verror(const pam_handle_t *_pamh,
    135 	const char *_fmt,
    136 	va_list _ap)
    137 	OPENPAM_FORMAT ((__syslog__, 2, 0))
    138 	OPENPAM_NONNULL((1,2));
    139 
    140 int
    141 pam_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
    155 char *
    156 openpam_readline(FILE *_f,
    157 	int *_lineno,
    158 	size_t *_lenp)
    159 	OPENPAM_NONNULL((1));
    160 
    161 char **
    162 openpam_readlinev(FILE *_f,
    163 	int *_lineno,
    164 	int *_lenp)
    165 	OPENPAM_NONNULL((1));
    166 
    167 char *
    168 openpam_readword(FILE *_f,
    169 	int *_lineno,
    170 	size_t *_lenp)
    171 	OPENPAM_NONNULL((1));
    172 #endif
    173 
    174 int
    175 openpam_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  */
    184 enum {
    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 
    193 int
    194 openpam_set_feature(int _feature, int _onoff);
    195 
    196 int
    197 openpam_get_feature(int _feature, int *_onoff);
    198 
    199 /*
    200  * Log levels
    201  */
    202 enum openpam_log_primitives {
    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  */
    213 void
    214 _openpam_log(int _level,
    215 	const char *_func,
    216 	const char *_fmt,
    217 	...)
    218 	OPENPAM_FORMAT ((__syslog__, 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(__func__)
    231 #define openpam_log(lvl, fmt...) \
    232 	_openpam_log((lvl), __func__, ##fmt)
    233 #else
    234 void
    235 openpam_log(int _level,
    236 	const char *_format,
    237 	...)
    238 	OPENPAM_FORMAT ((__syslog__, 2, 3))
    239 	OPENPAM_NONNULL((2));
    240 #endif
    241 
    242 /*
    243  * Generic conversation function
    244  */
    245 struct pam_message;
    246 struct pam_response;
    247 int openpam_ttyconv(int _n,
    248 	const struct pam_message **_msg,
    249 	struct pam_response **_resp,
    250 	void *_data);
    251 
    252 extern int openpam_ttyconv_timeout;
    253 
    254 /*
    255  * Null conversation function
    256  */
    257 int openpam_nullconv(int _n,
    258 	const struct pam_message **_msg,
    259 	struct pam_response **_resp,
    260 	void *_data);
    261 
    262 /*
    263  * PAM primitives
    264  */
    265 enum openpam_sm_primitives {
    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)						\
    280 PAM_EXTERN int								\
    281 pam_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  */
    295 struct pam_handle;
    296 typedef int (*pam_func_t)(struct pam_handle *, int, int, const char **);
    297 
    298 /*
    299  * A struct that describes a module.
    300  */
    301 typedef struct pam_module pam_module_t;
    302 struct 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(__GNUC__) || defined(__PCC__)) && defined(OPENPAM_STATIC_MODULES)
    361 # include <sys/cdefs.h>
    362 # ifdef __FreeBSD__
    363 #  include <linker_set.h>
    364 # endif
    365 # ifdef __NetBSD__
    366 #  define DATA_SET(a, b) __link_set_add_data(a, b)
    367 #  define SET_DECLARE(a, b) __link_set_decl(a, b)
    368 #  define SET_FOREACH(a, b) __link_set_foreach(a, b)
    369 # endif
    370 # define PAM_EXTERN static
    371 # define PAM_MODULE_ENTRY(name)						\
    372 	static char _pam_name[] = name PAM_SOEXT;			\
    373 	static struct pam_module _pam_module = {			\
    374 		.path = _pam_name,					\
    375 		.func = {						\
    376 			[PAM_SM_AUTHENTICATE] = _PAM_SM_AUTHENTICATE,	\
    377 			[PAM_SM_SETCRED] = _PAM_SM_SETCRED,		\
    378 			[PAM_SM_ACCT_MGMT] = _PAM_SM_ACCT_MGMT,		\
    379 			[PAM_SM_OPEN_SESSION] = _PAM_SM_OPEN_SESSION,	\
    380 			[PAM_SM_CLOSE_SESSION] = _PAM_SM_CLOSE_SESSION, \
    381 			[PAM_SM_CHAUTHTOK] = _PAM_SM_CHAUTHTOK		\
    382 		},							\
    383 	};								\
    384 	DATA_SET(openpam_static_modules, _pam_module)
    385 #else
    386 /* normal case */
    387 # define PAM_EXTERN
    388 # define PAM_MODULE_ENTRY(name)
    389 #endif
    390 
    391 #ifdef __cplusplus
    392 }
    393 #endif
    394 
    395 #endif /* !SECURITY_OPENPAM_H_INCLUDED */
    396