aboutsummaryrefslogtreecommitdiff
path: root/pam_log
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2006-09-06 13:05:34 +0000
committerSergey Poznyakoff <gray@gnu.org.ua>2006-09-06 13:05:34 +0000
commit331da3dd57c84cd645270a4086ccf5e79945e79e (patch)
tree6c49dc1bcd903dbbbdabaca52001440430882001 /pam_log
parenta91c9b991a43d43727e881223f4dff274f4cf990 (diff)
downloadpam-modules-331da3dd57c84cd645270a4086ccf5e79945e79e.tar.gz
pam-modules-331da3dd57c84cd645270a4086ccf5e79945e79e.tar.bz2
Implemented
git-svn-id: file:///svnroot/pam-modules/trunk@35 56984be4-0537-0410-a56c-fcb268c96130
Diffstat (limited to 'pam_log')
-rw-r--r--pam_log/pam_log.c330
1 files changed, 316 insertions, 14 deletions
diff --git a/pam_log/pam_log.c b/pam_log/pam_log.c
index ad02b13..74488b5 100644
--- a/pam_log/pam_log.c
+++ b/pam_log/pam_log.c
@@ -24,58 +24,360 @@
#endif
#include <stdio.h>
+#include <stdlib.h>
#include <unistd.h>
#include <syslog.h>
#include <stdarg.h>
+#define obstack_chunk_alloc malloc
+#define obstack_chunk_free free
+#include <obstack.h>
#define PAM_SM_AUTH
#define PAM_SM_PASSWORD
#include <security/pam_modules.h>
-PAM_EXTERN
-int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc,
- const char **argv)
+#include <common.c>
+
+
+/* Command line parsing */
+#define CNTL_DEBUG 0x0001
+#define CNTL_AUDIT 0x0002
+#define CNTL_WAITDEBUG 0x0004
+
+#define CNTL_DEBUG_LEV() (cntl_flags>>16)
+#define CNTL_SET_DEBUG_LEV(cntl,n) (cntl |= ((n)<<16))
+
+static int cntl_flags;
+
+static int xargc;
+static const char **xargv;
+static int priority = LOG_INFO;
+
+#define DEBUG(m,c) if (CNTL_DEBUG_LEV()>=(m)) _pam_debug c
+#define AUDIT(c) if (cntl_flags&CNTL_AUDIT) _pam_debug c
+
+struct keyword {
+ char *name;
+ int len;
+ int code;
+};
+#define DCL(n,c) { n, sizeof n - 1, c }
+
+static struct keyword *
+find_keyword(struct keyword *kwtab, const char *str, size_t len)
+{
+ for (; kwtab->name; kwtab++)
+ if (kwtab->len == len
+ && strncmp(kwtab->name, str, kwtab->len) == 0)
+ return kwtab;
+ return NULL;
+}
+
+static struct keyword syslog_facility[] = {
+ DCL("user", LOG_USER),
+ DCL("daemon", LOG_DAEMON),
+ DCL("auth", LOG_AUTH),
+ DCL("authpriv", LOG_AUTHPRIV),
+ DCL("local0", LOG_LOCAL0),
+ DCL("local1", LOG_LOCAL1),
+ DCL("local2", LOG_LOCAL2),
+ DCL("local3", LOG_LOCAL3),
+ DCL("local4", LOG_LOCAL4),
+ DCL("local5", LOG_LOCAL5),
+ DCL("local6", LOG_LOCAL6),
+ DCL("local7", LOG_LOCAL7),
+ { NULL }
+};
+
+static struct keyword syslog_priority[] = {
+ DCL("emerg", LOG_EMERG ),
+ DCL("alert", LOG_ALERT ),
+ DCL("crit", LOG_CRIT ),
+ DCL("err", LOG_ERR ),
+ DCL("warning", LOG_WARNING ),
+ DCL("notice", LOG_NOTICE ),
+ DCL("info", LOG_INFO ),
+ DCL("debug", LOG_DEBUG ),
+ { NULL }
+};
+
+static char *
+parse_priority(const char *str)
+{
+ int len;
+ struct keyword *kw;
+
+ for (len = 0; str[len]; len++)
+ if (ispunct(str[len]))
+ break;
+
+ if (len) {
+ kw = find_keyword(syslog_facility, str, len);
+ if (!kw) {
+ _pam_log(LOG_ERR,
+ "unknown syslog facility: %*.*s",
+ len, len, str);
+ return;
+ }
+ facility = kw->code;
+ }
+
+ if (str[len]) {
+ str += len + 1;
+ kw = find_keyword(syslog_priority, str, strlen(str));
+ if (!kw) {
+ _pam_log(LOG_ERR,
+ "unknown syslog priority: %s", str);
+ return;
+ }
+ priority = kw->code;
+ }
+}
+
+static void
+_pam_parse(pam_handle_t *pamh, int argc, const char **argv)
+{
+ int ctrl = 0;
+
+ /* Collect generic arguments */
+ for (; argc > 0; argv++, argc--) {
+ if (!strncmp(*argv, "-debug", 6)) {
+ ctrl |= CNTL_DEBUG;
+ if ((*argv)[6] == '=')
+ CNTL_SET_DEBUG_LEV(ctrl, atoi(*argv + 7));
+ else
+ CNTL_SET_DEBUG_LEV(ctrl, 1);
+ } else if (!strcmp(*argv, "-audit"))
+ ctrl |= CNTL_AUDIT;
+ else if (!strncmp(*argv, "-waitdebug", 10))
+ WAITDEBUG(*argv + 10);
+ else if (!strncmp(*argv, "-tag=", 5))
+ syslog_tag = *argv + 5;
+ else if (!strncmp(*argv, "-pri=", 5))
+ parse_priority(*argv + 5);
+ else if (!strcmp(*argv, "-no-open"))
+ syslog_dont_open = 1;
+ else if (!strcmp(*argv, "--"))
+ break;
+ else if (**argv == '-')
+ _pam_log(LOG_ERR,
+ "unknown option: %s", *argv);
+ else
+ break;
+ }
+
+ /* Save the format variables */
+ xargc = argc;
+ xargv = argv;
+
+ cntl_flags = ctrl;
+}
+
+static struct keyword vartab[] = {
+ DCL("service", PAM_SERVICE),
+ DCL("user", PAM_USER),
+ DCL("tty", PAM_TTY),
+ DCL("rhost", PAM_RHOST),
+ DCL("ruser", PAM_RUSER),
+ DCL("prompt", PAM_USER_PROMPT),
+ DCL("password", PAM_AUTHTOK),
+ { NULL }
+};
+
+static int
+var_tok(const char *str, const char ** pvar, size_t *plen)
+{
+ size_t len;
+
+ for (len = 0; str[len]; len++) {
+ if (str[len] == '}' || str[len] == ':') {
+ *pvar = str;
+ *plen = len;
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static int
+repl_tok(const char *str, const char ** pret, size_t *plen)
+{
+ size_t len;
+
+ for (len = 0; str[len]; len++) {
+ if (str[len] == '}') {
+ *pret = str;
+ *plen = len;
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static int
+get_variable(pam_handle_t *pamh, const char *str, struct obstack *stk,
+ const char **endp)
+{
+ const char *name;
+ size_t namelen;
+ const char *repl = NULL;
+ size_t repllen = 0;
+ const char *val;
+ size_t vallen;
+ struct keyword *kw;
+ const char *end;
+ int rc;
+
+ str++; /* Get past the initial $ */
+ if (*str == '{') {
+ str++;
+
+ if (var_tok(str, &name, &namelen))
+ return 1;
+
+ end = str + namelen;
+ if (*end == ':') {
+ end++;
+ if (*end == '-')
+ end++;
+ if (repl_tok(end, &repl, &repllen))
+ return 1;
+ end += repllen;
+ }
+ end++;
+ } else {
+ name = str;
+ namelen = strlen(str);
+ end = str + namelen;
+ }
+
+ kw = find_keyword(vartab, name, namelen);
+ if (!kw) {
+ _pam_log(LOG_ERR,
+ "unknown PAM variable: %*.*s",
+ namelen, namelen, name);
+ return 1;
+ }
+
+ rc = pam_get_item(pamh, kw->code, (const void**) &val);
+ if (rc) {
+ _pam_log(LOG_ERR,
+ "cannot obtain variable %s: %s",
+ kw->name, pam_strerror(pamh, rc));
+ return 1;
+ }
+
+ if (!val) {
+ if (repl) {
+ val = repl;
+ vallen = repllen;
+ } else {
+ val = "";
+ vallen = 0;
+ }
+ } else
+ vallen = strlen(val);
+
+ obstack_grow(stk, val, vallen);
+ *endp = end;
+ return 0;
+}
+
+static void
+expand_string(pam_handle_t *pamh, struct obstack *stk)
+{
+ int i;
+
+ for (i = 0; i < xargc; i++) {
+ DEBUG(2,("%s: %d %s", __FUNCTION__, i, xargv[i]));
+ if (i > 0)
+ obstack_1grow(stk, ' ');
+ if (strchr(xargv[i], '$') == 0)
+ obstack_grow(stk, xargv[i], strlen(xargv[i]));
+ else {
+ const char *p;
+
+ for (p = xargv[i]; *p; p++) {
+ if (*p == '\\') {
+ p++;
+ obstack_1grow(stk, *p);
+ } else if (*p == '$') {
+ if (get_variable(pamh, p, stk, &p))
+ obstack_1grow(stk, *p);
+ else
+ p--;
+ } else
+ obstack_1grow(stk, *p);
+ }
+ }
+ }
+}
+
+static int
+echo(pam_handle_t *pamh, const char *prefix, int argc, const char **argv)
+{
+ char *str;
+ struct obstack stk;
+
+ _pam_parse(pamh, argc, argv);
+ obstack_init(&stk);
+ if (prefix) {
+ obstack_grow(&stk, prefix, strlen(prefix));
+ obstack_grow(&stk, ": ", 2);
+ }
+ expand_string(pamh, &stk);
+ obstack_1grow(&stk, 0);
+ str = obstack_finish(&stk);
+ _pam_log(priority, "%s", str);
+ obstack_free(&stk, NULL);
+ return PAM_IGNORE;
+}
+
+
+
+PAM_EXTERN int
+pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv)
{
- return PAM_IGNORE;
+ return echo(pamh, __FUNCTION__, argc, argv);
}
-PAM_EXTERN
-int pam_sm_setcred(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)
{
- return PAM_IGNORE;
+ return echo(pamh, __FUNCTION__, argc, argv);
}
-PAM_EXTERN
-int pam_sm_chauthtok(pam_handle_t *pamh,int flags,int argc,const char **argv)
+PAM_EXTERN int
+pam_sm_chauthtok(pam_handle_t *pamh,int flags,int argc,const char **argv)
{
- return PAM_IGNORE;
+ return echo(pamh, __FUNCTION__, argc, argv);
}
PAM_EXTERN int
pam_sm_acct_mgmt (pam_handle_t *pamh, int flags, int argc, const char **argv)
{
- return PAM_IGNORE;
+ return echo(pamh, __FUNCTION__, argc, argv);
}
PAM_EXTERN int
pam_sm_open_session (pam_handle_t *pamh, int flags, int argc,
const char **argv)
{
- return PAM_IGNORE;
+ return echo(pamh, __FUNCTION__, argc, argv);
}
PAM_EXTERN int
pam_sm_close_session (pam_handle_t *pamh, int flags, int argc,
const char **argv)
{
- return PAM_IGNORE;
+ return echo(pamh, __FUNCTION__, argc, argv);
}
#ifdef PAM_STATIC
/* static module data */
-struct pam_module _pam_warn_modstruct = {
+struct pam_module _pam_log_modstruct = {
"pam_log",
pam_sm_authenticate,
pam_sm_setcred,

Return to:

Send suggestions and report system problems to the System administrator.