]> git.armaanb.net Git - opendoas.git/blobdiff - env.c
more precisely describe what happens to the environment without keepenv; OK tedu@
[opendoas.git] / env.c
diff --git a/env.c b/env.c
index 42a0d2e1856f8c766c87338ef95b5bd33d74bf3f..2090897ea1738601eb9b82efe25d37b8660a4541 100644 (file)
--- a/env.c
+++ b/env.c
 #include <err.h>
 #include <unistd.h>
 #include <errno.h>
+#include <pwd.h>
 
 #include "doas.h"
 #include "includes.h"
 
+const char *formerpath;
+
 struct envnode {
        RB_ENTRY(envnode) node;
        const char *key;
@@ -39,6 +42,8 @@ struct env {
        u_int count;
 };
 
+static void fillenv(struct env *env, const char **envlist);
+
 static int
 envcmp(struct envnode *a, struct envnode *b)
 {
@@ -69,9 +74,24 @@ freenode(struct envnode *node)
        free(node);
 }
 
+static void
+addnode(struct env *env, const char *key, const char *value)
+{
+       struct envnode *node;
+
+       node = createnode(key, value);
+       RB_INSERT(envtree, &env->root, node);
+       env->count++;
+}
+
 static struct env *
-createenv(struct rule *rule)
+createenv(const struct rule *rule, const struct passwd *mypw,
+    const struct passwd *targpw)
 {
+       static const char *copyset[] = {
+               "DISPLAY", "TERM",
+               NULL
+       };
        struct env *env;
        u_int i;
 
@@ -81,8 +101,17 @@ createenv(struct rule *rule)
        RB_INIT(&env->root);
        env->count = 0;
 
+       addnode(env, "DOAS_USER", mypw->pw_name);
+       addnode(env, "HOME", targpw->pw_dir);
+       addnode(env, "LOGNAME", targpw->pw_name);
+       addnode(env, "PATH", getenv("PATH"));
+       addnode(env, "SHELL", targpw->pw_shell);
+       addnode(env, "USER", targpw->pw_name);
+
+       fillenv(env, copyset);
+
        if (rule->options & KEEPENV) {
-               extern const char **environ;
+               extern char **environ;
 
                for (i = 0; environ[i] != NULL; i++) {
                        struct envnode *node;
@@ -172,8 +201,12 @@ fillenv(struct env *env, const char **envlist)
                /* assign value or inherit from environ */
                if (eq) {
                        val = eq + 1;
-                       if (*val == '$')
-                               val = getenv(val + 1);
+                       if (*val == '$') {
+                               if (strcmp(val + 1, "PATH") == 0)
+                                       val = formerpath;
+                               else
+                                       val = getenv(val + 1);
+                       }
                } else {
                        val = getenv(name);
                }
@@ -187,20 +220,12 @@ fillenv(struct env *env, const char **envlist)
 }
 
 char **
-prepenv(struct rule *rule)
+prepenv(const struct rule *rule, const struct passwd *mypw,
+    const struct passwd *targpw)
 {
-       static const char *safeset[] = {
-               "DISPLAY", "HOME", "LOGNAME", "MAIL",
-               "PATH", "TERM", "USER", "USERNAME",
-               NULL
-       };
        struct env *env;
-       
-       env = createenv(rule);
 
-       /* if we started with blank, fill some defaults then apply rules */
-       if (!(rule->options & KEEPENV))
-               fillenv(env, safeset);
+       env = createenv(rule, mypw, targpw);
        if (rule->envlist)
                fillenv(env, rule->envlist);