From b0ec5d1e472a0cd74972bfe9575dcf6a3d0cad1c Mon Sep 17 00:00:00 2001 From: "Dmitry V. Levin" Date: Fri, 24 Jan 2014 15:32:08 +0000 Subject: Introduce pam_modutil_sanitize_helper_fds This change introduces pam_modutil_sanitize_helper_fds - a new function that redirects standard descriptors and closes all other descriptors. pam_modutil_sanitize_helper_fds supports three types of input and output redirection: - PAM_MODUTIL_IGNORE_FD: do not redirect at all. - PAM_MODUTIL_PIPE_FD: redirect to a pipe. For stdin, it is implemented by creating a pipe, closing its write end, and redirecting stdin to its read end. Likewise, for stdout/stderr it is implemented by creating a pipe, closing its read end, and redirecting to its write end. Unlike stdin redirection, stdout/stderr redirection to a pipe has a side effect that a process writing to such descriptor should be prepared to handle SIGPIPE appropriately. - PAM_MODUTIL_NULL_FD: redirect to /dev/null. For stdin, it is implemented via PAM_MODUTIL_PIPE_FD because there is no functional difference. For stdout/stderr, it is classic redirection to /dev/null. PAM_MODUTIL_PIPE_FD is usually more suitable due to linux kernel security restrictions, but when the helper process might be writing to the corresponding descriptor and termination of the helper process by SIGPIPE is not desirable, one should choose PAM_MODUTIL_NULL_FD. * libpam/pam_modutil_sanitize.c: New file. * libpam/Makefile.am (libpam_la_SOURCES): Add it. * libpam/include/security/pam_modutil.h (pam_modutil_redirect_fd, pam_modutil_sanitize_helper_fds): New declarations. * libpam/libpam.map (LIBPAM_MODUTIL_1.1.9): New interface. * modules/pam_exec/pam_exec.c (call_exec): Use pam_modutil_sanitize_helper_fds. * modules/pam_mkhomedir/pam_mkhomedir.c (create_homedir): Likewise. * modules/pam_unix/pam_unix_acct.c (_unix_run_verify_binary): Likewise. * modules/pam_unix/pam_unix_passwd.c (_unix_run_update_binary): Likewise. * modules/pam_unix/support.c (_unix_run_helper_binary): Likewise. * modules/pam_xauth/pam_xauth.c (run_coprocess): Likewise. * modules/pam_unix/support.h (MAX_FD_NO): Remove. --- libpam/Makefile.am | 2 +- libpam/include/security/pam_modutil.h | 13 +++ libpam/libpam.map | 5 + libpam/pam_modutil_sanitize.c | 175 ++++++++++++++++++++++++++++++++++ 4 files changed, 194 insertions(+), 1 deletion(-) create mode 100644 libpam/pam_modutil_sanitize.c (limited to 'libpam') diff --git a/libpam/Makefile.am b/libpam/Makefile.am index 417ca779..685a797d 100644 --- a/libpam/Makefile.am +++ b/libpam/Makefile.am @@ -43,4 +43,4 @@ libpam_la_SOURCES = pam_account.c pam_auth.c pam_data.c pam_delay.c \ pam_modutil_cleanup.c pam_modutil_getpwnam.c pam_modutil_ioloop.c \ pam_modutil_getgrgid.c pam_modutil_getpwuid.c pam_modutil_getgrnam.c \ pam_modutil_getspnam.c pam_modutil_getlogin.c pam_modutil_ingroup.c \ - pam_modutil_priv.c + pam_modutil_priv.c pam_modutil_sanitize.c diff --git a/libpam/include/security/pam_modutil.h b/libpam/include/security/pam_modutil.h index 8087ba15..4ce8c552 100644 --- a/libpam/include/security/pam_modutil.h +++ b/libpam/include/security/pam_modutil.h @@ -129,6 +129,19 @@ extern int PAM_NONNULL((1,2)) pam_modutil_regain_priv(pam_handle_t *pamh, struct pam_modutil_privs *p); +enum pam_modutil_redirect_fd { + PAM_MODUTIL_IGNORE_FD, /* do not redirect */ + PAM_MODUTIL_PIPE_FD, /* redirect to a pipe */ + PAM_MODUTIL_NULL_FD, /* redirect to /dev/null */ +}; + +/* redirect standard descriptors, close all other descriptors. */ +extern int PAM_NONNULL((1)) +pam_modutil_sanitize_helper_fds(pam_handle_t *pamh, + enum pam_modutil_redirect_fd redirect_stdin, + enum pam_modutil_redirect_fd redirect_stdout, + enum pam_modutil_redirect_fd redirect_stderr); + #ifdef __cplusplus } #endif diff --git a/libpam/libpam.map b/libpam/libpam.map index b0885d65..d6835b47 100644 --- a/libpam/libpam.map +++ b/libpam/libpam.map @@ -67,3 +67,8 @@ LIBPAM_MODUTIL_1.1.3 { pam_modutil_drop_priv; pam_modutil_regain_priv; } LIBPAM_MODUTIL_1.1; + +LIBPAM_MODUTIL_1.1.9 { + global: + pam_modutil_sanitize_helper_fds; +} LIBPAM_MODUTIL_1.1.3; diff --git a/libpam/pam_modutil_sanitize.c b/libpam/pam_modutil_sanitize.c new file mode 100644 index 00000000..65f85d01 --- /dev/null +++ b/libpam/pam_modutil_sanitize.c @@ -0,0 +1,175 @@ +/* + * This file implements the following functions: + * pam_modutil_sanitize_helper_fds: + * redirects standard descriptors, closes all other descriptors. + */ + +#include "pam_modutil_private.h" +#include +#include +#include +#include +#include + +/* + * Creates a pipe, closes its write end, redirects fd to its read end. + * Returns fd on success, -1 otherwise. + */ +static int +redirect_in_pipe(pam_handle_t *pamh, int fd, const char *name) +{ + int in[2]; + + if (pipe(in) < 0) { + pam_syslog(pamh, LOG_ERR, "Could not create pipe: %m"); + return -1; + } + + close(in[1]); + + if (in[0] == fd) + return fd; + + if (dup2(in[0], fd) != fd) { + pam_syslog(pamh, LOG_ERR, "dup2 of %s failed: %m", name); + fd = -1; + } + + close(in[0]); + return fd; +} + +/* + * Creates a pipe, closes its read end, redirects fd to its write end. + * Returns fd on success, -1 otherwise. + */ +static int +redirect_out_pipe(pam_handle_t *pamh, int fd, const char *name) +{ + int out[2]; + + if (pipe(out) < 0) { + pam_syslog(pamh, LOG_ERR, "Could not create pipe: %m"); + return -1; + } + + close(out[0]); + + if (out[1] == fd) + return fd; + + if (dup2(out[1], fd) != fd) { + pam_syslog(pamh, LOG_ERR, "dup2 of %s failed: %m", name); + fd = -1; + } + + close(out[1]); + return fd; +} + +/* + * Opens /dev/null for writing, redirects fd there. + * Returns fd on success, -1 otherwise. + */ +static int +redirect_out_null(pam_handle_t *pamh, int fd, const char *name) +{ + int null = open("/dev/null", O_WRONLY); + + if (null < 0) { + pam_syslog(pamh, LOG_ERR, "open of %s failed: %m", "/dev/null"); + return -1; + } + + if (null == fd) + return fd; + + if (dup2(null, fd) != fd) { + pam_syslog(pamh, LOG_ERR, "dup2 of %s failed: %m", name); + fd = -1; + } + + close(null); + return fd; +} + +static int +redirect_out(pam_handle_t *pamh, enum pam_modutil_redirect_fd mode, + int fd, const char *name) +{ + switch (mode) { + case PAM_MODUTIL_PIPE_FD: + if (redirect_out_pipe(pamh, fd, name) < 0) + return -1; + break; + case PAM_MODUTIL_NULL_FD: + if (redirect_out_null(pamh, fd, name) < 0) + return -1; + break; + case PAM_MODUTIL_IGNORE_FD: + break; + } + return fd; +} + +/* Closes all descriptors after stderr. */ +static void +close_fds(void) +{ + /* + * An arbitrary upper limit for the maximum file descriptor number + * returned by RLIMIT_NOFILE. + */ + const int MAX_FD_NO = 65535; + + /* The lower limit is the same as for _POSIX_OPEN_MAX. */ + const int MIN_FD_NO = 20; + + int fd; + struct rlimit rlim; + + if (getrlimit(RLIMIT_NOFILE, &rlim) || rlim.rlim_max > MAX_FD_NO) + fd = MAX_FD_NO; + else if (rlim.rlim_max < MIN_FD_NO) + fd = MIN_FD_NO; + else + fd = rlim.rlim_max - 1; + + for (; fd > STDERR_FILENO; --fd) + close(fd); +} + +int +pam_modutil_sanitize_helper_fds(pam_handle_t *pamh, + enum pam_modutil_redirect_fd stdin_mode, + enum pam_modutil_redirect_fd stdout_mode, + enum pam_modutil_redirect_fd stderr_mode) +{ + if (stdin_mode != PAM_MODUTIL_IGNORE_FD && + redirect_in_pipe(pamh, STDIN_FILENO, "stdin") < 0) { + return -1; + } + + if (redirect_out(pamh, stdout_mode, STDOUT_FILENO, "stdout") < 0) + return -1; + + /* + * If stderr should not be ignored and + * redirect mode for stdout and stderr are the same, + * optimize by redirecting stderr to stdout. + */ + if (stderr_mode != PAM_MODUTIL_IGNORE_FD && + stdout_mode == stderr_mode) { + if (dup2(STDOUT_FILENO, STDERR_FILENO) != STDERR_FILENO) { + pam_syslog(pamh, LOG_ERR, + "dup2 of %s failed: %m", "stderr"); + return -1; + } + } else { + if (redirect_out(pamh, stderr_mode, STDERR_FILENO, "stderr") < 0) + return -1; + } + + close_fds(); + return 0; +} -- cgit v1.2.1 From 0d29e379601819c7f7ed8de18b54de803a9f4049 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Fri, 5 Sep 2014 09:09:37 +0200 Subject: Add grantor field to audit records of libpam. The grantor field gives audit trail of PAM modules which granted access for successful return from libpam calls. In case of failed return the grantor field is set to '?'. libpam/pam_account.c (pam_acct_mgmt): Remove _pam_auditlog() call. libpam/pam_auth.c (pam_authenticate, pam_setcred): Likewise. libpam/pam_password.c (pam_chauthtok): Likewise. libpam/pam_session.c (pam_open_session, pam_close_session): Likewise. libpam/pam_audit.c (_pam_audit_writelog): Add grantors parameter, add grantor= field to the message if grantors is set. (_pam_list_grantors): New function creating the string with grantors list. (_pam_auditlog): Add struct handler pointer parameter, call _pam_list_grantors() to list the grantors from the handler list. (_pam_audit_end): Add NULL handler parameter to _pam_auditlog() call. (pam_modutil_audit_write): Add NULL grantors parameter to _pam_audit_writelog(). libpam/pam_dispatch.c (_pam_dispatch_aux): Set h->grantor where appropriate. (_pam_clear_grantors): New function to clear grantor field of handler. (_pam_dispatch): Call _pam_clear_grantors() before executing the stack. Call _pam_auditlog() when appropriate. libpam/pam_handlers.c (extract_modulename): Do not allow empty module name or just "?" to avoid confusing audit trail. (_pam_add_handler): Test for NULL return from extract_modulename(). Clear grantor field of handler. libpam/pam_private.h: Add grantor field to struct handler, add handler pointer parameter to _pam_auditlog(). --- libpam/pam_account.c | 4 --- libpam/pam_audit.c | 84 +++++++++++++++++++++++++++++++++++++++++++-------- libpam/pam_auth.c | 8 ----- libpam/pam_dispatch.c | 41 ++++++++++++++++++++----- libpam/pam_handlers.c | 14 +++++++-- libpam/pam_password.c | 4 --- libpam/pam_private.h | 3 +- libpam/pam_session.c | 7 ----- 8 files changed, 119 insertions(+), 46 deletions(-) (limited to 'libpam') diff --git a/libpam/pam_account.c b/libpam/pam_account.c index 572acc47..3a4fb1fc 100644 --- a/libpam/pam_account.c +++ b/libpam/pam_account.c @@ -19,9 +19,5 @@ int pam_acct_mgmt(pam_handle_t *pamh, int flags) retval = _pam_dispatch(pamh, flags, PAM_ACCOUNT); -#ifdef HAVE_LIBAUDIT - retval = _pam_auditlog(pamh, PAM_ACCOUNT, retval, flags); -#endif - return retval; } diff --git a/libpam/pam_audit.c b/libpam/pam_audit.c index 531746ab..24fb799a 100644 --- a/libpam/pam_audit.c +++ b/libpam/pam_audit.c @@ -6,12 +6,12 @@ Authors: Steve Grubb */ -#include -#include #include "pam_private.h" #include "pam_modutil_private.h" #ifdef HAVE_LIBAUDIT +#include +#include #include #include #include @@ -25,17 +25,24 @@ static int _pam_audit_writelog(pam_handle_t *pamh, int audit_fd, int type, - const char *message, int retval) + const char *message, const char *grantors, int retval) { static int old_errno = -1; - int rc; - char buf[32]; + int rc = -ENOMEM; + char *buf; + const char *grantors_field = " grantors="; - snprintf(buf, sizeof(buf), "PAM:%s", message); + if (grantors == NULL) { + grantors = ""; + grantors_field = ""; + } - rc = audit_log_acct_message (audit_fd, type, NULL, buf, - (retval != PAM_USER_UNKNOWN && pamh->user) ? pamh->user : "?", - -1, pamh->rhost, NULL, pamh->tty, retval == PAM_SUCCESS ); + if (asprintf(&buf, "PAM:%s%s%s", message, grantors_field, grantors) >= 0) { + rc = audit_log_acct_message(audit_fd, type, NULL, buf, + (retval != PAM_USER_UNKNOWN && pamh->user) ? pamh->user : "?", + -1, pamh->rhost, NULL, pamh->tty, retval == PAM_SUCCESS); + free(buf); + } /* libaudit sets errno to his own negative error code. This can be an official errno number, but must not. It can also be a audit @@ -78,12 +85,54 @@ _pam_audit_open(pam_handle_t *pamh) return audit_fd; } +static int +_pam_list_grantors(struct handler *hlist, int retval, char **list) +{ + *list = NULL; + + if (retval == PAM_SUCCESS) { + struct handler *h; + char *p = NULL; + size_t len = 0; + + for (h = hlist; h != NULL; h = h->next) { + if (h->grantor) { + len += strlen(h->mod_name) + 1; + } + } + + if (len == 0) { + return 0; + } + + *list = malloc(len); + if (*list == NULL) { + return -1; + } + + for (h = hlist; h != NULL; h = h->next) { + if (h->grantor) { + if (p == NULL) { + p = *list; + } else { + p = stpcpy(p, ","); + } + + p = stpcpy(p, h->mod_name); + } + } + } + + return 0; +} + int -_pam_auditlog(pam_handle_t *pamh, int action, int retval, int flags) +_pam_auditlog(pam_handle_t *pamh, int action, int retval, int flags, struct handler *h) { const char *message; int type; int audit_fd; + char *grantors; if ((audit_fd=_pam_audit_open(pamh)) == -1) { return PAM_SYSTEM_ERR; @@ -134,8 +183,17 @@ _pam_auditlog(pam_handle_t *pamh, int action, int retval, int flags) retval = PAM_SYSTEM_ERR; } - if (_pam_audit_writelog(pamh, audit_fd, type, message, retval) < 0) + if (_pam_list_grantors(h, retval, &grantors) < 0) { + /* allocation failure */ + pam_syslog(pamh, LOG_CRIT, "_pam_list_grantors() failed: %m"); retval = PAM_SYSTEM_ERR; + } + + if (_pam_audit_writelog(pamh, audit_fd, type, message, + grantors ? grantors : "?", retval) < 0) + retval = PAM_SYSTEM_ERR; + + free(grantors); audit_close(audit_fd); return retval; @@ -149,7 +207,7 @@ _pam_audit_end(pam_handle_t *pamh, int status UNUSED) * stacks having been run. Assume that this is sshd faking * things for an unknown user. */ - _pam_auditlog(pamh, _PAM_ACTION_DONE, PAM_USER_UNKNOWN, 0); + _pam_auditlog(pamh, _PAM_ACTION_DONE, PAM_USER_UNKNOWN, 0, NULL); } return 0; @@ -168,7 +226,7 @@ pam_modutil_audit_write(pam_handle_t *pamh, int type, return retval; } - rc = _pam_audit_writelog(pamh, audit_fd, type, message, retval); + rc = _pam_audit_writelog(pamh, audit_fd, type, message, NULL, retval); audit_close(audit_fd); diff --git a/libpam/pam_auth.c b/libpam/pam_auth.c index 5984fa59..1e7bc6e7 100644 --- a/libpam/pam_auth.c +++ b/libpam/pam_auth.c @@ -45,10 +45,6 @@ int pam_authenticate(pam_handle_t *pamh, int flags) prelude_send_alert(pamh, retval); #endif -#ifdef HAVE_LIBAUDIT - retval = _pam_auditlog(pamh, PAM_AUTHENTICATE, retval, flags); -#endif - return retval; } @@ -71,10 +67,6 @@ int pam_setcred(pam_handle_t *pamh, int flags) retval = _pam_dispatch(pamh, flags, PAM_SETCRED); -#ifdef HAVE_LIBAUDIT - retval = _pam_auditlog(pamh, PAM_SETCRED, retval, flags); -#endif - D(("pam_setcred exit")); return retval; diff --git a/libpam/pam_dispatch.c b/libpam/pam_dispatch.c index eb52c824..cf632e8e 100644 --- a/libpam/pam_dispatch.c +++ b/libpam/pam_dispatch.c @@ -217,8 +217,14 @@ static int _pam_dispatch_aux(pam_handle_t *pamh, int flags, struct handler *h, status = retval; } } - if ( impression == _PAM_POSITIVE && action == _PAM_ACTION_DONE ) { - goto decision_made; + if ( impression == _PAM_POSITIVE ) { + if ( retval == PAM_SUCCESS ) { + h->grantor = 1; + } + + if ( action == _PAM_ACTION_DONE ) { + goto decision_made; + } } break; @@ -262,6 +268,9 @@ static int _pam_dispatch_aux(pam_handle_t *pamh, int flags, struct handler *h, || (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; } @@ -308,6 +317,13 @@ decision_made: /* by getting here we have made a decision */ return status; } +static void _pam_clear_grantors(struct handler *h) +{ + for (; h != NULL; h = h->next) { + h->grantor = 0; + } +} + /* * This function translates the module dispatch request into a pointer * to the stack of modules that will actually be run. the @@ -318,21 +334,21 @@ decision_made: /* by getting here we have made a decision */ int _pam_dispatch(pam_handle_t *pamh, int flags, int choice) { struct handler *h = NULL; - int retval, use_cached_chain; + int retval = PAM_SYSTEM_ERR, use_cached_chain; _pam_boolean resumed; IF_NO_PAMH("_pam_dispatch", pamh, PAM_SYSTEM_ERR); if (__PAM_FROM_MODULE(pamh)) { D(("called from a module!?")); - return PAM_SYSTEM_ERR; + goto end; } /* Load all modules, resolve all symbols */ if ((retval = _pam_init_handlers(pamh)) != PAM_SUCCESS) { pam_syslog(pamh, LOG_ERR, "unable to dispatch function"); - return retval; + goto end; } use_cached_chain = _PAM_PLEASE_FREEZE; @@ -360,7 +376,8 @@ int _pam_dispatch(pam_handle_t *pamh, int flags, int choice) break; default: pam_syslog(pamh, LOG_ERR, "undefined fn choice; %d", choice); - return PAM_ABORT; + retval = PAM_ABORT; + goto end; } if (h == NULL) { /* there was no handlers.conf... entry; will use @@ -393,11 +410,13 @@ int _pam_dispatch(pam_handle_t *pamh, int flags, int choice) pam_syslog(pamh, LOG_ERR, "application failed to re-exec stack [%d:%d]", pamh->former.choice, choice); - return PAM_ABORT; + retval = PAM_ABORT; + goto end; } resumed = PAM_TRUE; } else { resumed = PAM_FALSE; + _pam_clear_grantors(h); } __PAM_TO_MODULE(pamh); @@ -417,5 +436,13 @@ int _pam_dispatch(pam_handle_t *pamh, int flags, int choice) pamh->former.choice = PAM_NOT_STACKED; } +end: + +#ifdef HAVE_LIBAUDIT + if (choice != PAM_CHAUTHTOK || flags & PAM_UPDATE_AUTHTOK || retval != PAM_SUCCESS) { + retval = _pam_auditlog(pamh, choice, retval, flags, h); + } +#endif + return retval; } diff --git a/libpam/pam_handlers.c b/libpam/pam_handlers.c index 02714f78..df3a1d91 100644 --- a/libpam/pam_handlers.c +++ b/libpam/pam_handlers.c @@ -611,6 +611,12 @@ extract_modulename(const char *mod_path) if (dot) *dot = '\0'; + if (*retval == '\0' || strcmp(retval, "?") == 0) { + /* do not allow empty module name or "?" to avoid confusing audit trail */ + _pam_drop(retval); + return NULL; + } + return retval; } @@ -888,7 +894,9 @@ int _pam_add_handler(pam_handle_t *pamh (*handler_p)->cached_retval_p = &((*handler_p)->cached_retval); (*handler_p)->argc = argc; (*handler_p)->argv = argv; /* not a copy */ - (*handler_p)->mod_name = extract_modulename(mod_path); + 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 */ @@ -920,7 +928,9 @@ int _pam_add_handler(pam_handle_t *pamh } else { (*handler_p2)->argv = NULL; /* no arguments */ } - (*handler_p2)->mod_name = extract_modulename(mod_path); + if (((*handler_p2)->mod_name = extract_modulename(mod_path)) == NULL) + return PAM_ABORT; + (*handler_p2)->grantor = 0; (*handler_p2)->next = NULL; } diff --git a/libpam/pam_password.c b/libpam/pam_password.c index 75db5e50..592e01fb 100644 --- a/libpam/pam_password.c +++ b/libpam/pam_password.c @@ -57,9 +57,5 @@ int pam_chauthtok(pam_handle_t *pamh, int flags) D(("will resume when ready", retval)); } -#ifdef HAVE_LIBAUDIT - retval = _pam_auditlog(pamh, PAM_CHAUTHTOK, retval, flags); -#endif - return retval; } diff --git a/libpam/pam_private.h b/libpam/pam_private.h index 134dc726..d93283ce 100644 --- a/libpam/pam_private.h +++ b/libpam/pam_private.h @@ -55,6 +55,7 @@ struct handler { struct handler *next; char *mod_name; int stack_level; + int grantor; }; #define PAM_HT_MODULE 0 @@ -316,7 +317,7 @@ if ((pamh) == NULL) { \ do { (pamh)->caller_is = _PAM_CALLED_FROM_APP; } while (0) #ifdef HAVE_LIBAUDIT -extern int _pam_auditlog(pam_handle_t *pamh, int action, int retval, int flags); +extern int _pam_auditlog(pam_handle_t *pamh, int action, int retval, int flags, struct handler *h); extern int _pam_audit_end(pam_handle_t *pamh, int pam_status); #endif diff --git a/libpam/pam_session.c b/libpam/pam_session.c index 512153f2..cb393c1a 100644 --- a/libpam/pam_session.c +++ b/libpam/pam_session.c @@ -22,9 +22,6 @@ int pam_open_session(pam_handle_t *pamh, int flags) } retval = _pam_dispatch(pamh, flags, PAM_OPEN_SESSION); -#ifdef HAVE_LIBAUDIT - retval = _pam_auditlog(pamh, PAM_OPEN_SESSION, retval, flags); -#endif return retval; } @@ -43,10 +40,6 @@ int pam_close_session(pam_handle_t *pamh, int flags) retval = _pam_dispatch(pamh, flags, PAM_CLOSE_SESSION); -#ifdef HAVE_LIBAUDIT - retval = _pam_auditlog(pamh, PAM_CLOSE_SESSION, retval, flags); -#endif - return retval; } -- cgit v1.2.1 From c1023edd3d2e9dcd83a7822f1830a69f51101334 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Mon, 22 Dec 2014 15:46:43 -0500 Subject: libpam: Only print "Password change aborted" when it's true. pam_get_authtok() may be used any time that a password needs to be entered, unlike pam_get_authtok_{no,}verify(), which may only be used when changing a password; yet when the user aborts, it prints "Password change aborted." whether or not that was the operation being performed. This bug was non-obvious because none of the modules distributed with Linux-PAM use it for anything but changing passwords; pam_unix has its own utility function that it uses instead. As an example, the nss-pam-ldapd package uses it in pam_sm_authenticate(). libpam/pam_get_authtok.c (pam_get_authtok_internal): check that the password is trying to be changed before printing a message about the password change being aborted. --- libpam/pam_get_authtok.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'libpam') diff --git a/libpam/pam_get_authtok.c b/libpam/pam_get_authtok.c index 31bb1627..663f1f36 100644 --- a/libpam/pam_get_authtok.c +++ b/libpam/pam_get_authtok.c @@ -151,8 +151,9 @@ pam_get_authtok_internal (pam_handle_t *pamh, int item, if (retval != PAM_SUCCESS || resp[0] == NULL || (chpass > 1 && resp[1] == NULL)) { - /* We want to abort the password change */ - pam_error (pamh, _("Password change aborted.")); + /* We want to abort */ + if (chpass) + pam_error (pamh, _("Password change aborted.")); return PAM_AUTHTOK_ERR; } -- cgit v1.2.1 From 0698382cf55ad79d0d591fad9609c68eabfac2a2 Mon Sep 17 00:00:00 2001 From: Thorsten Kukuk Date: Tue, 24 Mar 2015 13:03:06 +0100 Subject: Adjust documentation (Ticket#36) * libpam/pam_delay.c: Change 25% in comment to 50% as used in code. * doc/man/pam_fail_delay.3.xml: Change 25% to 50% --- libpam/pam_delay.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libpam') diff --git a/libpam/pam_delay.c b/libpam/pam_delay.c index cb6c9d5c..972e72b6 100644 --- a/libpam/pam_delay.c +++ b/libpam/pam_delay.c @@ -81,7 +81,7 @@ static unsigned int _pam_compute_delay(unsigned int seed, unsigned int base) /* ********************************************************************** * the following function sleeps for a random time. The actual time * slept is computed above.. It is based on the requested time but will - * differ by up to +/- 25%. + * differ by up to +/- 50%. */ void _pam_await_timer(pam_handle_t *pamh, int status) -- cgit v1.2.1 From 10b83ef224a5e9c3e2663b3f08dd17090acc58ab Mon Sep 17 00:00:00 2001 From: Thorsten Kukuk Date: Wed, 25 Mar 2015 15:00:38 +0100 Subject: Support alternative "vendor configuration" files as fallback to /etc (Ticket#34, patch from ay Sievers ) * doc/man/pam.8.xml: document additonal config directory * libpam/pam_handlers.c: add /usr/lib/pam.d as config file fallback directory * libpam/pam_private.h: adjust defines --- libpam/pam_handlers.c | 124 +++++++++++++++++++++++++++++++++----------------- libpam/pam_private.h | 9 ++-- 2 files changed, 87 insertions(+), 46 deletions(-) (limited to 'libpam') diff --git a/libpam/pam_handlers.c b/libpam/pam_handlers.c index df3a1d91..bc3fd9d8 100644 --- a/libpam/pam_handlers.c +++ b/libpam/pam_handlers.c @@ -274,6 +274,66 @@ static int _pam_parse_conf_file(pam_handle_t *pamh, FILE *f return ( (x < 0) ? PAM_ABORT:PAM_SUCCESS ); } +static int +_pam_open_config_file(pam_handle_t *pamh + , const char *service + , char **path + , FILE **file) +{ + char *p; + FILE *f; + int err = 0; + + /* Absolute path */ + if (service[0] == '/') { + p = _pam_strdup(service); + if (p == NULL) { + pam_syslog(pamh, LOG_CRIT, "strdup failed"); + return PAM_BUF_ERR; + } + + f = fopen(service, "r"); + if (f != NULL) { + *path = p; + *file = f; + return PAM_SUCCESS; + } + + _pam_drop(p); + return PAM_ABORT; + } + + /* Local Machine Configuration /etc/pam.d/ */ + if (asprintf (&p, PAM_CONFIG_DF, service) < 0) { + pam_syslog(pamh, LOG_CRIT, "asprintf failed"); + return PAM_BUF_ERR; + } + D(("opening %s", p)); + f = fopen(p, "r"); + if (f != NULL) { + *path = p; + *file = f; + return PAM_SUCCESS; + } + + /* System Configuration /usr/lib/pam.d/ */ + _pam_drop(p); + if (asprintf (&p, PAM_CONFIG_DIST_DF, service) < 0) { + pam_syslog(pamh, LOG_CRIT, "asprintf failed"); + return PAM_BUF_ERR; + } + D(("opening %s", p)); + f = fopen(p, "r"); + if (f != NULL) { + *path = p; + *file = f; + return PAM_SUCCESS; + } + _pam_drop(p); + + return PAM_ABORT; +} + static int _pam_load_conf_file(pam_handle_t *pamh, const char *config_name , const char *service /* specific file */ , int module_type /* specific type */ @@ -284,7 +344,7 @@ static int _pam_load_conf_file(pam_handle_t *pamh, const char *config_name ) { FILE *f; - char *config_path = NULL; + char *path = NULL; int retval = PAM_ABORT; D(("_pam_load_conf_file called")); @@ -297,39 +357,29 @@ static int _pam_load_conf_file(pam_handle_t *pamh, const char *config_name if (config_name == NULL) { D(("no config file supplied")); - pam_syslog(pamh, LOG_ERR, "(%s) no config file supplied", service); + pam_syslog(pamh, LOG_ERR, "(%s) no config name supplied", service); return PAM_ABORT; } - if (config_name[0] != '/') { - if (asprintf (&config_path, PAM_CONFIG_DF, config_name) < 0) { - pam_syslog(pamh, LOG_CRIT, "asprintf failed"); - return PAM_BUF_ERR; - } - config_name = config_path; - } - - D(("opening %s", config_name)); - f = fopen(config_name, "r"); - if (f != NULL) { + if (_pam_open_config_file(pamh, config_name, &path, &f) == PAM_SUCCESS) { retval = _pam_parse_conf_file(pamh, f, service, module_type, stack_level #ifdef PAM_READ_BOTH_CONFS , not_other #endif /* PAM_READ_BOTH_CONFS */ ); - fclose(f); if (retval != PAM_SUCCESS) pam_syslog(pamh, LOG_ERR, "_pam_load_conf_file: error reading %s: %s", - config_name, pam_strerror(pamh, retval)); + path, pam_strerror(pamh, retval)); + _pam_drop(path); + fclose(f); } else { D(("unable to open %s", config_name)); pam_syslog(pamh, LOG_ERR, - "_pam_load_conf_file: unable to open %s", + "_pam_load_conf_file: unable to open config for %s", config_name); } - _pam_drop(config_path); return retval; } @@ -396,39 +446,31 @@ int _pam_init_handlers(pam_handle_t *pamh) struct stat test_d; /* Is there a PAM_CONFIG_D directory? */ - if ( stat(PAM_CONFIG_D, &test_d) == 0 && S_ISDIR(test_d.st_mode) ) { - char *filename; + if ((stat(PAM_CONFIG_D, &test_d) == 0 && S_ISDIR(test_d.st_mode)) || + (stat(PAM_CONFIG_DIST_D, &test_d) == 0 && S_ISDIR(test_d.st_mode))) { + char *path = NULL; int read_something=0; - D(("searching " PAM_CONFIG_D " for config files")); - if (asprintf(&filename, PAM_CONFIG_DF, pamh->service_name) < 0) { - pam_syslog(pamh, LOG_ERR, - "_pam_init_handlers: no memory; service %s", - pamh->service_name); - return PAM_BUF_ERR; - } - D(("opening %s", filename)); - f = fopen(filename, "r"); - if (f != NULL) { - /* would test magic here? */ + if (_pam_open_config_file(pamh, pamh->service_name, &path, &f) == PAM_SUCCESS) { retval = _pam_parse_conf_file(pamh, f, pamh->service_name, PAM_T_ANY, 0 #ifdef PAM_READ_BOTH_CONFS , 0 #endif /* PAM_READ_BOTH_CONFS */ ); - fclose(f); if (retval != PAM_SUCCESS) { pam_syslog(pamh, LOG_ERR, "_pam_init_handlers: error reading %s", - filename); + path); pam_syslog(pamh, LOG_ERR, "_pam_init_handlers: [%s]", pam_strerror(pamh, retval)); } else { read_something = 1; } + _pam_drop(path); + fclose(f); } else { - D(("unable to open %s", filename)); + D(("unable to open configuration for %s", pamh->service_name)); #ifdef PAM_READ_BOTH_CONFS D(("checking %s", PAM_CONFIG)); @@ -443,14 +485,11 @@ int _pam_init_handlers(pam_handle_t *pamh) * use "other" */ } - _pam_drop(filename); if (retval == PAM_SUCCESS) { - /* now parse the PAM_DEFAULT_SERVICE_FILE */ + /* now parse the PAM_DEFAULT_SERVICE */ - D(("opening %s", PAM_DEFAULT_SERVICE_FILE)); - f = fopen(PAM_DEFAULT_SERVICE_FILE, "r"); - if (f != NULL) { + if (_pam_open_config_file(pamh, PAM_DEFAULT_SERVICE, &path, &f) == PAM_SUCCESS) { /* would test magic here? */ retval = _pam_parse_conf_file(pamh, f, PAM_DEFAULT_SERVICE, PAM_T_ANY, 0 @@ -458,22 +497,23 @@ int _pam_init_handlers(pam_handle_t *pamh) , 0 #endif /* PAM_READ_BOTH_CONFS */ ); - fclose(f); if (retval != PAM_SUCCESS) { pam_syslog(pamh, LOG_ERR, "_pam_init_handlers: error reading %s", - PAM_DEFAULT_SERVICE_FILE); + path); pam_syslog(pamh, LOG_ERR, "_pam_init_handlers: [%s]", pam_strerror(pamh, retval)); } else { read_something = 1; } + _pam_drop(path); + fclose(f); } else { - D(("unable to open %s", PAM_DEFAULT_SERVICE_FILE)); + D(("unable to open %s", PAM_DEFAULT_SERVICE)); pam_syslog(pamh, LOG_ERR, "_pam_init_handlers: no default config %s", - PAM_DEFAULT_SERVICE_FILE); + PAM_DEFAULT_SERVICE); } if (!read_something) { /* nothing read successfully */ retval = PAM_ABORT; diff --git a/libpam/pam_private.h b/libpam/pam_private.h index d93283ce..11382774 100644 --- a/libpam/pam_private.h +++ b/libpam/pam_private.h @@ -24,12 +24,13 @@ /* the Linux-PAM configuration file */ -#define PAM_CONFIG "/etc/pam.conf" -#define PAM_CONFIG_D "/etc/pam.d" -#define PAM_CONFIG_DF "/etc/pam.d/%s" +#define PAM_CONFIG "/etc/pam.conf" +#define PAM_CONFIG_D "/etc/pam.d" +#define PAM_CONFIG_DF "/etc/pam.d/%s" +#define PAM_CONFIG_DIST_D "/usr/lib/pam.d" +#define PAM_CONFIG_DIST_DF "/usr/lib/pam.d/%s" #define PAM_DEFAULT_SERVICE "other" /* lower case */ -#define PAM_DEFAULT_SERVICE_FILE PAM_CONFIG_D "/" PAM_DEFAULT_SERVICE #ifdef PAM_LOCKING /* -- cgit v1.2.1 From 8b4fa62e67bb0368af797ea0e2eb622209106af0 Mon Sep 17 00:00:00 2001 From: Thorsten Kukuk Date: Mon, 27 Apr 2015 16:50:32 +0200 Subject: Release version 1.2.0 * NEWS: Update * configure.ac: Bump version * libpam/Makefile.am: Bump version of libpam * libpam_misc/Makefile.am: Bump version of libpam_misc * po/*: Regenerate po files --- libpam/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libpam') diff --git a/libpam/Makefile.am b/libpam/Makefile.am index 685a797d..ac2a1fbf 100644 --- a/libpam/Makefile.am +++ b/libpam/Makefile.am @@ -20,7 +20,7 @@ include_HEADERS = include/security/_pam_compat.h \ noinst_HEADERS = pam_prelude.h pam_private.h pam_tokens.h \ pam_modutil_private.h pam_static_modules.h -libpam_la_LDFLAGS = -no-undefined -version-info 83:1:83 +libpam_la_LDFLAGS = -no-undefined -version-info 84:1:84 libpam_la_LIBADD = @LIBAUDIT@ $(LIBPRELUDE_LIBS) @LIBDL@ if STATIC_MODULES -- cgit v1.2.1 From 20047e7fdcfff6633d8201f0954be51f6378f1ae Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Thu, 17 Dec 2015 17:43:27 +0100 Subject: Relax the conditions for fatal failure on auditing. The PAM library calls will not fail anymore for any uid if the return value from the libaudit call is -EPERM. * libpam/pam_audit.c (_pam_audit_writelog): Remove check for uid != 0. --- libpam/pam_audit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libpam') diff --git a/libpam/pam_audit.c b/libpam/pam_audit.c index 24fb799a..97a9a929 100644 --- a/libpam/pam_audit.c +++ b/libpam/pam_audit.c @@ -53,7 +53,7 @@ _pam_audit_writelog(pam_handle_t *pamh, int audit_fd, int type, pamh->audit_state |= PAMAUDIT_LOGGED; if (rc < 0) { - if (rc == -EPERM && getuid() != 0) + if (rc == -EPERM) return 0; if (errno != old_errno) { old_errno = errno; -- cgit v1.2.1 From a684595c0bbd88df71285f43fb27630e3829121e Mon Sep 17 00:00:00 2001 From: Thorsten Kukuk Date: Tue, 29 Mar 2016 14:14:03 +0200 Subject: Remove "--enable-static-modules" option and support from Linux-PAM. It was never official supported and was broken since years. * configure.ac: Remove --enable-static-modules option. * doc/man/pam_sm_acct_mgmt.3.xml: Remove PAM_EXTERN. * doc/man/pam_sm_authenticate.3.xml: Likewise. * doc/man/pam_sm_chauthtok.3.xml: Likewise. * doc/man/pam_sm_close_session.3.xml: Likewise. * doc/man/pam_sm_open_session.3.xml: Likewise. * doc/man/pam_sm_setcred.3.xml: Likewise. * libpam/Makefile.am: Remove STATIC_MODULES cases. * libpam/include/security/pam_modules.h: Remove PAM_STATIC parts. * libpam/pam_dynamic.c: Likewise. * libpam/pam_handlers.c: Likewise. * libpam/pam_private.h: Likewise. * libpam/pam_static.c: Remove file. * libpam/pam_static_modules.h: Remove header file. * modules/pam_access/pam_access.c: Remove PAM_EXTERN and PAM_STATIC parts. * modules/pam_cracklib/pam_cracklib.c: Likewise. * modules/pam_debug/pam_debug.c: Likewise. * modules/pam_deny/pam_deny.c: Likewise. * modules/pam_echo/pam_echo.c: Likewise. * modules/pam_env/pam_env.c: Likewise. * modules/pam_exec/pam_exec.c: Likewise. * modules/pam_faildelay/pam_faildelay.c: Likewise. * modules/pam_filter/pam_filter.c: Likewise. * modules/pam_ftp/pam_ftp.c: Likewise. * modules/pam_group/pam_group.c: Likewise. * modules/pam_issue/pam_issue.c: Likewise. * modules/pam_keyinit/pam_keyinit.c: Likewise. * modules/pam_lastlog/pam_lastlog.c: Likewise. * modules/pam_limits/pam_limits.c: Likewise. * modules/pam_listfile/pam_listfile.c: Likewise. * modules/pam_localuser/pam_localuser.c: Likewise. * modules/pam_loginuid/pam_loginuid.c: Likewise. * modules/pam_mail/pam_mail.c: Likewise. * modules/pam_mkhomedir/pam_mkhomedir.c: Likewise. * modules/pam_motd/pam_motd.c: Likewise. * modules/pam_namespace/pam_namespace.c: Likewise. * modules/pam_nologin/pam_nologin.c: Likewise. * modules/pam_permit/pam_permit.c: Likewise. * modules/pam_pwhistory/pam_pwhistory.c: Likewise. * modules/pam_rhosts/pam_rhosts.c: Likewise. * modules/pam_rootok/pam_rootok.c: Likewise. * modules/pam_securetty/pam_securetty.c: Likewise. * modules/pam_selinux/pam_selinux.c: Likewise. * modules/pam_sepermit/pam_sepermit.c: Likewise. * modules/pam_shells/pam_shells.c: Likewise. * modules/pam_stress/pam_stress.c: Likewise. * modules/pam_succeed_if/pam_succeed_if.c: Likewise. * modules/pam_tally/pam_tally.c: Likewise. * modules/pam_tally2/pam_tally2.c: Likewise. * modules/pam_time/pam_time.c: Likewise. * modules/pam_timestamp/pam_timestamp.c: Likewise. * modules/pam_tty_audit/pam_tty_audit.c: Likewise. * modules/pam_umask/pam_umask.c: Likewise. * modules/pam_userdb/pam_userdb.c: Likewise. * modules/pam_warn/pam_warn.c: Likewise. * modules/pam_wheel/pam_wheel.c: Likewise. * modules/pam_xauth/pam_xauth.c: Likewise. * modules/pam_unix/Makefile.am: Remove STATIC_MODULES part. * modules/pam_unix/pam_unix_acct.c: Remove PAM_STATIC part. * modules/pam_unix/pam_unix_auth.c: Likewise. * modules/pam_unix/pam_unix_passwd.c: Likewise. * modules/pam_unix/pam_unix_sess.c: Likewise. * modules/pam_unix/pam_unix_static.c: Removed. * modules/pam_unix/pam_unix_static.h: Removed. * po/POTFILES.in: Remove removed files. * tests/tst-dlopen.c: Remove PAM_STATIC part. --- libpam/Makefile.am | 9 +-- libpam/include/security/pam_modules.h | 78 +++--------------- libpam/pam_dynamic.c | 3 - libpam/pam_handlers.c | 53 +----------- libpam/pam_private.h | 12 --- libpam/pam_static.c | 127 ----------------------------- libpam/pam_static_modules.h | 148 ---------------------------------- 7 files changed, 16 insertions(+), 414 deletions(-) delete mode 100644 libpam/pam_static.c delete mode 100644 libpam/pam_static_modules.h (limited to 'libpam') diff --git a/libpam/Makefile.am b/libpam/Makefile.am index ac2a1fbf..04a8df0f 100644 --- a/libpam/Makefile.am +++ b/libpam/Makefile.am @@ -18,16 +18,11 @@ include_HEADERS = include/security/_pam_compat.h \ include/security/pam_ext.h include/security/pam_modutil.h noinst_HEADERS = pam_prelude.h pam_private.h pam_tokens.h \ - pam_modutil_private.h pam_static_modules.h + pam_modutil_private.h libpam_la_LDFLAGS = -no-undefined -version-info 84:1:84 libpam_la_LIBADD = @LIBAUDIT@ $(LIBPRELUDE_LIBS) @LIBDL@ -if STATIC_MODULES - libpam_la_LIBADD += $(shell ls ../modules/pam_*/*.lo) \ - @LIBDB@ @LIBCRYPT@ $(NIS_LIBS) @LIBCRACK@ -lutil - AM_CFLAGS += $(NIS_CFLAGS) -endif if HAVE_VERSIONING libpam_la_LDFLAGS += -Wl,--version-script=$(srcdir)/libpam.map endif @@ -38,7 +33,7 @@ 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 \ pam_handlers.c pam_item.c \ pam_misc.c pam_password.c pam_prelude.c \ - pam_session.c pam_start.c pam_static.c pam_strerror.c \ + pam_session.c pam_start.c pam_strerror.c \ pam_vprompt.c pam_syslog.c pam_dynamic.c pam_audit.c \ pam_modutil_cleanup.c pam_modutil_getpwnam.c pam_modutil_ioloop.c \ pam_modutil_getgrgid.c pam_modutil_getpwuid.c pam_modutil_getgrnam.c \ diff --git a/libpam/include/security/pam_modules.h b/libpam/include/security/pam_modules.h index 5c516c4e..37568e99 100644 --- a/libpam/include/security/pam_modules.h +++ b/libpam/include/security/pam_modules.h @@ -30,80 +30,26 @@ pam_get_data(const pam_handle_t *pamh, const char *module_data_name, extern int PAM_NONNULL((1,2)) pam_get_user(pam_handle_t *pamh, const char **user, const char *prompt); -#ifdef PAM_STATIC - -#define PAM_EXTERN static - -struct pam_module { - const char *name; /* Name of the module */ - - /* These are function pointers to the module's key functions. */ - - int (*pam_sm_authenticate)(pam_handle_t *pamh, int flags, - int argc, const char **argv); - int (*pam_sm_setcred)(pam_handle_t *pamh, int flags, - int argc, const char **argv); - int (*pam_sm_acct_mgmt)(pam_handle_t *pamh, int flags, - int argc, const char **argv); - int (*pam_sm_open_session)(pam_handle_t *pamh, int flags, - int argc, const char **argv); - int (*pam_sm_close_session)(pam_handle_t *pamh, int flags, - int argc, const char **argv); - int (*pam_sm_chauthtok)(pam_handle_t *pamh, int flags, - int argc, const char **argv); -}; - -#else /* !PAM_STATIC */ - -#define PAM_EXTERN extern - -#endif /* PAM_STATIC */ - -/* Lots of files include pam_modules.h that don't need these - * declared. However, when they are declared static, they - * need to be defined later. So we have to protect C files - * that include these without wanting these functions defined.. */ - -#if (defined(PAM_STATIC) && defined(PAM_SM_AUTH)) || !defined(PAM_STATIC) - /* Authentication API's */ -PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, - int argc, const char **argv); -PAM_EXTERN int pam_sm_setcred(pam_handle_t *pamh, int flags, - int argc, const char **argv); - -#endif /*(defined(PAM_STATIC) && defined(PAM_SM_AUTH)) - || !defined(PAM_STATIC)*/ - -#if (defined(PAM_STATIC) && defined(PAM_SM_ACCOUNT)) || !defined(PAM_STATIC) +int pam_sm_authenticate(pam_handle_t *pamh, int flags, + int argc, const char **argv); +int pam_sm_setcred(pam_handle_t *pamh, int flags, + int argc, const char **argv); /* Account Management API's */ -PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, - int argc, const char **argv); - -#endif /*(defined(PAM_STATIC) && defined(PAM_SM_ACCOUNT)) - || !defined(PAM_STATIC)*/ - -#if (defined(PAM_STATIC) && defined(PAM_SM_SESSION)) || !defined(PAM_STATIC) +int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, + int argc, const char **argv); /* Session Management API's */ -PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags, - int argc, const char **argv); - -PAM_EXTERN int pam_sm_close_session(pam_handle_t *pamh, int flags, - int argc, const char **argv); +int pam_sm_open_session(pam_handle_t *pamh, int flags, + int argc, const char **argv); -#endif /*(defined(PAM_STATIC) && defined(PAM_SM_SESSION)) - || !defined(PAM_STATIC)*/ - -#if (defined(PAM_STATIC) && defined(PAM_SM_PASSWORD)) || !defined(PAM_STATIC) +int pam_sm_close_session(pam_handle_t *pamh, int flags, + int argc, const char **argv); /* Password Management API's */ -PAM_EXTERN int pam_sm_chauthtok(pam_handle_t *pamh, int flags, - int argc, const char **argv); - -#endif /*(defined(PAM_STATIC) && defined(PAM_SM_PASSWORD)) - || !defined(PAM_STATIC)*/ +int pam_sm_chauthtok(pam_handle_t *pamh, int flags, + int argc, const char **argv); /* The following two flags are for use across the Linux-PAM/module * interface only. The Application is not permitted to use these diff --git a/libpam/pam_dynamic.c b/libpam/pam_dynamic.c index e1155e50..50bfd792 100644 --- a/libpam/pam_dynamic.c +++ b/libpam/pam_dynamic.c @@ -33,8 +33,6 @@ #include "pam_private.h" -#ifndef PAM_STATIC - #ifdef PAM_SHL # include #elif defined(PAM_DYLD) @@ -139,4 +137,3 @@ _pam_dlerror (void) #endif } -#endif diff --git a/libpam/pam_handlers.c b/libpam/pam_handlers.c index bc3fd9d8..91cccadc 100644 --- a/libpam/pam_handlers.c +++ b/libpam/pam_handlers.c @@ -665,9 +665,7 @@ _pam_load_module(pam_handle_t *pamh, const char *mod_path, int handler_type) { int x = 0; int success; -#ifndef PAM_STATIC char *mod_full_isa_path=NULL, *isa=NULL; -#endif struct loaded_module *mod; D(("_pam_load_module: loading module `%s'", mod_path)); @@ -701,27 +699,6 @@ _pam_load_module(pam_handle_t *pamh, const char *mod_path, int handler_type) /* Be pessimistic... */ success = PAM_ABORT; -#ifdef PAM_STATIC - /* Only load static function if function was not found dynamically. - * This code should work even if no dynamic loading is available. */ - if (success != PAM_SUCCESS) { - D(("_pam_load_module: open static handler %s", mod_path)); - mod->dl_handle = _pam_open_static_handler(pamh, mod_path); - if (mod->dl_handle == NULL) { - D(("_pam_load_module: unable to find static handler %s", - mod_path)); - if (handler_type != PAM_HT_SILENT_MODULE) - pam_syslog(pamh, LOG_ERR, - "unable to open static handler %s", mod_path); - /* Didn't find module in dynamic or static..will mark bad */ - } else { - D(("static module added successfully")); - success = PAM_SUCCESS; - mod->type = PAM_MT_STATIC_MOD; - pamh->handlers.modules_used++; - } - } -#else D(("_pam_load_module: _pam_dlopen(%s)", mod_path)); mod->dl_handle = _pam_dlopen(mod_path); D(("_pam_load_module: _pam_dlopen'ed")); @@ -758,7 +735,6 @@ _pam_load_module(pam_handle_t *pamh, const char *mod_path, int handler_type) mod->type = PAM_MT_DYNAMIC_MOD; pamh->handlers.modules_used++; } -#endif if (success != PAM_SUCCESS) { /* add a malformed module */ mod->dl_handle = NULL; @@ -869,16 +845,8 @@ int _pam_add_handler(pam_handle_t *pamh } /* are the modules reliable? */ - if ( -#ifdef PAM_STATIC - mod_type != PAM_MT_STATIC_MOD - && -#else - mod_type != PAM_MT_DYNAMIC_MOD - && -#endif - mod_type != PAM_MT_FAULTY_MOD - ) { + if (mod_type != PAM_MT_DYNAMIC_MOD && + mod_type != PAM_MT_FAULTY_MOD) { D(("_pam_add_handlers: illegal module library type; %d", mod_type)); pam_syslog(pamh, LOG_ERR, "internal error: module library type not known: %s;%d", @@ -888,30 +856,15 @@ int _pam_add_handler(pam_handle_t *pamh /* now identify this module's functions - for non-faulty modules */ -#ifdef PAM_STATIC - if ((mod_type == PAM_MT_STATIC_MOD) && - (func = (servicefn)_pam_get_static_sym(mod->dl_handle, sym)) == NULL) { - pam_syslog(pamh, LOG_ERR, "unable to resolve static symbol: %s", sym); - } -#else if ((mod_type == PAM_MT_DYNAMIC_MOD) && !(func = _pam_dlsym(mod->dl_handle, sym)) ) { pam_syslog(pamh, LOG_ERR, "unable to resolve symbol: %s", sym); } -#endif if (sym2) { -#ifdef PAM_STATIC - if ((mod_type == PAM_MT_STATIC_MOD) && - (func2 = (servicefn)_pam_get_static_sym(mod->dl_handle, sym2)) - == NULL) { - pam_syslog(pamh, LOG_ERR, "unable to resolve symbol: %s", sym2); - } -#else if ((mod_type == PAM_MT_DYNAMIC_MOD) && !(func2 = _pam_dlsym(mod->dl_handle, sym2)) ) { pam_syslog(pamh, LOG_ERR, "unable to resolve symbol: %s", sym2); } -#endif } /* here func (and perhaps func2) point to the appropriate functions */ @@ -994,11 +947,9 @@ int _pam_free_handlers(pam_handle_t *pamh) while (pamh->handlers.modules_used) { D(("_pam_free_handlers: dlclose(%s)", mod->name)); free(mod->name); -#ifndef PAM_STATIC if (mod->type == PAM_MT_DYNAMIC_MOD) { _pam_dlclose(mod->dl_handle); } -#endif mod++; pamh->handlers.modules_used--; } diff --git a/libpam/pam_private.h b/libpam/pam_private.h index 11382774..7ff9f758 100644 --- a/libpam/pam_private.h +++ b/libpam/pam_private.h @@ -241,22 +241,10 @@ void _pam_await_timer(pam_handle_t *pamh, int status); typedef void (*voidfunc(void))(void); typedef int (*servicefn)(pam_handle_t *, int, int, char **); -#ifdef PAM_STATIC -/* The next two in ../modules/_pam_static/pam_static.c */ - -/* Return pointer to data structure used to define a static module */ -struct pam_module * _pam_open_static_handler (pam_handle_t *pamh, - const char *path); - -/* Return pointer to function requested from static module */ - -voidfunc *_pam_get_static_sym(struct pam_module *mod, const char *symname); -#else void *_pam_dlopen (const char *mod_path); servicefn _pam_dlsym (void *handle, const char *symbol); void _pam_dlclose (void *handle); const char *_pam_dlerror (void); -#endif /* For now we just use a stack and linear search for module data. */ /* If it becomes apparent that there is a lot of data, it should */ diff --git a/libpam/pam_static.c b/libpam/pam_static.c deleted file mode 100644 index 511026d4..00000000 --- a/libpam/pam_static.c +++ /dev/null @@ -1,127 +0,0 @@ -/* - * pam_static.c -- static module loading helper functions - * - * created by Michael K. Johnson, johnsonm@redhat.com - */ - -/* This whole file is only used for PAM_STATIC */ - -#ifdef PAM_STATIC - -#include -#include -#include - -#include "pam_private.h" - -#include "pam_static_modules.h" - -/* - * and now for the functions - */ - -/* Return pointer to data structure used to define a static module */ -struct pam_module * -_pam_open_static_handler (pam_handle_t *pamh, const char *path) -{ - int i; - const char *clpath = path; - char *lpath, *end; - - if (strchr(clpath, '/')) { - /* ignore path and leading "/" */ - clpath = strrchr(path, '/') + 1; - } - /* create copy to muck with (must free before return) */ - lpath = _pam_strdup(clpath); - /* chop .so off copy if it exists (or other extension on other - platform...) */ - end = strstr(lpath, ".so"); - if (end) { - *end = '\0'; - } - - /* now go find the module */ - for (i = 0; static_modules[i] != NULL; i++) { - D(("%s=?%s\n", lpath, static_modules[i]->name)); - if (static_modules[i]->name && - ! strcmp(static_modules[i]->name, lpath)) { - break; - } - } - - if (static_modules[i] == NULL) { - pam_syslog (pamh, LOG_ERR, "no static module named %s", lpath); - } - - free(lpath); - return (static_modules[i]); -} - -/* Return pointer to function requested from static module - * Can't just return void *, because ANSI C disallows casting a - * pointer to a function to a void *... - * This definition means: - * _pam_get_static_sym is a function taking two arguments and - * returning a pointer to a function which takes no arguments - * and returns void... */ -voidfunc *_pam_get_static_sym(struct pam_module *mod, const char *symname) { - - if (! strcmp(symname, "pam_sm_authenticate")) { - return ((voidfunc *)mod->pam_sm_authenticate); - } else if (! strcmp(symname, "pam_sm_setcred")) { - return ((voidfunc *)mod->pam_sm_setcred); - } else if (! strcmp(symname, "pam_sm_acct_mgmt")) { - return ((voidfunc *)mod->pam_sm_acct_mgmt); - } else if (! strcmp(symname, "pam_sm_open_session")) { - return ((voidfunc *)mod->pam_sm_open_session); - } else if (! strcmp(symname, "pam_sm_close_session")) { - return ((voidfunc *)mod->pam_sm_close_session); - } else if (! strcmp(symname, "pam_sm_chauthtok")) { - return ((voidfunc *)mod->pam_sm_chauthtok); - } - /* getting to this point is an error */ - return ((voidfunc *)NULL); -} - -#else /* ! PAM_STATIC */ - -typedef int blarg; - -#endif /* ! PAM_STATIC */ - -/* - * Copyright (C) 1995 by Red Hat Software, Michael K. Johnson - * All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, and the entire permission notice in its entirety, - * including the disclaimer of warranties. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * ALTERNATIVELY, this product may be distributed under the terms of - * the GNU Public License, in which case the provisions of the GPL are - * required INSTEAD OF the above restrictions. (This clause is - * necessary due to a potential bad interaction between the GPL and - * the restrictions contained in a BSD-style copyright.) - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ diff --git a/libpam/pam_static_modules.h b/libpam/pam_static_modules.h deleted file mode 100644 index 698989bd..00000000 --- a/libpam/pam_static_modules.h +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, and the entire permission notice in its entirety, - * including the disclaimer of warranties. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * ALTERNATIVELY, this product may be distributed under the terms of - * the GNU Public License, in which case the provisions of the GPL are - * required INSTEAD OF the above restrictions. (This clause is - * necessary due to a potential bad interaction between the GPL and - * the restrictions contained in a BSD-style copyright.) - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* Pointers to static module data. */ - -extern struct pam_module _pam_access_modstruct; -extern struct pam_module _pam_cracklib_modstruct; -extern struct pam_module _pam_debug_modstruct; -extern struct pam_module _pam_deny_modstruct; -extern struct pam_module _pam_echo_modstruct; -extern struct pam_module _pam_env_modstruct; -extern struct pam_module _pam_exec_modstruct; -extern struct pam_module _pam_faildelay_modstruct; -extern struct pam_module _pam_filter_modstruct; -extern struct pam_module _pam_ftp_modstruct; -extern struct pam_module _pam_group_modstruct; -extern struct pam_module _pam_issue_modstruct; -#ifdef HAVE_KEY_MANAGEMENT -extern struct pam_module _pam_keyinit_modstruct; -#endif -extern struct pam_module _pam_lastlog_modstruct; -extern struct pam_module _pam_limits_modstruct; -extern struct pam_module _pam_listfile_modstruct; -extern struct pam_module _pam_localuser_modstruct; -extern struct pam_module _pam_loginuid_modstruct; -extern struct pam_module _pam_mail_modstruct; -extern struct pam_module _pam_mkhomedir_modstruct; -extern struct pam_module _pam_motd_modstruct; -#ifdef HAVE_UNSHARE -extern struct pam_module _pam_namespace_modstruct; -#endif -extern struct pam_module _pam_nologin_modstruct; -extern struct pam_module _pam_permit_modstruct; -extern struct pam_module _pam_pwhistory_modstruct; -extern struct pam_module _pam_rhosts_modstruct; -extern struct pam_module _pam_rootok_modstruct; -extern struct pam_module _pam_securetty_modstruct; -#ifdef WITH_SELINUX -extern struct pam_module _pam_selinux_modstruct; -extern struct pam_module _pam_sepermit_modstruct; -#endif -extern struct pam_module _pam_shells_modstruct; -extern struct pam_module _pam_stress_modstruct; -extern struct pam_module _pam_succeed_if_modstruct; -extern struct pam_module _pam_tally_modstruct; -extern struct pam_module _pam_tally2_modstruct; -extern struct pam_module _pam_time_modstruct; -extern struct pam_module _pam_timestamp_modstruct; -#ifdef HAVE_AUDIT_TTY_STATUS -extern struct pam_module _pam_tty_audit_modstruct; -#endif -extern struct pam_module _pam_umask_modstruct; -extern struct pam_module _pam_unix_modstruct; -extern struct pam_module _pam_userdb_modstruct; -extern struct pam_module _pam_warn_modstruct; -extern struct pam_module _pam_wheel_modstruct; -extern struct pam_module _pam_xauth_modstruct; - -/* and here is a structure that connects libpam to the above static - modules. */ - -static struct pam_module *static_modules[] = { - &_pam_access_modstruct, -#ifdef HAVE_LIBCRACK - &_pam_cracklib_modstruct, -#endif - &_pam_debug_modstruct, - &_pam_deny_modstruct, - &_pam_echo_modstruct, - &_pam_env_modstruct, - &_pam_exec_modstruct, - &_pam_faildelay_modstruct, - &_pam_filter_modstruct, - &_pam_ftp_modstruct, - &_pam_group_modstruct, - &_pam_issue_modstruct, -#ifdef HAVE_KEY_MANAGEMENT - &_pam_keyinit_modstruct, -#endif - &_pam_lastlog_modstruct, - &_pam_limits_modstruct, - &_pam_listfile_modstruct, - &_pam_localuser_modstruct, - &_pam_loginuid_modstruct, - &_pam_mail_modstruct, - &_pam_mkhomedir_modstruct, - &_pam_motd_modstruct, -#ifdef HAVE_UNSHARE - &_pam_namespace_modstruct, -#endif - &_pam_nologin_modstruct, - &_pam_permit_modstruct, - &_pam_pwhistory_modstruct, - &_pam_rhosts_modstruct, - &_pam_rootok_modstruct, - &_pam_securetty_modstruct, -#ifdef WITH_SELINUX - &_pam_selinux_modstruct, - &_pam_sepermit_modstruct, -#endif - &_pam_shells_modstruct, - &_pam_stress_modstruct, - &_pam_succeed_if_modstruct, - &_pam_tally_modstruct, - &_pam_tally2_modstruct, - &_pam_time_modstruct, - &_pam_timestamp_modstruct, -#ifdef HAVE_AUDIT_TTY_STATUS - &_pam_tty_audit_modstruct, -#endif - &_pam_umask_modstruct, - &_pam_unix_modstruct, - &_pam_userdb_modstruct, - &_pam_warn_modstruct, - &_pam_wheel_modstruct, - &_pam_xauth_modstruct, - NULL -}; -- cgit v1.2.1 From 6b12a20c527cb6ced5b8911ea0f1dcdfc6e6f30c Mon Sep 17 00:00:00 2001 From: Thorsten Kukuk Date: Tue, 29 Mar 2016 14:17:34 +0200 Subject: PAM_EXTERN isn't needed anymore, but don't remove it to not break lot of external code using it. * libpam/include/security/pam_modules.h: Readd PAM_EXTERN for compatibility --- libpam/include/security/pam_modules.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'libpam') diff --git a/libpam/include/security/pam_modules.h b/libpam/include/security/pam_modules.h index 37568e99..ec65e3e9 100644 --- a/libpam/include/security/pam_modules.h +++ b/libpam/include/security/pam_modules.h @@ -75,6 +75,9 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags, #define PAM_DATA_REPLACE 0x20000000 /* used when replacing a data item */ +/* PAM_EXTERN isn't needed anymore, but don't remove it to not break + lot of external code using it. */ +#define PAM_EXTERN extern /* take care of any compatibility issues */ #include -- cgit v1.2.1 From df87fb69e44d024ce4a0a052c78b85d261e6c6a3 Mon Sep 17 00:00:00 2001 From: "Dmitry V. Levin" Date: Fri, 1 Apr 2016 17:07:44 +0000 Subject: Fix whitespace issues Remove blank lines at EOF introduced by commit a684595c0bbd88df71285f43fb27630e3829121e, making the project free of warnings reported by git diff --check 4b825dc642cb6eb9a060e54bf8d69288fbee4904 HEAD * libpam/pam_dynamic.c: Remove blank line at EOF. * modules/pam_echo/pam_echo.c: Likewise. * modules/pam_keyinit/pam_keyinit.c: Likewise. * modules/pam_mkhomedir/pam_mkhomedir.c: Likewise. * modules/pam_pwhistory/pam_pwhistory.c: Likewise. * modules/pam_rhosts/pam_rhosts.c: Likewise. * modules/pam_sepermit/pam_sepermit.c: Likewise. * modules/pam_stress/pam_stress.c: Likewise. --- libpam/pam_dynamic.c | 1 - 1 file changed, 1 deletion(-) (limited to 'libpam') diff --git a/libpam/pam_dynamic.c b/libpam/pam_dynamic.c index 50bfd792..c063083f 100644 --- a/libpam/pam_dynamic.c +++ b/libpam/pam_dynamic.c @@ -136,4 +136,3 @@ _pam_dlerror (void) return dlerror (); #endif } - -- cgit v1.2.1 From 3c4328635ade0cd7bc1fb9d5f145f4dff76f9c1b Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Wed, 6 Apr 2016 13:52:21 +0200 Subject: pam_get_authtok(): Add authtok_type support to current password prompt. * libpam/pam_get_authtok.c (pam_get_authtok_internal): When changing password, use different prompt for current password allowing for authtok_type to be displayed to the user. --- libpam/pam_get_authtok.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'libpam') diff --git a/libpam/pam_get_authtok.c b/libpam/pam_get_authtok.c index 663f1f36..9bfbdf0f 100644 --- a/libpam/pam_get_authtok.c +++ b/libpam/pam_get_authtok.c @@ -38,6 +38,8 @@ #define PROMPT _("Password: ") /* For Translators: "%s%s" could be replaced with " " or "". */ +#define PROMPTCURRENT _("Current %s%spassword: ") +/* For Translators: "%s%s" could be replaced with " " or "". */ #define PROMPT1 _("New %s%spassword: ") /* For Translators: "%s%s" could be replaced with " " or "". */ #define PROMPT2 _("Retype new %s%spassword: ") @@ -89,12 +91,14 @@ pam_get_authtok_internal (pam_handle_t *pamh, int item, /* PAM_AUTHTOK in password stack returns new password, which needs to be verified. */ - if (item == PAM_AUTHTOK && pamh->choice == PAM_CHAUTHTOK) + if (pamh->choice == PAM_CHAUTHTOK) { - chpass = 1; - if (!(flags & PAM_GETAUTHTOK_NOVERIFY)) - ++chpass; - + if (item == PAM_AUTHTOK) + { + chpass = 1; + if (!(flags & PAM_GETAUTHTOK_NOVERIFY)) + ++chpass; + } authtok_type = get_option (pamh, "authtok_type"); if (authtok_type == NULL) { @@ -144,6 +148,10 @@ pam_get_authtok_internal (pam_handle_t *pamh, int item, PROMPT2, authtok_type, strlen (authtok_type) > 0?" ":""); } + else if (item == PAM_OLDAUTHTOK) + retval = pam_prompt (pamh, PAM_PROMPT_ECHO_OFF, &resp[0], + PROMPTCURRENT, authtok_type, + strlen (authtok_type) > 0?" ":""); else retval = pam_prompt (pamh, PAM_PROMPT_ECHO_OFF, &resp[0], "%s", PROMPT); -- cgit v1.2.1 From 1cad9fb2a0d729c5b5e5aa7297c521df7d5a2d33 Mon Sep 17 00:00:00 2001 From: Thorsten Kukuk Date: Thu, 28 Apr 2016 13:54:30 +0200 Subject: Release version 1.3.0 * NEWS: add changes for 1.3.0. * configure.ac: bump version number. * libpam/Makefile.am: bump revision of libpam.so version. --- libpam/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libpam') diff --git a/libpam/Makefile.am b/libpam/Makefile.am index 04a8df0f..638bb5c4 100644 --- a/libpam/Makefile.am +++ b/libpam/Makefile.am @@ -20,7 +20,7 @@ include_HEADERS = include/security/_pam_compat.h \ noinst_HEADERS = pam_prelude.h pam_private.h pam_tokens.h \ pam_modutil_private.h -libpam_la_LDFLAGS = -no-undefined -version-info 84:1:84 +libpam_la_LDFLAGS = -no-undefined -version-info 84:2:84 libpam_la_LIBADD = @LIBAUDIT@ $(LIBPRELUDE_LIBS) @LIBDL@ if HAVE_VERSIONING -- cgit v1.2.1