summaryrefslogtreecommitdiffstats
path: root/lib/libpam
diff options
context:
space:
mode:
authordumbbell <dumbbell@FreeBSD.org>2012-04-12 14:02:59 +0000
committerdumbbell <dumbbell@FreeBSD.org>2012-04-12 14:02:59 +0000
commitd6a537d930602e0c6bbc90382c52345098fb190e (patch)
tree9033e60d1628c7c25882c73dd925472313227df7 /lib/libpam
parent7e0aa0e933d2293b0968bdc27ace3e873c7a9230 (diff)
downloadFreeBSD-src-d6a537d930602e0c6bbc90382c52345098fb190e.zip
FreeBSD-src-d6a537d930602e0c6bbc90382c52345098fb190e.tar.gz
Fix error messages containing the executed command name
Before, we took the first argument to pam_exec(8). With the addition of options in front of the command, this could be wrong. Now, options are parsed before calling _pam_exec() and messages contain the proper command name. While here, fix a warning. Sponsored by: Yakaz (http://www.yakaz.com)
Diffstat (limited to 'lib/libpam')
-rw-r--r--lib/libpam/modules/pam_exec/pam_exec.c108
1 files changed, 77 insertions, 31 deletions
diff --git a/lib/libpam/modules/pam_exec/pam_exec.c b/lib/libpam/modules/pam_exec/pam_exec.c
index 0c66be0..d43d181 100644
--- a/lib/libpam/modules/pam_exec/pam_exec.c
+++ b/lib/libpam/modules/pam_exec/pam_exec.c
@@ -60,22 +60,17 @@ static struct {
ENV_ITEM(PAM_RUSER),
};
+struct pe_opts {
+ int return_prog_exit_status;
+};
+
#define PAM_RV_COUNT 24
static int
-_pam_exec(pam_handle_t *pamh __unused,
- const char *func, int flags __unused, int argc, const char *argv[])
+parse_options(const char *func, int *argc, const char **argv[],
+ struct pe_opts *options)
{
- int envlen, i, nitems, pam_err, status, return_prog_exit_status;
- int nitems_rv;
- char *env, **envlist, **tmp, *envstr;
- volatile int childerr;
- pid_t pid;
-
- /*
- * XXX For additional credit, divert child's stdin/stdout/stderr
- * to the conversation function.
- */
+ int i;
/*
* Parse options:
@@ -84,25 +79,45 @@ _pam_exec(pam_handle_t *pamh __unused,
* --:
* stop options parsing; what follows is the command to execute
*/
- return_prog_exit_status = 0;
- for (i = 0; i < argc; ++i) {
- if (strcmp(argv[i], "return_prog_exit_status") == 0) {
+ options->return_prog_exit_status = 0;
+
+ for (i = 0; i < *argc; ++i) {
+ if (strcmp((*argv)[i], "return_prog_exit_status") == 0) {
openpam_log(PAM_LOG_DEBUG,
"%s: Option \"return_prog_exit_status\" enabled",
func);
- return_prog_exit_status = 1;
+ options->return_prog_exit_status = 1;
} else {
- if (strcmp(argv[i], "--") == 0) {
- argc--;
- argv++;
+ if (strcmp((*argv)[i], "--") == 0) {
+ (*argc)--;
+ (*argv)++;
}
break;
}
}
- argc -= i;
- argv += i;
+ (*argc) -= i;
+ (*argv) += i;
+
+ return (0);
+}
+
+static int
+_pam_exec(pam_handle_t *pamh __unused,
+ const char *func, int flags __unused, int argc, const char *argv[],
+ struct pe_opts *options)
+{
+ int envlen, i, nitems, pam_err, status;
+ int nitems_rv;
+ char **envlist, **tmp, *envstr;
+ volatile int childerr;
+ pid_t pid;
+
+ /*
+ * XXX For additional credit, divert child's stdin/stdout/stderr
+ * to the conversation function.
+ */
/* Check there's a program name left after parsing options. */
if (argc < 1) {
@@ -122,7 +137,7 @@ _pam_exec(pam_handle_t *pamh __unused,
/* nothing */ ;
nitems = sizeof(env_items) / sizeof(*env_items);
/* Count PAM return values put in the environment. */
- nitems_rv = return_prog_exit_status ? PAM_RV_COUNT : 0;
+ nitems_rv = options->return_prog_exit_status ? PAM_RV_COUNT : 0;
tmp = realloc(envlist, (envlen + nitems + 1 + nitems_rv + 1) *
sizeof(*envlist));
if (tmp == NULL) {
@@ -136,7 +151,8 @@ _pam_exec(pam_handle_t *pamh __unused,
pam_err = pam_get_item(pamh, env_items[i].item, &item);
if (pam_err != PAM_SUCCESS || item == NULL)
continue;
- asprintf(&envstr, "%s=%s", env_items[i].name, item);
+ asprintf(&envstr, "%s=%s", env_items[i].name,
+ (const char *)item);
if (envstr == NULL) {
openpam_free_envlist(envlist);
return (PAM_BUF_ERR);
@@ -154,7 +170,7 @@ _pam_exec(pam_handle_t *pamh __unused,
envlist[envlen++] = envstr;
/* Add the PAM return values to the environment. */
- if (return_prog_exit_status) {
+ if (options->return_prog_exit_status) {
#define ADD_PAM_RV_TO_ENV(name) \
asprintf(&envstr, #name "=%d", name); \
if (envstr == NULL) { \
@@ -232,7 +248,7 @@ _pam_exec(pam_handle_t *pamh __unused,
return (PAM_SERVICE_ERR);
}
- if (return_prog_exit_status) {
+ if (options->return_prog_exit_status) {
openpam_log(PAM_LOG_DEBUG,
"%s: Use program exit status as return value: %d",
func, WEXITSTATUS(status));
@@ -248,8 +264,13 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags,
int argc, const char *argv[])
{
int ret;
+ struct pe_opts options;
- ret = _pam_exec(pamh, __func__, flags, argc, argv);
+ ret = parse_options(__func__, &argc, &argv, &options);
+ if (ret != 0)
+ return (PAM_SERVICE_ERR);
+
+ ret = _pam_exec(pamh, __func__, flags, argc, argv, &options);
/*
* We must check that the program returned a valid code for this
@@ -284,8 +305,13 @@ pam_sm_setcred(pam_handle_t *pamh, int flags,
int argc, const char *argv[])
{
int ret;
+ struct pe_opts options;
- ret = _pam_exec(pamh, __func__, flags, argc, argv);
+ ret = parse_options(__func__, &argc, &argv, &options);
+ if (ret != 0)
+ return (PAM_SERVICE_ERR);
+
+ ret = _pam_exec(pamh, __func__, flags, argc, argv, &options);
/*
* We must check that the program returned a valid code for this
@@ -319,8 +345,13 @@ pam_sm_acct_mgmt(pam_handle_t *pamh, int flags,
int argc, const char *argv[])
{
int ret;
+ struct pe_opts options;
+
+ ret = parse_options(__func__, &argc, &argv, &options);
+ if (ret != 0)
+ return (PAM_SERVICE_ERR);
- ret = _pam_exec(pamh, __func__, flags, argc, argv);
+ ret = _pam_exec(pamh, __func__, flags, argc, argv, &options);
/*
* We must check that the program returned a valid code for this
@@ -354,8 +385,13 @@ pam_sm_open_session(pam_handle_t *pamh, int flags,
int argc, const char *argv[])
{
int ret;
+ struct pe_opts options;
+
+ ret = parse_options(__func__, &argc, &argv, &options);
+ if (ret != 0)
+ return (PAM_SERVICE_ERR);
- ret = _pam_exec(pamh, __func__, flags, argc, argv);
+ ret = _pam_exec(pamh, __func__, flags, argc, argv, &options);
/*
* We must check that the program returned a valid code for this
@@ -386,8 +422,13 @@ pam_sm_close_session(pam_handle_t *pamh, int flags,
int argc, const char *argv[])
{
int ret;
+ struct pe_opts options;
- ret = _pam_exec(pamh, __func__, flags, argc, argv);
+ ret = parse_options(__func__, &argc, &argv, &options);
+ if (ret != 0)
+ return (PAM_SERVICE_ERR);
+
+ ret = _pam_exec(pamh, __func__, flags, argc, argv, &options);
/*
* We must check that the program returned a valid code for this
@@ -418,8 +459,13 @@ pam_sm_chauthtok(pam_handle_t *pamh, int flags,
int argc, const char *argv[])
{
int ret;
+ struct pe_opts options;
+
+ ret = parse_options(__func__, &argc, &argv, &options);
+ if (ret != 0)
+ return (PAM_SERVICE_ERR);
- ret = _pam_exec(pamh, __func__, flags, argc, argv);
+ ret = _pam_exec(pamh, __func__, flags, argc, argv, &options);
/*
* We must check that the program returned a valid code for this
OpenPOWER on IntegriCloud