summaryrefslogtreecommitdiffstats
path: root/lib/libpam/modules
diff options
context:
space:
mode:
authordes <des@FreeBSD.org>2005-02-01 10:37:07 +0000
committerdes <des@FreeBSD.org>2005-02-01 10:37:07 +0000
commitb0d098fb3c0b0335d47a860cc6fb174948400795 (patch)
tree65d57a59486631e60b35f8fa1de4a06222ab3897 /lib/libpam/modules
parent23d6a7f7bdf09e516a012868a7fca7637293c628 (diff)
downloadFreeBSD-src-b0d098fb3c0b0335d47a860cc6fb174948400795.zip
FreeBSD-src-b0d098fb3c0b0335d47a860cc6fb174948400795.tar.gz
In addition to the PAM environment, export a handful of useful PAM items.
Suggested by: Ed Maste <emaste@phaedrus.sandvine.ca>
Diffstat (limited to 'lib/libpam/modules')
-rw-r--r--lib/libpam/modules/pam_exec/pam_exec.811
-rw-r--r--lib/libpam/modules/pam_exec/pam_exec.c59
2 files changed, 62 insertions, 8 deletions
diff --git a/lib/libpam/modules/pam_exec/pam_exec.8 b/lib/libpam/modules/pam_exec/pam_exec.8
index c07ff26..d7e5308 100644
--- a/lib/libpam/modules/pam_exec/pam_exec.8
+++ b/lib/libpam/modules/pam_exec/pam_exec.8
@@ -32,7 +32,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd February 6, 2003
+.Dd February 1, 2005
.Dt PAM_EXEC 8
.Os
.Sh NAME
@@ -51,8 +51,17 @@ arguments.
The child's environment is set to the current PAM environment list,
as returned by
.Xr pam_getenvlist 3 .
+In addition, the following PAM items are exported as environment
+variables:
+.Ev PAM_RHOST ,
+.Ev PAM_RUSER ,
+.Ev PAM_SERVICE ,
+.Ev PAM_TTY ,
+and
+.Ev PAM_USER .
.Sh SEE ALSO
.Xr pam.conf 5 ,
+.Xr pam_get_item 3 ,
.Xr pam 8
.Sh AUTHORS
The
diff --git a/lib/libpam/modules/pam_exec/pam_exec.c b/lib/libpam/modules/pam_exec/pam_exec.c
index b59a9d3..620dc0d 100644
--- a/lib/libpam/modules/pam_exec/pam_exec.c
+++ b/lib/libpam/modules/pam_exec/pam_exec.c
@@ -47,12 +47,24 @@ __FBSDID("$FreeBSD$");
#include <security/pam_modules.h>
#include <security/openpam.h>
+#define ENV_ITEM(n) { (n), #n }
+static struct {
+ int item;
+ const char *name;
+} env_items[] = {
+ ENV_ITEM(PAM_SERVICE),
+ ENV_ITEM(PAM_USER),
+ ENV_ITEM(PAM_TTY),
+ ENV_ITEM(PAM_RHOST),
+ ENV_ITEM(PAM_RUSER),
+};
+
static int
_pam_exec(pam_handle_t *pamh __unused, int flags __unused,
int argc, const char *argv[])
{
- int childerr, status;
- char **env, **envlist;
+ int childerr, envlen, i, nitems, pam_err, status;
+ char *env, **envlist, **tmp;
pid_t pid;
if (argc < 1)
@@ -62,16 +74,49 @@ _pam_exec(pam_handle_t *pamh __unused, int flags __unused,
* XXX For additional credit, divert child's stdin/stdout/stderr
* to the conversation function.
*/
+
+ /*
+ * Set up the child's environment list. It consists of the PAM
+ * environment, plus a few hand-picked PAM items.
+ */
envlist = pam_getenvlist(pamh);
+ for (envlen = 0; envlist[envlen] != NULL; ++envlen)
+ /* nothing */ ;
+ nitems = sizeof(env_items) / sizeof(*env_items);
+ tmp = realloc(envlist, (envlen + nitems + 1) * sizeof **envlist);
+ if (tmp == NULL) {
+ openpam_free_envlist(envlist);
+ return (PAM_BUF_ERR);
+ }
+ envlist = tmp;
+ for (i = 0; i < nitems; ++i) {
+ const void *item;
+ char *envstr;
+
+ 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);
+ if (envstr == NULL) {
+ openpam_free_envlist(envlist);
+ return (PAM_BUF_ERR);
+ }
+ envlist[envlen++] = envstr;
+ envlist[envlen] = NULL;
+ }
+
+ /*
+ * Fork and run the command. By using vfork() instead of fork(),
+ * we can distinguish between an execve() failure and a non-zero
+ * exit code from the command.
+ */
childerr = 0;
if ((pid = vfork()) == 0) {
- execve(argv[0], argv, envlist);
+ execve(argv[0], (char * const *)argv, (char * const *)envlist);
childerr = errno;
_exit(1);
}
- for (env = envlist; *env != NULL; ++env)
- free(*env);
- free(envlist);
+ openpam_free_envlist(envlist);
if (pid == -1) {
openpam_log(PAM_LOG_ERROR, "vfork(): %m");
return (PAM_SYSTEM_ERR);
@@ -81,7 +126,7 @@ _pam_exec(pam_handle_t *pamh __unused, int flags __unused,
return (PAM_SYSTEM_ERR);
}
if (childerr != 0) {
- openpam_log(PAM_LOG_ERROR, "execv(): %m");
+ openpam_log(PAM_LOG_ERROR, "execve(): %m");
return (PAM_SYSTEM_ERR);
}
if (WIFSIGNALED(status)) {
OpenPOWER on IntegriCloud