mirror of
git://git.gnu.org.ua/pam-modules.git
synced 2025-04-27 08:59:53 +03:00
Implemented
git-svn-id: file:///svnroot/pam-modules/trunk@35 56984be4-0537-0410-a56c-fcb268c96130
This commit is contained in:
parent
a91c9b991a
commit
331da3dd57
1 changed files with 316 additions and 14 deletions
|
@ -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)
|
||||
{
|
||||
return PAM_IGNORE;
|
||||
for (; kwtab->name; kwtab++)
|
||||
if (kwtab->len == len
|
||||
&& strncmp(kwtab->name, str, kwtab->len) == 0)
|
||||
return kwtab;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PAM_EXTERN
|
||||
int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv)
|
||||
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)
|
||||
{
|
||||
return PAM_IGNORE;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
PAM_EXTERN
|
||||
int pam_sm_chauthtok(pam_handle_t *pamh,int flags,int argc,const char **argv)
|
||||
static void
|
||||
_pam_parse(pam_handle_t *pamh, int argc, const char **argv)
|
||||
{
|
||||
return PAM_IGNORE;
|
||||
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 echo(pamh, __FUNCTION__, argc, argv);
|
||||
}
|
||||
|
||||
PAM_EXTERN int
|
||||
pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv)
|
||||
{
|
||||
return echo(pamh, __FUNCTION__, argc, argv);
|
||||
}
|
||||
|
||||
PAM_EXTERN int
|
||||
pam_sm_chauthtok(pam_handle_t *pamh,int flags,int argc,const char **argv)
|
||||
{
|
||||
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,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue