aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitmodules3
-rw-r--r--configure.ac2
-rw-r--r--lib/Makefile.am9
-rw-r--r--lib/graypam.h5
-rw-r--r--lib/vartab.c217
m---------lib/wordsplit0
-rw-r--r--pam_ldaphome/pam_ldaphome.c36
-rw-r--r--pam_log/pam_log.c47
-rw-r--r--pam_sql/pam_mysql.c13
-rw-r--r--pam_sql/pam_pgsql.c12
-rw-r--r--pam_sql/pam_sql.c36
-rw-r--r--pam_sql/pam_sql.h3
-rw-r--r--pam_umotd/pam_umotd.c60
13 files changed, 159 insertions, 284 deletions
diff --git a/.gitmodules b/.gitmodules
index 527e24f..67e703b 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +1,6 @@
[submodule "imprimatur"]
path = imprimatur
url = git://git.gnu.org.ua/imprimatur.git
+[submodule "lib/wordsplit"]
+ path = lib/wordsplit
+ url = git://git.gnu.org.ua/wordsplit.git
diff --git a/configure.ac b/configure.ac
index e146a65..a784780 100644
--- a/configure.ac
+++ b/configure.ac
@@ -20,7 +20,7 @@ AC_INIT(pam-modules, 2.3.90, bug-pam-modules@gnu.org.ua)
AC_CONFIG_SRCDIR(pam_fshadow/pam_fshadow.c)
AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_MACRO_DIR([m4])
-AM_INIT_AUTOMAKE([1.11 no-exeext tar-ustar dist-xz silent-rules])
+AM_INIT_AUTOMAKE([1.11 no-exeext tar-ustar dist-xz silent-rules subdir-objects])
AM_CONFIG_HEADER(config.h)
# Enable silent rules by default:
diff --git a/lib/Makefile.am b/lib/Makefile.am
index cbceb4c..013d54e 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -1,5 +1,5 @@
# This file is part of pam-modules.
-# Copyright (C) 2008, 2010-2012, 2014-2015, 2018 Sergey Poznyakoff
+# Copyright (C) 2008-2020 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
@@ -32,6 +32,9 @@ libgraypam_la_SOURCES = \
sha1.h\
strutil.c\
vartab.c\
- escape.c
+ escape.c\
+ wordsplit/wordsplit.c
-noinst_HEADERS = graypam.h
+noinst_HEADERS = graypam.h wordsplit/wordsplit.h
+
+AM_CPPFLAGS = -I$(srcdir)/wordsplit
diff --git a/lib/graypam.h b/lib/graypam.h
index dcb9dde..f9ce0fc 100644
--- a/lib/graypam.h
+++ b/lib/graypam.h
@@ -177,10 +177,7 @@ ssize_t gray_base64_decode(gray_slist_t slist, const char *iptr, size_t isize);
int gray_check_ldap_pass (const char *db_pass, const char *pass);
-void gray_expand_argv(pam_handle_t *pamh, int argc, const char **argv,
- gray_slist_t slist);
-void gray_expand_string(pam_handle_t *pamh, const char *str,
- gray_slist_t slist);
+int gray_expand_string(pam_handle_t *pamh, const char *str, char **output);
void gray_escape_string(gray_slist_t slist, const char *str, size_t len);
struct keyword {
diff --git a/lib/vartab.c b/lib/vartab.c
index 40fa89f..89974cd 100644
--- a/lib/vartab.c
+++ b/lib/vartab.c
@@ -1,5 +1,5 @@
/* This file is part of pam-modules.
- Copyright (C) 2009-2012, 2014-2015, 2018 Sergey Poznyakoff
+ Copyright (C) 2009-2020 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
@@ -15,6 +15,7 @@
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)
@@ -25,177 +26,77 @@ gray_find_keyword(struct keyword *kwtab, const char *str, size_t len)
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 }
+ 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)
+get_pam_var(char **ret, const char *var, size_t len, void *clos)
{
- 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;
-}
-
-#define ISKW(c) ((c) && (isalnum(c) || (c) == '_'))
-
-static int
-get_variable(pam_handle_t *pamh, const char *str, gray_slist_t slist,
- const char **endp)
-{
- const char *name;
- size_t namelen;
- const char *repl = NULL;
- size_t repllen = 0;
- const char *val;
- size_t vallen;
+ pam_handle_t *pamh = clos;
struct keyword *kw;
- const char *end;
+ char const *val;
int rc;
+ char *s;
- 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 = end = str;
- for (namelen = 0; ISKW(*end); namelen++, end++)
- ;
- }
-
- kw = gray_find_keyword(vartab, name, namelen);
- if (!kw) {
- _pam_log(LOG_ERR,
- "unknown PAM variable: %*.*s",
- namelen, namelen, name);
- return 1;
- }
-
+ 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 1;
- }
-
+ if (rc) {
+ _pam_log(LOG_ERR,
+ "cannot obtain variable %s: %s",
+ kw->name, pam_strerror(pamh, rc));
+ return WRDSE_UNDEF;
+ }
if (!val) {
- if (repl) {
- val = repl;
- vallen = repllen;
- } else {
- val = "";
- vallen = 0;
- }
- } else
- vallen = strlen(val);
-
- gray_escape_string(slist, val, vallen);
- *endp = end;
- return 0;
-}
-
-void
-gray_expand_argv(pam_handle_t *pamh, int argc, const char **argv,
- gray_slist_t slist)
-{
- int i;
-
- for (i = 0; i < argc; i++) {
- if (i > 0)
- gray_slist_append_char(slist, ' ');
- if (strchr(argv[i], '$') == 0)
- gray_slist_append(slist, argv[i], strlen(argv[i]));
- else {
- const char *p;
-
- for (p = argv[i]; *p; p++) {
- if (*p == '\\') {
- p++;
- gray_slist_append_char(slist, *p);
- } else if (*p == '$') {
- if (get_variable(pamh, p, slist, &p))
- gray_slist_append_char(slist,
- *p);
- else
- p--;
- } else
- gray_slist_append_char(slist, *p);
- }
- }
+ val = "";
}
+ s = strdup(val);
+ if (!s)
+ return WRDSE_NOSPACE;
+ *ret = s;
+ return WRDSE_OK;
}
-void
-gray_expand_string(pam_handle_t *pamh, const char *str, gray_slist_t slist)
+int
+gray_expand_string(pam_handle_t *pamh, const char *str, char **output_ptr)
{
- const char *p;
-#define FLUSH() gray_slist_append(slist, str, p - str); str = p
+ struct wordsplit ws;
+ int wsflags = WRDSF_NOSPLIT
+ | WRDSF_GETVAR
+ | WRDSF_CLOSURE
+ | WRDSF_NOCMD
+ | WRDSF_UNDEF;
+ int rc;
- for (p = str; *p; ) {
- if (*p == '\\') {
- FLUSH();
- p++;
- if (*p) {
- gray_slist_append_char(slist, *p);
- p++;
- } else {
- gray_slist_append_char(slist, '\\');
- break;
- }
- str = p;
- } else if (*p == '$') {
- FLUSH();
- if (get_variable(pamh, p, slist, &p)) {
- gray_slist_append_char(slist, *p);
- p++;
- }
- str = p;
- } else
- p++;
+ 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;
}
- FLUSH();
+ wordsplit_free(&ws);
+ return rc;
}
diff --git a/lib/wordsplit b/lib/wordsplit
new file mode 160000
+Subproject 66e5c112850e85e3a37efbec30a0d7b8d7cff83
diff --git a/pam_ldaphome/pam_ldaphome.c b/pam_ldaphome/pam_ldaphome.c
index 0b492dd..5269af0 100644
--- a/pam_ldaphome/pam_ldaphome.c
+++ b/pam_ldaphome/pam_ldaphome.c
@@ -1576,10 +1576,8 @@ import_public_key(pam_handle_t *pamh, struct passwd *pw, struct gray_env *env)
_pam_log(LOG_ERR, "configuration variable `filter' not set");
return PAM_SERVICE_ERR;
}
- if (!attr) {
- _pam_log(LOG_ERR, "configuration variable `attr' not set");
- return PAM_SERVICE_ERR;
- }
+ if (!attr)
+ attr = "sshPublicKey";
ld = ldap_connect(env);
if (!ld)
@@ -1588,27 +1586,15 @@ import_public_key(pam_handle_t *pamh, struct passwd *pw, struct gray_env *env)
retval = PAM_SERVICE_ERR;
else {
char *filter;
- gray_slist_t slist;
-
- slist = gray_slist_create();
- if (!slist)
- retval = errno_to_pam(errno);
- else {
- gray_expand_string(pamh, filter_pat, slist);
- gray_slist_append_char(slist, 0);
- filter = gray_slist_finish(slist);
- if (filter) {
- char **keys = get_pubkeys(ld, base, filter,
- attr);
- if (keys) {
- retval = store_pubkeys(keys, pw, env);
- argcvz_free(keys);
- } else
- retval = PAM_SUCCESS;
- } else {
- retval = errno_to_pam(gray_slist_err(slist));
- }
- gray_slist_free(&slist);
+
+ retval = gray_expand_string(pamh, filter_pat, &filter);
+ if (retval == PAM_SUCCESS) {
+ char **keys = get_pubkeys(ld, base, filter, attr);
+ if (keys) {
+ retval = store_pubkeys(keys, pw, env);
+ argcvz_free(keys);
+ } else
+ retval = PAM_SUCCESS;
}
}
ldap_unbind(ld);
diff --git a/pam_log/pam_log.c b/pam_log/pam_log.c
index c59bc16..ae155dc 100644
--- a/pam_log/pam_log.c
+++ b/pam_log/pam_log.c
@@ -1,5 +1,5 @@
/* This file is part of pam-modules.
- Copyright (C) 2006-2008, 2010-2012, 2014-2015, 2018 Sergey Poznyakoff
+ Copyright (C) 2006-2020 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
@@ -20,8 +20,6 @@
/* Command line parsing */
static long debug_level;
-static int xargc;
-static const char **xargv;
static int priority = LOG_INFO;
static int facility = LOG_AUTHPRIV;
static const char *syslog_tag = MODULE_NAME;
@@ -103,7 +101,8 @@ struct pam_opt pam_opt[] = {
static int
-_pam_parse(pam_handle_t *pamh, int argc, const char **argv)
+_pam_parse(pam_handle_t *pamh, int argc, const char **argv,
+ int *ret_argc, char const ***ret_argv)
{
int i;
const char **targv;
@@ -125,8 +124,8 @@ _pam_parse(pam_handle_t *pamh, int argc, const char **argv)
gray_parseopt(pam_opt, i, targv);
free(targv);
- xargc = argc - i;
- xargv = argv + i;
+ *ret_argc = argc - i;
+ *ret_argv = argv + i;
closelog();
gray_log_init(!do_open, syslog_tag, facility);
@@ -136,7 +135,10 @@ _pam_parse(pam_handle_t *pamh, int argc, const char **argv)
static int
echo(pam_handle_t *pamh, const char *prefix, int argc, const char **argv)
{
- if (_pam_parse(pamh, argc, argv) == PAM_SUCCESS) {
+ int xargc;
+ const char **xargv;
+
+ if (_pam_parse(pamh, argc, argv, &xargc, &xargv) == PAM_SUCCESS) {
gray_slist_t slist;
slist = gray_slist_create();
@@ -144,20 +146,35 @@ echo(pam_handle_t *pamh, const char *prefix, int argc, const char **argv)
errno_to_pam(errno);
} else {
char *str;
+ int rc = PAM_SUCCESS;
+ int i;
+
if (prefix) {
gray_slist_append(slist, prefix,
strlen(prefix));
gray_slist_append(slist, ": ", 2);
}
- gray_expand_argv(pamh, xargc, xargv, slist);
- gray_slist_append_char(slist, 0);
- str = gray_slist_finish(slist);
- if (str)
- _pam_log(priority, "%s", str);
- else
- errno_to_pam(gray_slist_err(slist));
+
+ for (i = 0; i < xargc; i++) {
+ char *s;
+ if (i)
+ gray_slist_append(slist, " ", 1);
+ rc = gray_expand_string(pamh, xargv[i], &s);
+ if (rc != PAM_SUCCESS)
+ break;
+ gray_slist_append(slist, s, strlen(s));
+ free(s);
+ }
+ if (rc == PAM_SUCCESS) {
+ gray_slist_append_char(slist, 0);
+ str = gray_slist_finish(slist);
+ if (str)
+ _pam_log(priority, "%s", str);
+ else
+ errno_to_pam(gray_slist_err(slist));
+ }
+ gray_slist_free(&slist);
}
- gray_slist_free(&slist);
}
return PAM_IGNORE;
}
diff --git a/pam_sql/pam_mysql.c b/pam_sql/pam_mysql.c
index 3f4a0d6..a2e7c23 100644
--- a/pam_sql/pam_mysql.c
+++ b/pam_sql/pam_mysql.c
@@ -358,21 +358,16 @@ gpam_sql_verify_user_pass(pam_handle_t *pamh, const char *password,
rc = mysql_do_query(&mysql, query);
if (rc == PAM_SUCCESS) {
- const char *q;
- gray_slist_t slist;
-
+ char *q;
rc = check_query_result(&mysql, password);
/* FIXME: This comment is needed to pacify
`make check-sql-config' in doc:
gpam_sql_find_config("setenv-query") */
if (rc == PAM_SUCCESS) {
- rc = gpam_sql_get_query(pamh, "setenv-query", 0,
- &slist, &q);
+ rc = gpam_sql_get_query(pamh, "setenv-query", 0, &q);
if (rc == PAM_SUCCESS) {
- if (q) {
- mysql_setenv(pamh, &mysql, q);
- gray_slist_free(&slist);
- }
+ mysql_setenv(pamh, &mysql, q);
+ free(q);
}
}
mysql_close(&mysql);
diff --git a/pam_sql/pam_pgsql.c b/pam_sql/pam_pgsql.c
index 5f66b53..ed7a465 100644
--- a/pam_sql/pam_pgsql.c
+++ b/pam_sql/pam_pgsql.c
@@ -114,8 +114,7 @@ gpam_sql_verify_user_pass(pam_handle_t *pamh, const char *password,
} else {
char *p;
int n;
- gray_slist_t slist;
- char const *query;
+ char *query;
n = PQntuples(res);
DEBUG(20,("Returned %d tuples", n));
@@ -155,13 +154,10 @@ gpam_sql_verify_user_pass(pam_handle_t *pamh, const char *password,
`make check-sql-config' in doc:
gpam_sql_find_config("setenv-query") */
if (rc == PAM_SUCCESS) {
- rc = gpam_sql_get_query(pamh, "setenv-query", 0,
- &slist, &query);
+ rc = gpam_sql_get_query(pamh, "setenv-query", 0, &query);
if (rc == PAM_SUCCESS) {
- if (query) {
- pgsql_setenv(pamh, pgconn, query);
- gray_slist_free(&slist);
- }
+ pgsql_setenv(pamh, pgconn, query);
+ free(query);
}
}
}
diff --git a/pam_sql/pam_sql.c b/pam_sql/pam_sql.c
index 6707eb3..7a11df3 100644
--- a/pam_sql/pam_sql.c
+++ b/pam_sql/pam_sql.c
@@ -1,5 +1,5 @@
/* This file is part of pam-modules.
- Copyright (C) 2005-2008, 2010-2012, 2014-2015, 2018 Sergey Poznyakoff
+ Copyright (C) 2005-2020 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
@@ -161,11 +161,10 @@ gpam_sql_check_boolean_config(const char *name, int defval)
int
gpam_sql_get_query(pam_handle_t *pamh, const char *name, int required,
- gray_slist_t *pslist, const char **retptr)
+ char **retptr)
{
- gray_slist_t slist;
const char *query = gpam_sql_find_config(name);
- char *retval;
+ int rc;
if (!query) {
if (required) {
@@ -173,24 +172,13 @@ gpam_sql_get_query(pam_handle_t *pamh, const char *name, int required,
gpam_sql_config_file, name);
return PAM_AUTHINFO_UNAVAIL;
}
- *pslist = NULL;
*retptr = NULL;
return PAM_SUCCESS;
}
- slist = gray_slist_create();
- if (!slist)
- return errno_to_pam(errno);
- gray_expand_string(pamh, query, slist);
- gray_slist_append_char(slist, 0);
- *pslist = slist;
- retval = gray_slist_finish(slist);
- if (gray_slist_err(slist)) {
- int rc = errno_to_pam(gray_slist_err(slist));
- gray_slist_free(&slist);
+ rc = gray_expand_string(pamh, query, retptr);
+ if (rc != PAM_SUCCESS)
return rc;
- }
- *retptr = retval;
return PAM_SUCCESS;
}
@@ -226,18 +214,16 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv)
if (gray_env_read(gpam_sql_config_file, &config_env))
retval = PAM_SERVICE_ERR;
else {
- gray_slist_t slist;
- char const *query;
+ char *query;
/* FIXME: This comment is needed to pacify
`make check-sql-config' in doc:
gpam_sql_find_config("passwd-query") */
- retval = gpam_sql_get_query(pamh, "passwd-query", 1,
- &slist, &query);
+ retval = gpam_sql_get_query(pamh, "passwd-query", 1, &query);
if (retval == PAM_SUCCESS) {
retval = gpam_sql_verify_user_pass(pamh, password,
query);
- gray_slist_free(&slist);
+ free(query);
}
}
@@ -279,13 +265,13 @@ sql_session_mgmt(pam_handle_t *pamh, int flags,
retval = PAM_SERVICE_ERR;
else {
gray_slist_t slist;
- char const *query;
+ char *query;
- retval = gpam_sql_get_query(pamh, query_name, 0, &slist, &query);
+ retval = gpam_sql_get_query(pamh, query_name, 0, &query);
if (retval == PAM_SUCCESS) {
if (query) {
retval = gpam_sql_acct(pamh, query);
- gray_slist_free(&slist);
+ free(query);
}
}
}
diff --git a/pam_sql/pam_sql.h b/pam_sql/pam_sql.h
index 5dc9525..2515c32 100644
--- a/pam_sql/pam_sql.h
+++ b/pam_sql/pam_sql.h
@@ -48,7 +48,6 @@ int gpam_sql_acct(pam_handle_t *pamh, const char *query);
char *gpam_sql_find_config(const char *name);
int gpam_sql_get_query(pam_handle_t *pamh, char const *var,
- int required,
- gray_slist_t *pslist, const char **query);
+ int required, char **query);
int gpam_sql_check_boolean_config(const char *name, int defval);
diff --git a/pam_umotd/pam_umotd.c b/pam_umotd/pam_umotd.c
index 008e87b..3638aed 100644
--- a/pam_umotd/pam_umotd.c
+++ b/pam_umotd/pam_umotd.c
@@ -1,5 +1,5 @@
/* This file is part of pam-modules.
- Copyright (C) 2012, 2014-2015, 2018 Sergey Poznyakoff
+ Copyright (C) 2012-2020 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
@@ -314,11 +314,20 @@ exec_file(pam_handle_t *pamh, char **argv, const char *logfile)
return PAM_SUCCESS;
}
+static void
+argcv_free(int wc, char **wv)
+{
+ int i;
+
+ for (i = 0; i < wc; i++)
+ free(wv[i]);
+ free(wv);
+}
+
PAM_EXTERN int
pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv)
{
int retval = PAM_IGNORE;
- gray_slist_t slist;
cntl_flags = 0;
debug_level = 0;
@@ -338,22 +347,14 @@ pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv)
if (motd_file_name) {
char *file;
-
- slist = gray_slist_create();
- if (!slist)
- retval = errno_to_pam(errno);
- else {
- gray_expand_string(pamh, motd_file_name, slist);
- gray_slist_append_char(slist, 0);
- file = gray_slist_finish(slist);
- if (file)
- retval = read_file(pamh, file);
- else
- retval = errno_to_pam(errno);
+ retval = gray_expand_string(pamh, motd_file_name, &file);
+ if (retval == PAM_SUCCESS) {
+ retval = read_file(pamh, file);
+ free(file);
}
- gray_slist_free(&slist);
} else if (optindex >= 0) {
char **xargv;
+ int i;
argc -= optindex;
argv += optindex;
@@ -361,30 +362,21 @@ pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv)
_pam_log(LOG_INFO, "empty command line");
return retval;
}
- xargv = calloc((argc + 1), sizeof (xargv[0]));
+ xargv = calloc((argc + 1), sizeof(xargv[0]));
if (!xargv)
return errno_to_pam(errno);
- slist = gray_slist_create();
- if (!slist)
- retval = errno_to_pam(errno);
- else {
- int i;
- int ec;
-
- for (i = 0; i < argc; i++) {
- gray_expand_string(pamh, argv[i], slist);
- gray_slist_append_char(slist, 0);
- xargv[i] = gray_slist_finish(slist);
+ for (i = 0; i < argc; i++) {
+ retval = gray_expand_string(pamh, argv[i], &xargv[i]);
+ if (retval != PAM_SUCCESS) {
+ argc = i;
+ break;
}
+ }
+ if (retval == PAM_SUCCESS) {
xargv[i] = NULL;
- ec = gray_slist_err(slist);
- if (ec)
- retval = errno_to_pam(ec);
- else
- retval = exec_file(pamh, xargv, logfile_name);
- free(xargv);
- gray_slist_free(&slist);
+ retval = exec_file(pamh, xargv, logfile_name);
}
+ argcv_free(argc, xargv);
} else
_pam_log(LOG_ERR,
"invalid usage: either file or exec must be specified");

Return to:

Send suggestions and report system problems to the System administrator.