1 /*
2  * Interface to standard PAM logging.
3  *
4  * The canonical version of this file is maintained in the rra-c-util package,
5  * which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
6  *
7  * Written by Russ Allbery <eagle@eyrie.org>
8  * Copyright 2020 Russ Allbery <eagle@eyrie.org>
9  * Copyright 2006-2010, 2012-2013
10  *     The Board of Trustees of the Leland Stanford Junior University
11  *
12  * Permission is hereby granted, free of charge, to any person obtaining a
13  * copy of this software and associated documentation files (the "Software"),
14  * to deal in the Software without restriction, including without limitation
15  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16  * and/or sell copies of the Software, and to permit persons to whom the
17  * Software is furnished to do so, subject to the following conditions:
18  *
19  * The above copyright notice and this permission notice shall be included in
20  * all copies or substantial portions of the Software.
21  *
22  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
25  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28  * DEALINGS IN THE SOFTWARE.
29  *
30  * SPDX-License-Identifier: MIT
31  */
32 
33 #ifndef PAM_UTIL_LOGGING_H
34 #define PAM_UTIL_LOGGING_H 1
35 
36 #include <config.h>
37 #include <portable/macros.h>
38 #ifdef HAVE_KRB5
39 #    include <portable/krb5.h>
40 #endif
41 #include <portable/pam.h>
42 
43 #include <stddef.h>
44 #include <syslog.h>
45 
46 /* Forward declarations to avoid extra includes. */
47 struct pam_args;
48 
49 BEGIN_DECLS
50 
51 /* Default to a hidden visibility for all internal functions. */
52 #pragma GCC visibility push(hidden)
53 
54 /*
55  * Error reporting and debugging functions.  For each log level, there are two
56  * functions.  The _log function just prints out the message it's given.  The
57  * _log_pam function does the same but appends the pam_strerror results for
58  * the provided status code if it is not PAM_SUCCESS.
59  */
60 void putil_crit(struct pam_args *, const char *, ...)
61     __attribute__((__format__(printf, 2, 3)));
62 void putil_crit_pam(struct pam_args *, int, const char *, ...)
63     __attribute__((__format__(printf, 3, 4)));
64 void putil_err(struct pam_args *, const char *, ...)
65     __attribute__((__format__(printf, 2, 3)));
66 void putil_err_pam(struct pam_args *, int, const char *, ...)
67     __attribute__((__format__(printf, 3, 4)));
68 void putil_notice(struct pam_args *, const char *, ...)
69     __attribute__((__format__(printf, 2, 3)));
70 void putil_notice_pam(struct pam_args *, int, const char *, ...)
71     __attribute__((__format__(printf, 3, 4)));
72 void putil_debug(struct pam_args *, const char *, ...)
73     __attribute__((__format__(printf, 2, 3)));
74 void putil_debug_pam(struct pam_args *, int, const char *, ...)
75     __attribute__((__format__(printf, 3, 4)));
76 
77 /*
78  * The Kerberos versions of the PAM logging and debugging functions, which
79  * report the last Kerberos error.  These are only available if built with
80  * Kerberos support.
81  */
82 #ifdef HAVE_KRB5
83 void putil_crit_krb5(struct pam_args *, int, const char *, ...)
84     __attribute__((__format__(printf, 3, 4)));
85 void putil_err_krb5(struct pam_args *, int, const char *, ...)
86     __attribute__((__format__(printf, 3, 4)));
87 void putil_notice_krb5(struct pam_args *, int, const char *, ...)
88     __attribute__((__format__(printf, 3, 4)));
89 void putil_debug_krb5(struct pam_args *, int, const char *, ...)
90     __attribute__((__format__(printf, 3, 4)));
91 #endif
92 
93 /* Log entry to a PAM function. */
94 void putil_log_entry(struct pam_args *, const char *, int flags)
95     __attribute__((__nonnull__));
96 
97 /* Log an authentication failure. */
98 void putil_log_failure(struct pam_args *, const char *, ...)
99     __attribute__((__nonnull__, __format__(printf, 2, 3)));
100 
101 /* Undo default visibility change. */
102 #pragma GCC visibility pop
103 
104 END_DECLS
105 
106 /* __func__ is C99, but not provided by all implementations. */
107 #if (__STDC_VERSION__ < 199901L) && !defined(__func__)
108 #    if (__GNUC__ >= 2)
109 #        define __func__ __FUNCTION__
110 #    else
111 #        define __func__ "<unknown>"
112 #    endif
113 #endif
114 
115 /* Macros to record entry and exit from the main PAM functions. */
116 #define ENTRY(args, flags)                              \
117     do {                                                \
118         if (args->debug)                                \
119             putil_log_entry((args), __func__, (flags)); \
120     } while (0)
121 #define EXIT(args, pamret)                                                \
122     do {                                                                  \
123         if (args != NULL && args->debug)                                  \
124             pam_syslog(                                                   \
125                 (args)->pamh, LOG_DEBUG, "%s: exit (%s)", __func__,       \
126                 ((pamret) == PAM_SUCCESS)                                 \
127                     ? "success"                                           \
128                     : (((pamret) == PAM_IGNORE) ? "ignore" : "failure")); \
129     } while (0)
130 
131 #endif /* !PAM_UTIL_LOGGING_H */
132