diff options
Diffstat (limited to 'libpam')
-rw-r--r-- | libpam/Makefile.am | 2 | ||||
-rw-r--r-- | libpam/Makefile.in | 14 | ||||
-rw-r--r-- | libpam/include/pam_cc_compat.h | 20 | ||||
-rw-r--r-- | libpam/include/pam_inline.h | 64 | ||||
-rw-r--r-- | libpam/include/security/_pam_macros.h | 28 | ||||
-rw-r--r-- | libpam/include/security/_pam_types.h | 6 | ||||
-rw-r--r-- | libpam/include/security/pam_modutil.h | 11 | ||||
-rw-r--r-- | libpam/pam.pc.in | 2 | ||||
-rw-r--r-- | libpam/pam_dispatch.c | 17 | ||||
-rw-r--r-- | libpam/pam_dynamic.c | 84 | ||||
-rw-r--r-- | libpam/pam_end.c | 31 | ||||
-rw-r--r-- | libpam/pam_env.c | 9 | ||||
-rw-r--r-- | libpam/pam_get_authtok.c | 17 | ||||
-rw-r--r-- | libpam/pam_handlers.c | 92 | ||||
-rw-r--r-- | libpam/pam_item.c | 20 | ||||
-rw-r--r-- | libpam/pam_modutil_getlogin.c | 50 | ||||
-rw-r--r-- | libpam/pam_modutil_priv.c | 40 | ||||
-rw-r--r-- | libpam/pam_vprompt.c | 6 |
18 files changed, 285 insertions, 228 deletions
diff --git a/libpam/Makefile.am b/libpam/Makefile.am index 55222afc..389d5d02 100644 --- a/libpam/Makefile.am +++ b/libpam/Makefile.am @@ -21,7 +21,7 @@ noinst_HEADERS = pam_prelude.h pam_private.h pam_tokens.h \ include/pam_inline.h include/test_assert.h libpam_la_LDFLAGS = -no-undefined -version-info 85:1:85 -libpam_la_LIBADD = @LIBAUDIT@ $(LIBPRELUDE_LIBS) $(ECONF_LIBS) @LIBDL@ +libpam_la_LIBADD = @LIBAUDIT@ $(LIBPRELUDE_LIBS) $(ECONF_LIBS) @LIBDL@ @LTLIBINTL@ if HAVE_VERSIONING libpam_la_LDFLAGS += -Wl,--version-script=$(srcdir)/libpam.map diff --git a/libpam/Makefile.in b/libpam/Makefile.in index 0c2333c0..597c8dcd 100644 --- a/libpam/Makefile.in +++ b/libpam/Makefile.in @@ -286,6 +286,7 @@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ +DOCBOOK_RNG = @DOCBOOK_RNG@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ @@ -298,11 +299,13 @@ EXEEXT = @EXEEXT@ EXE_CFLAGS = @EXE_CFLAGS@ EXE_LDFLAGS = @EXE_LDFLAGS@ FGREP = @FGREP@ +FILECMD = @FILECMD@ FO2PDF = @FO2PDF@ GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ GMSGFMT = @GMSGFMT@ GMSGFMT_015 = @GMSGFMT_015@ GREP = @GREP@ +HTML_STYLESHEET = @HTML_STYLESHEET@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ @@ -334,12 +337,14 @@ LIBSELINUX = @LIBSELINUX@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ +LOGIND_CFLAGS = @LOGIND_CFLAGS@ LTLIBICONV = @LTLIBICONV@ LTLIBINTL = @LTLIBINTL@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ +MAN_STYLESHEET = @MAN_STYLESHEET@ MKDIR_P = @MKDIR_P@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ @@ -362,6 +367,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PDF_STYLESHEET = @PDF_STYLESHEET@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ @@ -372,12 +378,16 @@ SECUREDIR = @SECUREDIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ -STRINGPARAM_HMAC = @STRINGPARAM_HMAC@ +STRINGPARAM_PROFILECONDITIONS = @STRINGPARAM_PROFILECONDITIONS@ STRINGPARAM_VENDORDIR = @STRINGPARAM_VENDORDIR@ STRIP = @STRIP@ +SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@ +SYSTEMD_LIBS = @SYSTEMD_LIBS@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ +TXT_STYLESHEET = @TXT_STYLESHEET@ USE_NLS = @USE_NLS@ +VENDOR_SCONFIGDIR = @VENDOR_SCONFIGDIR@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ XGETTEXT = @XGETTEXT@ @@ -461,7 +471,7 @@ noinst_HEADERS = pam_prelude.h pam_private.h pam_tokens.h \ libpam_la_LDFLAGS = -no-undefined -version-info 85:1:85 \ $(am__append_1) -libpam_la_LIBADD = @LIBAUDIT@ $(LIBPRELUDE_LIBS) $(ECONF_LIBS) @LIBDL@ +libpam_la_LIBADD = @LIBAUDIT@ $(LIBPRELUDE_LIBS) $(ECONF_LIBS) @LIBDL@ @LTLIBINTL@ lib_LTLIBRARIES = libpam.la libpam_la_SOURCES = pam_account.c pam_auth.c pam_data.c pam_delay.c \ pam_dispatch.c pam_end.c pam_env.c pam_get_authtok.c \ diff --git a/libpam/include/pam_cc_compat.h b/libpam/include/pam_cc_compat.h index 69190368..0a6e32d5 100644 --- a/libpam/include/pam_cc_compat.h +++ b/libpam/include/pam_cc_compat.h @@ -32,6 +32,11 @@ _Pragma("GCC diagnostic ignored \"-Wcast-align\"") # define DIAG_POP_IGNORE_CAST_ALIGN \ _Pragma("GCC diagnostic pop") +# define DIAG_PUSH_IGNORE_FORMAT_NONLITERAL \ + _Pragma("GCC diagnostic push"); \ + _Pragma("GCC diagnostic ignored \"-Wformat-nonliteral\"") +# define DIAG_POP_IGNORE_FORMAT_NONLITERAL \ + _Pragma("GCC diagnostic pop") #elif PAM_CLANG_PREREQ(2, 6) # define DIAG_PUSH_IGNORE_CAST_QUAL \ _Pragma("clang diagnostic push"); \ @@ -43,11 +48,18 @@ _Pragma("clang diagnostic ignored \"-Wcast-align\"") # define DIAG_POP_IGNORE_CAST_ALIGN \ _Pragma("clang diagnostic pop") +# define DIAG_PUSH_IGNORE_FORMAT_NONLITERAL \ + _Pragma("clang diagnostic push"); \ + _Pragma("clang diagnostic ignored \"-Wformat-nonliteral\"") +# define DIAG_POP_IGNORE_FORMAT_NONLITERAL \ + _Pragma("clang diagnostic pop") #else -# define DIAG_PUSH_IGNORE_CAST_QUAL /* empty */ -# define DIAG_POP_IGNORE_CAST_QUAL /* empty */ -# define DIAG_PUSH_IGNORE_CAST_ALIGN /* empty */ -# define DIAG_POP_IGNORE_CAST_ALIGN /* empty */ +# define DIAG_PUSH_IGNORE_CAST_QUAL /* empty */ +# define DIAG_POP_IGNORE_CAST_QUAL /* empty */ +# define DIAG_PUSH_IGNORE_CAST_ALIGN /* empty */ +# define DIAG_POP_IGNORE_CAST_ALIGN /* empty */ +# define DIAG_PUSH_IGNORE_FORMAT_NONLITERAL /* empty */ +# define DIAG_POP_IGNORE_FORMAT_NONLITERAL /* empty */ #endif /* diff --git a/libpam/include/pam_inline.h b/libpam/include/pam_inline.h index ec2f3bf0..7721c0b7 100644 --- a/libpam/include/pam_inline.h +++ b/libpam/include/pam_inline.h @@ -9,6 +9,7 @@ #define PAM_INLINE_H #include "pam_cc_compat.h" +#include <stdlib.h> #include <string.h> #include <unistd.h> #include <errno.h> @@ -33,6 +34,12 @@ * 0, otherwise. */ #define PAM_MUST_BE_ARRAY(a_) PAM_FAIL_BUILD_ON_ZERO(!PAM_IS_NOT_ARRAY(a_)) +/* + * Evaluates to + * - a syntax error if the argument is an array, + * 0, otherwise. + */ +#define PAM_MUST_NOT_BE_ARRAY(a_) PAM_FAIL_BUILD_ON_ZERO(PAM_IS_NOT_ARRAY(a_)) /* Evaluates to the number of elements in the specified array. */ #define PAM_ARRAY_SIZE(a_) (sizeof(a_) / sizeof((a_)[0]) + PAM_MUST_BE_ARRAY(a_)) @@ -66,6 +73,59 @@ pam_str_skip_icase_prefix_len(const char *str, const char *prefix, size_t prefix #define pam_str_skip_icase_prefix(str_, prefix_) \ pam_str_skip_icase_prefix_len((str_), (prefix_), sizeof(prefix_) - 1 + PAM_MUST_BE_ARRAY(prefix_)) + +/* + * Macros to securely erase memory + */ + +#ifdef HAVE_MEMSET_EXPLICIT +static inline void pam_overwrite_n(void *ptr, size_t len) +{ + if (ptr) + memset_explicit(ptr, len); +} +#elif defined HAVE_EXPLICIT_BZERO +static inline void pam_overwrite_n(void *ptr, size_t len) +{ + if (ptr) + explicit_bzero(ptr, len); +} +#else +static inline void pam_overwrite_n(void *ptr, size_t len) +{ + if (ptr) { + ptr = memset(ptr, '\0', len); + __asm__ __volatile__ ("" : : "r"(ptr) : "memory"); + } +} +#endif + +#define pam_overwrite_string(x) \ +do { \ + char *xx__ = (x) + PAM_MUST_NOT_BE_ARRAY(x); \ + if (xx__) \ + pam_overwrite_n(xx__, strlen(xx__)); \ +} while(0) + +#define pam_overwrite_array(x) pam_overwrite_n(x, sizeof(x) + PAM_MUST_BE_ARRAY(x)) + +#define pam_overwrite_object(x) pam_overwrite_n(x, sizeof(*(x)) + PAM_MUST_NOT_BE_ARRAY(x)) + +static inline void +pam_drop_response(struct pam_response *reply, int replies) +{ + int reply_i; + + for (reply_i = 0; reply_i < replies; ++reply_i) { + if (reply[reply_i].resp) { + pam_overwrite_string(reply[reply_i].resp); + free(reply[reply_i].resp); + } + } + free(reply); +} + + static inline int pam_read_passwords(int fd, int npass, char **passwords) { @@ -101,7 +161,7 @@ pam_read_passwords(int fd, int npass, char **passwords) if (npass > 0) { memcpy(passwords[i], pptr, rbytes); } - memset(pptr, '\0', rbytes); + pam_overwrite_n(pptr, rbytes); } } offset += rbytes; @@ -109,7 +169,7 @@ pam_read_passwords(int fd, int npass, char **passwords) /* clear up */ if (offset > 0 && npass > 0) { - memset(passwords[i], '\0', offset); + pam_overwrite_n(passwords[i], offset); } return i; diff --git a/libpam/include/security/_pam_macros.h b/libpam/include/security/_pam_macros.h index e891e226..b5129d2a 100644 --- a/libpam/include/security/_pam_macros.h +++ b/libpam/include/security/_pam_macros.h @@ -7,6 +7,8 @@ * Organized by Cristian Gafton <gafton@redhat.com> */ +#include "_pam_types.h" + /* a 'safe' version of strdup */ #include <stdlib.h> @@ -14,20 +16,22 @@ #define x_strdup(s) ( (s) ? strdup(s):NULL ) -/* Good policy to strike out passwords with some characters not just - free the memory */ +/* + * WARNING: Do NOT use these overwrite macros, as they do not reliable + * override the memory. + */ -#define _pam_overwrite(x) \ -do { \ - register char *__xx__; \ - if ((__xx__=(x))) \ - while (*__xx__) \ - *__xx__++ = '\0'; \ +#define _pam_overwrite(x) \ +do { \ + PAM_DEPRECATED register char *__xx__; \ + if ((__xx__=(x))) \ + while (*__xx__) \ + *__xx__++ = '\0'; \ } while (0) #define _pam_overwrite_n(x,n) \ do { \ - register char *__xx__; \ + PAM_DEPRECATED register char *__xx__; \ register unsigned int __i__ = 0; \ if ((__xx__=(x))) \ for (;__i__<n; __i__++) \ @@ -46,9 +50,13 @@ do { \ } \ } while (0) +/* + * WARNING: Do NOT use this macro, as it does not reliable override the memory. + */ + #define _pam_drop_reply(/* struct pam_response * */ reply, /* int */ replies) \ do { \ - int reply_i; \ + PAM_DEPRECATED int reply_i; \ \ for (reply_i=0; reply_i<replies; ++reply_i) { \ if (reply[reply_i].resp) { \ diff --git a/libpam/include/security/_pam_types.h b/libpam/include/security/_pam_types.h index 2abb7ee5..4d6909e8 100644 --- a/libpam/include/security/_pam_types.h +++ b/libpam/include/security/_pam_types.h @@ -160,6 +160,12 @@ typedef struct pam_handle pam_handle_t; # define PAM_FORMAT(params) #endif +#if PAM_GNUC_PREREQ(3,1) +# define PAM_DEPRECATED __attribute__((__deprecated__)) +#else +# define PAM_DEPRECATED +#endif + #if PAM_GNUC_PREREQ(3,3) && !defined(LIBPAM_COMPILE) # define PAM_NONNULL(params) __attribute__((__nonnull__ params)) #else diff --git a/libpam/include/security/pam_modutil.h b/libpam/include/security/pam_modutil.h index 33f87b90..c2578323 100644 --- a/libpam/include/security/pam_modutil.h +++ b/libpam/include/security/pam_modutil.h @@ -147,7 +147,16 @@ pam_modutil_sanitize_helper_fds(pam_handle_t *pamh, enum pam_modutil_redirect_fd redirect_stdout, enum pam_modutil_redirect_fd redirect_stderr); -/* lookup a value for key in login.defs file or similar key value format */ +/************************************************** + * @brief Lookup a value for the key in the file (i.e. login.defs or a similar + * key-value format file). + * + * @param[in] pamh The pam handle structure + * @param[in] file_name Configuration file name + * @param[in] key Lookup key + * + * @return value, or NULL if key was not found. + **************************************************/ extern char * PAM_NONNULL((1,2,3)) pam_modutil_search_key(pam_handle_t *pamh, const char *file_name, diff --git a/libpam/pam.pc.in b/libpam/pam.pc.in index a7cf852d..c3fafe4b 100644 --- a/libpam/pam.pc.in +++ b/libpam/pam.pc.in @@ -1,3 +1,5 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ diff --git a/libpam/pam_dispatch.c b/libpam/pam_dispatch.c index 974104a2..15cad01f 100644 --- a/libpam/pam_dispatch.c +++ b/libpam/pam_dispatch.c @@ -260,22 +260,7 @@ static int _pam_dispatch_aux(pam_handle_t *pamh, int flags, struct handler *h, if ( _PAM_ACTION_IS_JUMP(action) ) { /* If we are evaluating a cached chain, we treat this - module as required (aka _PAM_ACTION_OK) as well as - executing the jump. */ - - if (use_cached_chain) { - if (impression == _PAM_UNDEF - || (impression == _PAM_POSITIVE - && status == PAM_SUCCESS) ) { - if ( retval != PAM_IGNORE || cached_retval == retval ) { - if ( impression == _PAM_UNDEF && retval == PAM_SUCCESS ) { - h->grantor = 1; - } - impression = _PAM_POSITIVE; - status = retval; - } - } - } + module as ignored as well as executing the jump. */ /* this means that we need to skip #action stacked modules */ while (h->next != NULL && h->next->stack_level >= stack_level && action > 0) { diff --git a/libpam/pam_dynamic.c b/libpam/pam_dynamic.c index c063083f..81f49b43 100644 --- a/libpam/pam_dynamic.c +++ b/libpam/pam_dynamic.c @@ -32,107 +32,25 @@ */ #include "pam_private.h" - -#ifdef PAM_SHL -# include <dl.h> -#elif defined(PAM_DYLD) -# include <mach-o/dyld.h> -#else /* PAM_SHL */ -# include <dlfcn.h> -#endif /* PAM_SHL */ - -#ifndef SHLIB_SYM_PREFIX -#define SHLIB_SYM_PREFIX "_" -#endif +#include <dlfcn.h> void *_pam_dlopen(const char *mod_path) { -#ifdef PAM_SHL - return shl_load(mod_path, BIND_IMMEDIATE, 0L); -#elif defined(PAM_DYLD) - NSObjectFileImage ofile; - void *ret = NULL; - - if (NSCreateObjectFileImageFromFile(mod_path, &ofile) != - NSObjectFileImageSuccess ) - return NULL; - - ret = NSLinkModule(ofile, mod_path, NSLINKMODULE_OPTION_PRIVATE | NSLINKMODULE_OPTION_BINDNOW); - NSDestroyObjectFileImage(ofile); - - return ret; -#else return dlopen(mod_path, RTLD_NOW); -#endif } servicefn _pam_dlsym(void *handle, const char *symbol) { -#ifdef PAM_SHL - char *_symbol = NULL; - servicefn ret; - - if( symbol == NULL ) - return NULL; - - if( shl_findsym(&handle, symbol, (short) TYPE_PROCEDURE, &ret ){ - _symbol = malloc( strlen(symbol) + sizeof(SHLIB_SYM_PREFIX) + 1 ); - if( _symbol == NULL ) - return NULL; - strcpy(_symbol, SHLIB_SYM_PREFIX); - strcat(_symbol, symbol); - if( shl_findsym(&handle, _symbol, - (short) TYPE_PROCEDURE, &ret ){ - free(_symbol); - return NULL; - } - free(_symbol); - } - - return ret; - -#elif defined(PAM_DYLD) - NSSymbol nsSymbol; - char *_symbol; - - if( symbol == NULL ) - return NULL; - _symbol = malloc( strlen(symbol) + 2 ); - if( _symbol == NULL ) - return NULL; - strcpy(_symbol, SHLIB_SYM_PREFIX); - strcat(_symbol, symbol); - - nsSymbol = NSLookupSymbolInModule(handle, _symbol); - if( nsSymbol == NULL ) - return NULL; - free(_symbol); - - return (servicefn)NSAddressOfSymbol(nsSymbol); -#else return (servicefn) dlsym(handle, symbol); -#endif } void _pam_dlclose(void *handle) { -#ifdef PAM_SHL - shl_unload(handle); -#elif defined(PAM_DYLD) - NSUnLinkModule((NSModule)handle, NSUNLINKMODULE_OPTION_NONE); -#else dlclose(handle); -#endif - - return; } const char * _pam_dlerror (void) { -#if defined(PAM_SHL) || defined(PAM_DYLD) - return "unknown"; -#else return dlerror (); -#endif } diff --git a/libpam/pam_end.c b/libpam/pam_end.c index 406b1478..9179a915 100644 --- a/libpam/pam_end.c +++ b/libpam/pam_end.c @@ -5,6 +5,7 @@ */ #include "pam_private.h" +#include "pam_inline.h" #include <stdlib.h> @@ -41,34 +42,34 @@ int pam_end(pam_handle_t *pamh, int pam_status) _pam_drop_env(pamh); /* purge the environment */ - _pam_overwrite(pamh->authtok); /* blank out old token */ + pam_overwrite_string(pamh->authtok); /* blank out old token */ _pam_drop(pamh->authtok); - _pam_overwrite(pamh->oldauthtok); /* blank out old token */ + pam_overwrite_string(pamh->oldauthtok); /* blank out old token */ _pam_drop(pamh->oldauthtok); - _pam_overwrite(pamh->former.prompt); + pam_overwrite_string(pamh->former.prompt); _pam_drop(pamh->former.prompt); /* drop saved prompt */ - _pam_overwrite(pamh->service_name); + pam_overwrite_string(pamh->service_name); _pam_drop(pamh->service_name); - _pam_overwrite(pamh->user); + pam_overwrite_string(pamh->user); _pam_drop(pamh->user); - _pam_overwrite(pamh->confdir); + pam_overwrite_string(pamh->confdir); _pam_drop(pamh->confdir); - _pam_overwrite(pamh->prompt); + pam_overwrite_string(pamh->prompt); _pam_drop(pamh->prompt); /* prompt for pam_get_user() */ - _pam_overwrite(pamh->tty); + pam_overwrite_string(pamh->tty); _pam_drop(pamh->tty); - _pam_overwrite(pamh->rhost); + pam_overwrite_string(pamh->rhost); _pam_drop(pamh->rhost); - _pam_overwrite(pamh->ruser); + pam_overwrite_string(pamh->ruser); _pam_drop(pamh->ruser); _pam_drop(pamh->pam_conversation); @@ -76,16 +77,16 @@ int pam_end(pam_handle_t *pamh, int pam_status) _pam_drop(pamh->former.substates); - _pam_overwrite(pamh->xdisplay); + pam_overwrite_string(pamh->xdisplay); _pam_drop(pamh->xdisplay); - _pam_overwrite(pamh->xauth.name); + pam_overwrite_string(pamh->xauth.name); _pam_drop(pamh->xauth.name); - _pam_overwrite_n(pamh->xauth.data, (unsigned int)pamh->xauth.datalen); + pam_overwrite_n(pamh->xauth.data, (unsigned int)pamh->xauth.datalen); _pam_drop(pamh->xauth.data); - _pam_overwrite_n((char *)&pamh->xauth, sizeof(pamh->xauth)); + pam_overwrite_object(&pamh->xauth); - _pam_overwrite(pamh->authtok_type); + pam_overwrite_string(pamh->authtok_type); _pam_drop(pamh->authtok_type); /* and finally liberate the memory for the pam_handle structure */ diff --git a/libpam/pam_env.c b/libpam/pam_env.c index 1c8403d6..bfeb57ab 100644 --- a/libpam/pam_env.c +++ b/libpam/pam_env.c @@ -11,6 +11,7 @@ */ #include "pam_private.h" +#include "pam_inline.h" #include <string.h> #include <stdlib.h> @@ -100,7 +101,7 @@ void _pam_drop_env(pam_handle_t *pamh) for (i=pamh->env->requested-1; i-- > 0; ) { D(("dropping #%3d>%s<", i, pamh->env->list[i])); - _pam_overwrite(pamh->env->list[i]); /* clean */ + pam_overwrite_string(pamh->env->list[i]); /* clean */ _pam_drop(pamh->env->list[i]); /* forget */ } pamh->env->requested = 0; @@ -227,7 +228,7 @@ int pam_putenv(pam_handle_t *pamh, const char *name_value) } else { /* replace old */ D(("replacing item: %s\n with: %s" , pamh->env->list[item], name_value)); - _pam_overwrite(pamh->env->list[item]); + pam_overwrite_string(pamh->env->list[item]); _pam_drop(pamh->env->list[item]); } @@ -261,7 +262,7 @@ int pam_putenv(pam_handle_t *pamh, const char *name_value) */ D(("deleting: env#%3d:[%s]", item, pamh->env->list[item])); - _pam_overwrite(pamh->env->list[item]); + pam_overwrite_string(pamh->env->list[item]); _pam_drop(pamh->env->list[item]); --(pamh->env->requested); D(("mmove: item[%d]+%d -> item[%d]" @@ -341,7 +342,7 @@ static char **_copy_env(pam_handle_t *pamh) /* out of memory */ while (dump[++i]) { - _pam_overwrite(dump[i]); + pam_overwrite_string(dump[i]); _pam_drop(dump[i]); } _pam_drop(dump); diff --git a/libpam/pam_get_authtok.c b/libpam/pam_get_authtok.c index 3fa7f7df..3f383339 100644 --- a/libpam/pam_get_authtok.c +++ b/libpam/pam_get_authtok.c @@ -33,6 +33,7 @@ #include "config.h" #include "pam_private.h" +#include "pam_inline.h" #include <security/pam_ext.h> @@ -174,6 +175,10 @@ pam_get_authtok_internal (pam_handle_t *pamh, int item, (chpass > 1 && resp[1] == NULL)) { /* We want to abort */ + pam_overwrite_string (resp[0]); + _pam_drop (resp[0]); + pam_overwrite_string (resp[1]); + _pam_drop (resp[1]); if (chpass) pam_error (pamh, _("Password change has been aborted.")); return PAM_AUTHTOK_ERR; @@ -182,18 +187,18 @@ pam_get_authtok_internal (pam_handle_t *pamh, int item, if (chpass > 1 && strcmp (resp[0], resp[1]) != 0) { pam_error (pamh, MISTYPED_PASS); - _pam_overwrite (resp[0]); + pam_overwrite_string (resp[0]); _pam_drop (resp[0]); - _pam_overwrite (resp[1]); + pam_overwrite_string (resp[1]); _pam_drop (resp[1]); return PAM_TRY_AGAIN; } - _pam_overwrite (resp[1]); + pam_overwrite_string (resp[1]); _pam_drop (resp[1]); retval = pam_set_item (pamh, item, resp[0]); - _pam_overwrite (resp[0]); + pam_overwrite_string (resp[0]); _pam_drop (resp[0]); if (retval != PAM_SUCCESS) return retval; @@ -263,13 +268,13 @@ pam_get_authtok_verify (pam_handle_t *pamh, const char **authtok, { pam_set_item (pamh, PAM_AUTHTOK, NULL); pam_error (pamh, MISTYPED_PASS); - _pam_overwrite (resp); + pam_overwrite_string (resp); _pam_drop (resp); return PAM_TRY_AGAIN; } retval = pam_set_item (pamh, PAM_AUTHTOK, resp); - _pam_overwrite (resp); + pam_overwrite_string (resp); _pam_drop (resp); if (retval != PAM_SUCCESS) return retval; diff --git a/libpam/pam_handlers.c b/libpam/pam_handlers.c index ffa5e4ae..dc5f81fa 100644 --- a/libpam/pam_handlers.c +++ b/libpam/pam_handlers.c @@ -123,6 +123,10 @@ static int _pam_parse_conf_file(pam_handle_t *pamh, FILE *f module_type = PAM_T_ACCT; } else if (!strcasecmp("password", tok)) { module_type = PAM_T_PASS; + } else if (!strcasecmp("@include", tok)) { + pam_include = 1; + module_type = requested_module_type; + goto parsing_done; } else { /* Illegal module type */ D(("_pam_init_handlers: bad module type: %s", tok)); @@ -193,8 +197,10 @@ static int _pam_parse_conf_file(pam_handle_t *pamh, FILE *f _pam_set_default_control(actions, _PAM_ACTION_BAD); } +parsing_done: tok = _pam_StrTok(NULL, " \n\t", &nexttok); if (pam_include) { + struct stat include_dir; if (substack) { res = _pam_add_handler(pamh, PAM_HT_SUBSTACK, other, stack_level, module_type, actions, tok, @@ -205,13 +211,35 @@ static int _pam_parse_conf_file(pam_handle_t *pamh, FILE *f return PAM_ABORT; } } - if (_pam_load_conf_file(pamh, tok, this_service, module_type, - stack_level + substack + if (tok[0] == '/') { + if (_pam_load_conf_file(pamh, tok, this_service, + module_type, stack_level + substack +#ifdef PAM_READ_BOTH_CONFS + , !other +#endif /* PAM_READ_BOTH_CONFS */ + ) == PAM_SUCCESS) + continue; + } + else if (!stat(PAM_CONFIG_D, &include_dir) + && S_ISDIR(include_dir.st_mode)) + { + char *include_file; + if (asprintf (&include_file, PAM_CONFIG_DF, tok) < 0) { + pam_syslog(pamh, LOG_CRIT, "asprintf failed"); + return PAM_ABORT; + } + if (_pam_load_conf_file(pamh, include_file, this_service, + module_type, stack_level + substack #ifdef PAM_READ_BOTH_CONFS , !other #endif /* PAM_READ_BOTH_CONFS */ - ) == PAM_SUCCESS) - continue; + ) == PAM_SUCCESS) + { + free(include_file); + continue; + } + free(include_file); + } _pam_set_default_control(actions, _PAM_ACTION_BAD); mod_path = NULL; handler_type = PAM_HT_MUST_FAIL; @@ -281,7 +309,7 @@ _pam_open_config_file(pam_handle_t *pamh , char **path , FILE **file) { - const char *pamd_dirs[] = { PAM_CONFIG_DF, PAM_CONFIG_DIST_DF + const char *const pamd_dirs[] = { PAM_CONFIG_DF, PAM_CONFIG_DIST_DF #ifdef VENDORDIR , PAM_CONFIG_DIST2_DF #endif @@ -317,10 +345,12 @@ _pam_open_config_file(pam_handle_t *pamh } for (i = 0; i < PAM_ARRAY_SIZE(pamd_dirs); i++) { - if (asprintf (&p, pamd_dirs[i], service) < 0) { + DIAG_PUSH_IGNORE_FORMAT_NONLITERAL + if (asprintf (&p, pamd_dirs[i], service) < 0) { pam_syslog(pamh, LOG_CRIT, "asprintf failed"); return PAM_BUF_ERR; } + DIAG_POP_IGNORE_FORMAT_NONLITERAL D(("opening %s", p)); f = fopen(p, "r"); @@ -707,7 +737,27 @@ _pam_load_module(pam_handle_t *pamh, const char *mod_path, int handler_type) success = PAM_ABORT; D(("_pam_load_module: _pam_dlopen(%s)", mod_path)); - mod->dl_handle = _pam_dlopen(mod_path); + if (mod_path[0] == '/') { + mod->dl_handle = _pam_dlopen(mod_path); + } else { + char *mod_full_path = NULL; + if (asprintf(&mod_full_path, "%s%s", + DEFAULT_MODULE_PATH, mod_path) >= 0) { + mod->dl_handle = _pam_dlopen(mod_full_path); + _pam_drop(mod_full_path); + } else { + pam_syslog(pamh, LOG_CRIT, "cannot malloc full mod path"); + } + if (!mod->dl_handle) { + if (asprintf(&mod_full_path, "%s/%s", + _PAM_ISA, mod_path) >= 0) { + mod->dl_handle = _pam_dlopen(mod_full_path); + _pam_drop(mod_full_path); + } else { + pam_syslog(pamh, LOG_CRIT, "cannot malloc full mod path"); + } + } + } D(("_pam_load_module: _pam_dlopen'ed")); D(("_pam_load_module: dlopen'ed")); if (mod->dl_handle == NULL) { @@ -784,7 +834,6 @@ int _pam_add_handler(pam_handle_t *pamh struct handler **handler_p2; struct handlers *the_handlers; const char *sym, *sym2; - char *mod_full_path; servicefn func, func2; int mod_type = PAM_MT_FAULTY_MOD; @@ -796,16 +845,7 @@ int _pam_add_handler(pam_handle_t *pamh if ((handler_type == PAM_HT_MODULE || handler_type == PAM_HT_SILENT_MODULE) && mod_path != NULL) { - if (mod_path[0] == '/') { - mod = _pam_load_module(pamh, mod_path, handler_type); - } else if (asprintf(&mod_full_path, "%s%s", - DEFAULT_MODULE_PATH, mod_path) >= 0) { - mod = _pam_load_module(pamh, mod_full_path, handler_type); - _pam_drop(mod_full_path); - } else { - pam_syslog(pamh, LOG_CRIT, "cannot malloc full mod path"); - return PAM_ABORT; - } + mod = _pam_load_module(pamh, mod_path, handler_type); if (mod == NULL) { /* if we get here with NULL it means allocation error */ @@ -889,8 +929,8 @@ int _pam_add_handler(pam_handle_t *pamh handler_p = &((*handler_p)->next); } - if ((*handler_p = malloc(sizeof(struct handler))) == NULL) { - pam_syslog(pamh, LOG_CRIT, "cannot malloc struct handler #1"); + if ((*handler_p = calloc(1, sizeof(struct handler))) == NULL) { + pam_syslog(pamh, LOG_CRIT, "cannot allocate struct handler #1"); return (PAM_ABORT); } @@ -904,8 +944,6 @@ int _pam_add_handler(pam_handle_t *pamh (*handler_p)->argv = argv; /* not a copy */ if (((*handler_p)->mod_name = extract_modulename(mod_path)) == NULL) return PAM_ABORT; - (*handler_p)->grantor = 0; - (*handler_p)->next = NULL; /* some of the modules have a second calling function */ if (handler_p2) { @@ -914,8 +952,8 @@ int _pam_add_handler(pam_handle_t *pamh handler_p2 = &((*handler_p2)->next); } - if ((*handler_p2 = malloc(sizeof(struct handler))) == NULL) { - pam_syslog(pamh, LOG_CRIT, "cannot malloc struct handler #2"); + if ((*handler_p2 = calloc(1, sizeof(struct handler))) == NULL) { + pam_syslog(pamh, LOG_CRIT, "cannot allocate struct handler #2"); return (PAM_ABORT); } @@ -933,13 +971,9 @@ int _pam_add_handler(pam_handle_t *pamh return (PAM_ABORT); } memcpy((*handler_p2)->argv, argv, argvlen); - } else { - (*handler_p2)->argv = NULL; /* no arguments */ } if (((*handler_p2)->mod_name = extract_modulename(mod_path)) == NULL) return PAM_ABORT; - (*handler_p2)->grantor = 0; - (*handler_p2)->next = NULL; } D(("_pam_add_handler: returning successfully")); @@ -1037,7 +1071,7 @@ void _pam_free_handlers_aux(struct handler **hp) _pam_drop(h->argv); /* This is all allocated in a single chunk */ _pam_drop(h->mod_name); h = h->next; - memset(last, 0, sizeof(*last)); + pam_overwrite_object(last); free(last); } diff --git a/libpam/pam_item.c b/libpam/pam_item.c index d6af710b..42857da5 100644 --- a/libpam/pam_item.c +++ b/libpam/pam_item.c @@ -5,6 +5,7 @@ */ #include "pam_private.h" +#include "pam_inline.h" #include <ctype.h> #include <stdlib.h> @@ -79,7 +80,7 @@ int pam_set_item (pam_handle_t *pamh, int item_type, const void *item) */ if (__PAM_FROM_MODULE(pamh)) { if (pamh->authtok != item) { - _pam_overwrite(pamh->authtok); + pam_overwrite_string(pamh->authtok); TRY_SET(pamh->authtok, item); } } else { @@ -95,7 +96,7 @@ int pam_set_item (pam_handle_t *pamh, int item_type, const void *item) */ if (__PAM_FROM_MODULE(pamh)) { if (pamh->oldauthtok != item) { - _pam_overwrite(pamh->oldauthtok); + pam_overwrite_string(pamh->oldauthtok); TRY_SET(pamh->oldauthtok, item); } } else { @@ -139,24 +140,23 @@ int pam_set_item (pam_handle_t *pamh, int item_type, const void *item) if (&pamh->xauth == item) break; if (pamh->xauth.namelen) { - _pam_overwrite(pamh->xauth.name); + pam_overwrite_string(pamh->xauth.name); free(pamh->xauth.name); } if (pamh->xauth.datalen) { - _pam_overwrite_n(pamh->xauth.data, - (unsigned int) pamh->xauth.datalen); + pam_overwrite_n(pamh->xauth.data, (unsigned int) pamh->xauth.datalen); free(pamh->xauth.data); } pamh->xauth = *((const struct pam_xauth_data *) item); if ((pamh->xauth.name=_pam_strdup(pamh->xauth.name)) == NULL) { - memset(&pamh->xauth, '\0', sizeof(pamh->xauth)); + pam_overwrite_object(&pamh->xauth); return PAM_BUF_ERR; } if ((pamh->xauth.data=_pam_memdup(pamh->xauth.data, pamh->xauth.datalen)) == NULL) { - _pam_overwrite(pamh->xauth.name); + pam_overwrite_string(pamh->xauth.name); free(pamh->xauth.name); - memset(&pamh->xauth, '\0', sizeof(pamh->xauth)); + pam_overwrite_object(&pamh->xauth); return PAM_BUF_ERR; } break; @@ -330,7 +330,7 @@ int pam_get_user(pam_handle_t *pamh, const char **user, const char *prompt) /* ok, we can resume where we left off last time */ pamh->former.want_user = PAM_FALSE; - _pam_overwrite(pamh->former.prompt); + pam_overwrite_string(pamh->former.prompt); _pam_drop(pamh->former.prompt); } @@ -388,7 +388,7 @@ int pam_get_user(pam_handle_t *pamh, const char **user, const char *prompt) * note 'resp' is allocated by the application and is * correctly free()'d here */ - _pam_drop_reply(resp, 1); + pam_drop_response(resp, 1); } D(("completed")); diff --git a/libpam/pam_modutil_getlogin.c b/libpam/pam_modutil_getlogin.c index 04a20fd8..2e7a0116 100644 --- a/libpam/pam_modutil_getlogin.c +++ b/libpam/pam_modutil_getlogin.c @@ -10,7 +10,6 @@ #include <stdlib.h> #include <unistd.h> -#include <utmp.h> #define _PAMMODUTIL_GETLOGIN "_pammodutil_getlogin" @@ -19,62 +18,29 @@ pam_modutil_getlogin(pam_handle_t *pamh) { int status; const void *logname; - const void *void_curr_tty; - const char *curr_tty; char *curr_user; - struct utmp *ut, line; status = pam_get_data(pamh, _PAMMODUTIL_GETLOGIN, &logname); if (status == PAM_SUCCESS) { return logname; } - status = pam_get_item(pamh, PAM_TTY, &void_curr_tty); - if ((status != PAM_SUCCESS) || (void_curr_tty == NULL)) - curr_tty = ttyname(0); - else - curr_tty = (const char*)void_curr_tty; - - if (curr_tty == NULL) { - return NULL; - } - - if (curr_tty[0] == '/') { /* full path */ - const char *t; - curr_tty++; - if ((t = strchr(curr_tty, '/')) != NULL) { - curr_tty = t + 1; - } - } - logname = NULL; - - setutent(); - strncpy(line.ut_line, curr_tty, sizeof(line.ut_line)); - - if ((ut = getutline(&line)) == NULL) { - goto clean_up_and_go_home; + logname = getlogin(); + if (logname == NULL) { + return NULL; } - curr_user = calloc(sizeof(line.ut_user)+1, 1); + curr_user = strdup(logname); if (curr_user == NULL) { - goto clean_up_and_go_home; + return NULL; } - strncpy(curr_user, ut->ut_user, sizeof(ut->ut_user)); - /* calloc already zeroed the memory */ - status = pam_set_data(pamh, _PAMMODUTIL_GETLOGIN, curr_user, pam_modutil_cleanup); if (status != PAM_SUCCESS) { - free(curr_user); - goto clean_up_and_go_home; + free(curr_user); + return NULL; } - logname = curr_user; - -clean_up_and_go_home: - - endutent(); - - return logname; + return curr_user; } diff --git a/libpam/pam_modutil_priv.c b/libpam/pam_modutil_priv.c index a463e06a..7df6e6b1 100644 --- a/libpam/pam_modutil_priv.c +++ b/libpam/pam_modutil_priv.c @@ -14,7 +14,9 @@ #include <syslog.h> #include <pwd.h> #include <grp.h> +#ifdef HAVE_SYS_FSUID_H #include <sys/fsuid.h> +#endif /* HAVE_SYS_FSUID_H */ /* * Two setfsuid() calls in a row are necessary to check @@ -22,17 +24,55 @@ */ static int change_uid(uid_t uid, uid_t *save) { +#ifdef HAVE_SYS_FSUID_H uid_t tmp = setfsuid(uid); if (save) *save = tmp; return (uid_t) setfsuid(uid) == uid ? 0 : -1; +#else + uid_t euid = geteuid(); + uid_t ruid = getuid(); + if (save) + *save = ruid; + if (ruid == uid && uid != 0) + if (setreuid(euid, uid)) + return -1; + else { + setreuid(0, -1); + if (setreuid(-1, uid)) { + setreuid(-1, 0); + setreuid(0, -1); + if (setreuid(-1, uid)) + return -1; + } + } +#endif } static int change_gid(gid_t gid, gid_t *save) { +#ifdef HAVE_SYS_FSUID_H gid_t tmp = setfsgid(gid); if (save) *save = tmp; return (gid_t) setfsgid(gid) == gid ? 0 : -1; +#else + gid_t egid = getegid(); + gid_t rgid = getgid(); + if (save) + *save = rgid; + if (rgid == gid) + if (setregid(egid, gid)) + return -1; + else { + setregid(0, -1); + if (setregid(-1, gid)) { + setregid(-1, 0); + setregid(0, -1); + if (setregid(-1, gid)) + return -1; + } + } +#endif } static int cleanup(struct pam_modutil_privs *p) diff --git a/libpam/pam_vprompt.c b/libpam/pam_vprompt.c index c53079b5..8c9d63d5 100644 --- a/libpam/pam_vprompt.c +++ b/libpam/pam_vprompt.c @@ -40,10 +40,10 @@ #include <errno.h> #include <security/pam_modules.h> -#include <security/_pam_macros.h> #include <security/pam_ext.h> #include "pam_private.h" +#include "pam_inline.h" int pam_vprompt (pam_handle_t *pamh, int style, char **response, @@ -88,10 +88,10 @@ pam_vprompt (pam_handle_t *pamh, int style, char **response, *response = pam_resp == NULL ? NULL : pam_resp->resp; else if (pam_resp && pam_resp->resp) { - _pam_overwrite (pam_resp->resp); + pam_overwrite_string (pam_resp->resp); _pam_drop (pam_resp->resp); } - _pam_overwrite (msgbuf); + pam_overwrite_string (msgbuf); _pam_drop (pam_resp); free (msgbuf); if (retval != PAM_SUCCESS) |