aboutsummaryrefslogtreecommitdiff
path: root/lib/lib.c
diff options
context:
space:
mode:
authorRob Landley <rob@landley.net>2019-03-07 21:04:25 -0600
committerRob Landley <rob@landley.net>2019-03-07 21:04:25 -0600
commite191597e6bbf03e920e1b42f44ac65faaddedf51 (patch)
tree1df440763287236d530ad379165e0f4f67348c8c /lib/lib.c
parentf8ba1d6d8a9a6023bd28c19a43580d768f45c199 (diff)
downloadtoybox-e191597e6bbf03e920e1b42f44ac65faaddedf51.tar.gz
Add reset_env() and make su and login use it. Do long-delayed login cleanup.
Diffstat (limited to 'lib/lib.c')
-rw-r--r--lib/lib.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/lib/lib.c b/lib/lib.c
index 54bfc8c4..d1210f49 100644
--- a/lib/lib.c
+++ b/lib/lib.c
@@ -122,6 +122,7 @@ ssize_t readall(int fd, void *buf, size_t len)
ssize_t writeall(int fd, void *buf, size_t len)
{
size_t count = 0;
+
while (count<len) {
int i = write(fd, count+(char *)buf, len-count);
if (i<1) return i;
@@ -1427,3 +1428,37 @@ char *format_iso_time(char *buf, size_t len, struct timespec *ts)
return buf;
}
+
+// reset environment for a user, optionally clearing most of it
+void reset_env(struct passwd *p, int clear)
+{
+ int i;
+
+ if (clear) {
+ char *s, *stuff[] = {"TERM", "DISPLAY", "COLORTERM", "XAUTHORITY"};
+
+ for (i=0; i<ARRAY_LEN(stuff); i++)
+ stuff[i] = (s = getenv(stuff[i])) ? xmprintf("%s=%s", stuff[i], s) : 0;
+ clearenv();
+ for (i=0; i < ARRAY_LEN(stuff); i++) if (stuff[i]) putenv(stuff[i]);
+ if (chdir(p->pw_dir)) {
+ perror_msg("chdir %s", p->pw_dir);
+ xchdir("/");
+ }
+ } else {
+ char **ev1, **ev2;
+
+ // remove LD_*, IFS, ENV, and BASH_ENV from environment
+ for (ev1 = ev2 = environ;;) {
+ while (*ev2 && (strstart(ev2, "LD_") || strstart(ev2, "IFS=") ||
+ strstart(ev2, "ENV=") || strstart(ev2, "BASH_ENV="))) ev2++;
+ if (!(*ev1++ = *ev2++)) break;
+ }
+ }
+
+ setenv("PATH", _PATH_DEFPATH, 1);
+ setenv("HOME", p->pw_dir, 1);
+ setenv("SHELL", p->pw_shell, 1);
+ setenv("USER", p->pw_name, 1);
+ setenv("LOGNAME", p->pw_name, 1);
+}