]> granicus.if.org Git - linux-pam/commitdiff
Relevant BUGIDs: none
authorThorsten Kukuk <kukuk@thkukuk.de>
Sat, 3 Sep 2005 17:09:19 +0000 (17:09 +0000)
committerThorsten Kukuk <kukuk@thkukuk.de>
Sat, 3 Sep 2005 17:09:19 +0000 (17:09 +0000)
Purpose of commit: new feature

Commit summary:
---------------

Add pam_syslog to unify log messages from PAM modules.

12 files changed:
.cvsignore
CHANGELOG
configure.in
libpam/Makefile.am
libpam/include/security/pam_ext.h
libpam/libpam.map
libpam/pam_dispatch.c
libpam/pam_handlers.c
libpam/pam_private.h
libpam/pam_syslog.c [new file with mode: 0644]
libpam/pam_vprompt.c
modules/pam_warn/pam_warn.c

index 8537288d78e2c499b9de50749d775e515e40af55..672dcdfc1a9e41e12aa2d956895ead43dcfeca79 100644 (file)
@@ -2,6 +2,7 @@ default.defs
 .freezemake
 .filelist
 autom4te.cache
+libtool
 include
 config.h
 config.status
@@ -13,3 +14,4 @@ _pam_aconf.h
 Make.Rules
 Makefile
 Makefile.in
+stamp-h1
index ceceb822e9fb4dd6e9a3fef9f59d944165a9ebdc..bdecdb7874d2129e63337fcf5fe758fc65ad9e6a 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -83,6 +83,8 @@ BerliOS Bugs are marked with (BerliOS #XXXX).
 * libpam: Add pam_prompt,pam_vprompt,pam_error,pam_verror,pam_info
   and pam_vinfo functions for use by modules as extension (kukuk).
 * pam_cracklib: Make path to cracklib dicts an option (kukuk).
+* libpam: Add pam_syslog function for unified syslog messages from
+  PAM modules (kukuk).
 
 0.80: Wed Jul 13 13:23:20 CEST 2005
 * pam_tally: test for NULL data before dereferencing them (t8m)
index 4037cfb7d7abb44e83fb91203b3d5378267d2981..13ac073add766f4a3807f79e6574340a9664bd54 100644 (file)
@@ -287,6 +287,13 @@ LIBS=$BACKUP_LIBS
 AC_SUBST(LIBSELINUX)
 AM_CONDITIONAL([HAVE_LIBSELINUX], [test ! -z "$LIBSELINUX"])
 
+dnl Checks for Libcap
+BACKUP_LIBS=$LIBS
+AC_CHECK_LIB([cap], [cap_get_proc], LIBCAP="-lcap", LIBCAP="" )
+LIBS=$BACKUP_LIBS
+AC_SUBST(LIBCAP)
+AM_CONDITIONAL([HAVE_LIBCAP], [test ! -z "$LIBCAP"])
+
 BACKUP_LIBS=$LIBS
 AC_CHECK_LIB([pwdb],[pwdb_db_name], LIBPWDB="-lpwdb", LIBPWDB="")
 LIBS=$BACKUP_LIBS
index a9ebcf72825cbf5e8a1e98cb01c4955903863763..b6c3a6579d862fd587497b691f7705e9d275652a 100644 (file)
@@ -25,5 +25,5 @@ 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_handlers.c pam_item.c \
        pam_log.c pam_malloc.c pam_misc.c pam_password.c pam_prelude.c \
        pam_session.c pam_start.c pam_static.c pam_strerror.c \
-       pam_vprompt.c
+       pam_vprompt.c pam_syslog.c
 
index b461f2d0f0165e6d8ae71320818bbbf48220158e..754a83dd7500f5ca694244d69c6d7b55c0ce5123 100644 (file)
 #include <security/_pam_types.h>
 #include <stdarg.h>
 
-extern int PAM_FORMAT((printf, 4, 0)) PAM_NONNULL((4))
+extern void PAM_FORMAT((printf, 3, 0)) PAM_NONNULL((1,3))
+pam_vsyslog (pam_handle_t *pamh, int priority,
+             const char *fmt, va_list args);
+
+extern void PAM_FORMAT((printf, 3, 4)) PAM_NONNULL((1,3))
+pam_syslog (pam_handle_t *pamh, int priority, const char *fmt, ...);
+
+extern int PAM_FORMAT((printf, 4, 0)) PAM_NONNULL((1,4))
 pam_vprompt (pam_handle_t *pamh, int style, char **response,
             const char *fmt, va_list args);
 
-extern int PAM_FORMAT((printf, 4, 5)) PAM_NONNULL((4))
+extern int PAM_FORMAT((printf, 4, 5)) PAM_NONNULL((1,4))
 pam_prompt (pam_handle_t *pamh, int style, char **response,
            const char *fmt, ...);
 
-#define pam_error(pamh, fmt, args...) pam_prompt(pamh, PAM_ERROR_MSG, NULL, fmt, args)
-#define pam_verror(pamh, fmt, args) pam_vprompt(pamh, PAM_ERROR_MSG, NULL, fmt, args)
+#define pam_error(pamh, fmt, args...) \
+       pam_prompt(pamh, PAM_ERROR_MSG, NULL, fmt, args)
+#define pam_verror(pamh, fmt, args) \
+       pam_vprompt(pamh, PAM_ERROR_MSG, NULL, fmt, args)
 
 #define pam_info(pamh, fmt, args...) pam_prompt(pamh, PAM_TEXT_INFO, NULL, fmt, args)
 #define pam_vinfo(pamh, fmt, ...) pam_vprompt(pamh, PAM_TEXT_INFO, NULL, fmt, args)
index 75f8934937217d19aa6f5ecdadde86e9bd3a5042..515842ae474b07ed603684db9e1303c46e7ac752 100644 (file)
@@ -35,5 +35,7 @@ LIBPAM_EXTENSION_1.0 {
   global:
     pam_prompt;
     pam_vprompt;
+    pam_syslog;
+    pam_vsyslog;
 };
 
index 686c05ec290150f0a64ff5dd949021894c21c497..15d381a79225513f8256b62eb47dcdc44df61390 100644 (file)
@@ -80,7 +80,9 @@ static int _pam_dispatch_aux(pam_handle_t *pamh, int flags, struct handler *h,
            retval = PAM_MODULE_UNKNOWN;
        } else {
            D(("passing control to module..."));
+           pamh->mod_name=h->mod_name;
            retval = h->func(pamh, flags, h->argc, h->argv);
+           pamh->mod_name=NULL;
            D(("module returned: %s", pam_strerror(pamh, retval)));
            if (h->must_fail) {
                D(("module poorly listed in PAM config; forcing failure"));
@@ -366,6 +368,7 @@ int _pam_dispatch(pam_handle_t *pamh, int flags, int choice)
     __PAM_TO_MODULE(pamh);
 
     /* call the list of module functions */
+    pamh->choice = choice;
     retval = _pam_dispatch_aux(pamh, flags, h, resumed, use_cached_chain);
     resumed = PAM_FALSE;
 
index fd5e8760d0693c4aae3731f93957d2c526199926..b2d7c3a7954e81b1c7849b8444ba2886249d2654 100644 (file)
@@ -576,6 +576,27 @@ static int _pam_assemble_line(FILE *f, char *buffer, int buf_len)
     return used;
 }
 
+static char *
+extract_modulename(const char *mod_path)
+{
+  const char *p = strrchr (mod_path, '/');
+  char *dot, *retval;
+
+  if (p == NULL)
+    p = mod_path;
+  else
+    *p++;
+
+  if ((retval = strdup (p)) == NULL)
+    return NULL;
+
+  dot = strrchr (retval, '.');
+  if (dot)
+    *dot = '\0';
+
+  return retval;
+}
+
 typedef int (*servicefn)(pam_handle_t *, int, int, char **);
 
 int _pam_add_handler(pam_handle_t *pamh
@@ -886,6 +907,7 @@ 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->name);
     (*handler_p)->next = NULL;
 
     /* some of the modules have a second calling function */
@@ -916,6 +938,7 @@ int _pam_add_handler(pam_handle_t *pamh
        } else {
            (*handler_p2)->argv = NULL;              /* no arguments */
        }
+       (*handler_p2)->mod_name = extract_modulename(mod->name);
        (*handler_p2)->next = NULL;
     }
 
@@ -1018,6 +1041,8 @@ void _pam_free_handlers_aux(struct handler **hp)
     while (h) {
        last = h;
        _pam_drop(h->argv);  /* This is all alocated in a single chunk */
+       if (h->mod_name)
+         _pam_drop(h->mod_name);
        h = h->next;
        memset(last, 0, sizeof(*last));
        free(last);
index 24bb47dca04816721a04331267da240675687b9c..7ff592768186116807df4076dddc4f792acb4393 100644 (file)
@@ -54,6 +54,7 @@ struct handler {
     int argc;
     char **argv;
     struct handler *next;
+    char *mod_name;
 };
 
 struct loaded_module {
@@ -146,6 +147,8 @@ struct pam_handle {
     struct service handlers;
     struct _pam_former_state former;  /* library state - support for
                                         event driven applications */
+    const char *mod_name;      /* Name of the module currently executed */
+    int choice;                        /* Which function we call from the module */
 };
 
 /* Values for select arg to _pam_dispatch() */
diff --git a/libpam/pam_syslog.c b/libpam/pam_syslog.c
new file mode 100644 (file)
index 0000000..53ab7e2
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * 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.
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdarg.h>
+#include <errno.h>
+
+#include <security/pam_modules.h>
+#include <security/_pam_macros.h>
+#include <security/pam_ext.h>
+
+#include "pam_private.h"
+
+static const char *
+_pam_choice2str (int choice)
+{
+  switch (choice)
+    {
+    case PAM_AUTHENTICATE:
+      return "auth";
+    case PAM_SETCRED:
+      return "setcred";
+    case PAM_ACCOUNT:
+      return "account";
+    case PAM_OPEN_SESSION:
+    case PAM_CLOSE_SESSION:
+      return "session";
+    case PAM_CHAUTHTOK:
+      return "chauthtok";
+    }
+  return "";
+}
+
+void
+pam_vsyslog (pam_handle_t *pamh, int priority,
+            const char *fmt, va_list args)
+{
+  char *msgbuf1 = NULL, *msgbuf2 = NULL;
+  int save_errno = errno;
+
+  if (pamh->mod_name)
+    {
+      if (asprintf (&msgbuf1, "%s(%s:%s):", pamh->mod_name,
+                   pamh->service_name?pamh->service_name:"<unknown>",
+                   _pam_choice2str (pamh->choice)) < 0)
+       {
+         syslog (LOG_AUTHPRIV|LOG_ERR, "asprintf: %m");
+         return;
+       }
+    }
+  else
+    {
+      msgbuf1 = strdup (_PAM_SYSTEM_LOG_PREFIX);
+      if (msgbuf1 == NULL)
+       {
+         vsyslog (LOG_AUTHPRIV|priority, fmt, args);
+         return;
+       }
+    }
+
+  if (vasprintf (&msgbuf2, fmt, args) < 0)
+    {
+      syslog (LOG_AUTHPRIV|LOG_ERR, "vasprintf: %m");
+      _pam_drop (msgbuf1);
+      return;
+    }
+
+  errno = save_errno;
+  syslog (LOG_AUTHPRIV|priority, "%s %s", msgbuf1, msgbuf2);
+
+  _pam_drop (msgbuf1);
+  _pam_drop (msgbuf2);
+}
+
+void
+pam_syslog (pam_handle_t *pamh, int priority,
+           const char *fmt, ...)
+{
+  va_list args;
+
+  va_start (args, fmt);
+  pam_vsyslog (pamh, priority, fmt, args);
+  va_end (args);
+}
index 2c6ce757bc7ac5207d11123e4a7f05e321638969..43ce3262e398e6af4f338859e46898c0a4f976bb 100644 (file)
@@ -45,7 +45,7 @@
 
 #include "pam_private.h"
 
-int PAM_FORMAT((printf, 4, 0)) PAM_NONNULL((4))
+int
 pam_vprompt (pam_handle_t *pamh, int style, char **response,
             const char *fmt, va_list args)
 {
@@ -97,7 +97,7 @@ pam_vprompt (pam_handle_t *pamh, int style, char **response,
   return retval;
 }
 
-int PAM_FORMAT((printf, 4, 5)) PAM_NONNULL((4))
+int
 pam_prompt (pam_handle_t *pamh, int style, char **response,
            const char *fmt, ...)
 {
index 65e591a7378c4108ddd9c651a6089a1604387d26..566b1bc45ccd9d13dc88d3eaf7f6002609ca4033 100644 (file)
@@ -24,6 +24,7 @@
 #define PAM_SM_PASSWORD
 
 #include <security/pam_modules.h>
+#include <security/pam_ext.h>
 
 /* some syslogging */
 
      value = value ? value : default_value ;                    \
 } while (0)
 
-static void _pam_log(int err, const char *format, ...)
-{
-    va_list args;
-
-    va_start(args, format);
-    openlog("PAM-warn", LOG_CONS|LOG_PID, LOG_AUTH);
-    vsyslog(err, format, args);
-    va_end(args);
-    closelog();
-}
-
 static void log_items(pam_handle_t *pamh, const char *function)
 {
      const void *service=NULL, *user=NULL, *terminal=NULL,
@@ -54,23 +44,27 @@ static void log_items(pam_handle_t *pamh, const char *function)
      OBTAIN(PAM_RUSER, ruser, "<unknown>");
      OBTAIN(PAM_RHOST, rhost, "<unknown>");
 
-     _pam_log(LOG_NOTICE, "function=[%s] service=[%s] terminal=[%s] user=[%s]"
-             " ruser=[%s] rhost=[%s]\n",
-             function, service, terminal, user, ruser, rhost);
+     pam_syslog(pamh, LOG_NOTICE,
+               "function=[%s] service=[%s] terminal=[%s] user=[%s]"
+               " ruser=[%s] rhost=[%s]\n", function,
+               (const char *) service, (const char *) terminal,
+               (const char *) user, (const char *) ruser,
+               (const char *) rhost);
 }
 
 /* --- authentication management functions (only) --- */
 
 PAM_EXTERN
-int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc,
-                       const char **argv)
+int pam_sm_authenticate(pam_handle_t *pamh, int flags UNUSED,
+                       int argc UNUSED, const char **argv UNUSED)
 {
     log_items(pamh, __FUNCTION__);
     return PAM_IGNORE;
 }
 
 PAM_EXTERN
-int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv)
+int pam_sm_setcred(pam_handle_t *pamh, int flags UNUSED,
+                  int argc UNUSED, const char **argv UNUSED)
 {
     log_items(pamh, __FUNCTION__);
     return PAM_IGNORE;
@@ -79,7 +73,8 @@ int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv)
 /* password updating functions */
 
 PAM_EXTERN
-int pam_sm_chauthtok(pam_handle_t *pamh,int flags,int argc,const char **argv)
+int pam_sm_chauthtok(pam_handle_t *pamh, int flags UNUSED,
+                    int argc UNUSED, const char **argv UNUSED)
 {
     log_items(pamh, __FUNCTION__);
     return PAM_IGNORE;