mirror of
git://git.gnu.org.ua/pam-modules.git
synced 2025-05-10 15:45:48 +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
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <syslog.h>
|
#include <syslog.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#define obstack_chunk_alloc malloc
|
||||||
|
#define obstack_chunk_free free
|
||||||
|
#include <obstack.h>
|
||||||
|
|
||||||
#define PAM_SM_AUTH
|
#define PAM_SM_AUTH
|
||||||
#define PAM_SM_PASSWORD
|
#define PAM_SM_PASSWORD
|
||||||
#include <security/pam_modules.h>
|
#include <security/pam_modules.h>
|
||||||
|
|
||||||
PAM_EXTERN
|
#include <common.c>
|
||||||
int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc,
|
|
||||||
const char **argv)
|
|
||||||
|
/* 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
|
static struct keyword syslog_facility[] = {
|
||||||
int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv)
|
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
|
static void
|
||||||
int pam_sm_chauthtok(pam_handle_t *pamh,int flags,int argc,const char **argv)
|
_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_EXTERN int
|
||||||
pam_sm_acct_mgmt (pam_handle_t *pamh, int flags, int argc, const char **argv)
|
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_EXTERN int
|
||||||
pam_sm_open_session (pam_handle_t *pamh, int flags, int argc,
|
pam_sm_open_session (pam_handle_t *pamh, int flags, int argc,
|
||||||
const char **argv)
|
const char **argv)
|
||||||
{
|
{
|
||||||
return PAM_IGNORE;
|
return echo(pamh, __FUNCTION__, argc, argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
PAM_EXTERN int
|
PAM_EXTERN int
|
||||||
pam_sm_close_session (pam_handle_t *pamh, int flags, int argc,
|
pam_sm_close_session (pam_handle_t *pamh, int flags, int argc,
|
||||||
const char **argv)
|
const char **argv)
|
||||||
{
|
{
|
||||||
return PAM_IGNORE;
|
return echo(pamh, __FUNCTION__, argc, argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef PAM_STATIC
|
#ifdef PAM_STATIC
|
||||||
|
|
||||||
/* static module data */
|
/* static module data */
|
||||||
|
|
||||||
struct pam_module _pam_warn_modstruct = {
|
struct pam_module _pam_log_modstruct = {
|
||||||
"pam_log",
|
"pam_log",
|
||||||
pam_sm_authenticate,
|
pam_sm_authenticate,
|
||||||
pam_sm_setcred,
|
pam_sm_setcred,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue