pam-modules/lib/vartab.c
2022-02-04 09:38:17 +02:00

102 lines
2.6 KiB
C
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* This file is part of pam-modules.
Copyright (C) 2009-2022 Sergey Poznyakoff
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 3 of the License, or (at your
option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program. If not, see <http://www.gnu.org/licenses/>. */
#include <graypam.h>
#include "wordsplit/wordsplit.h"
struct keyword *
gray_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 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
get_pam_var(char **ret, const char *var, size_t len, void *clos)
{
pam_handle_t *pamh = clos;
struct keyword *kw;
char const *val;
int rc;
char *s;
kw = gray_find_keyword(vartab, var, len);
if (!kw)
return WRDSE_UNDEF;
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 WRDSE_UNDEF;
}
if (!val) {
val = "";
}
s = strdup(val);
if (!s)
return WRDSE_NOSPACE;
*ret = s;
return WRDSE_OK;
}
int
gray_expand_string(pam_handle_t *pamh, const char *str, char **output_ptr)
{
struct wordsplit ws;
int wsflags = WRDSF_NOSPLIT
| WRDSF_GETVAR
| WRDSF_CLOSURE
| WRDSF_NOCMD
| WRDSF_UNDEF;
int rc;
ws.ws_getvar = get_pam_var;
ws.ws_closure = pamh;
rc = wordsplit(str, &ws, wsflags);
if (rc) {
if (ws.ws_errctx)
_pam_log(LOG_ERR,
"string split: %s: %s",
wordsplit_strerror (&ws), ws.ws_errctx);
else
_pam_log(LOG_ERR,
"string split: %s",
wordsplit_strerror (&ws));
rc = (rc == WRDSE_NOSPACE) ? PAM_BUF_ERR : PAM_SERVICE_ERR;
} else {
*output_ptr = ws.ws_wordv[0];
ws.ws_wordv[0] = NULL;
}
wordsplit_free(&ws);
return rc;
}