1 /* $NetBSD: clean_env.c,v 1.3 2023/12/23 20:30:46 christos Exp $ */
2
3 /*++
4 /* NAME
5 /* clean_env 3
6 /* SUMMARY
7 /* clean up the environment
8 /* SYNOPSIS
9 /* #include <clean_env.h>
10 /*
11 /* void clean_env(preserve_list)
12 /* const char **preserve_list;
13 /*
14 /* void update_env(preserve_list)
15 /* const char **preserve_list;
16 /* DESCRIPTION
17 /* clean_env() reduces the process environment to the bare minimum.
18 /* The function takes a null-terminated list of arguments.
19 /* Each argument specifies the name of an environment variable
20 /* that should be preserved, or specifies a name=value that should
21 /* be entered into the new environment.
22 /*
23 /* update_env() applies name=value settings, but otherwise does not
24 /* change the process environment.
25 /* DIAGNOSTICS
26 /* Fatal error: out of memory.
27 /* SEE ALSO
28 /* safe_getenv(3), guarded getenv()
29 /* LICENSE
30 /* .ad
31 /* .fi
32 /* The Secure Mailer license must be distributed with this software.
33 /* AUTHOR(S)
34 /* Wietse Venema
35 /* IBM T.J. Watson Research
36 /* P.O. Box 704
37 /* Yorktown Heights, NY 10598, USA
38 /*
39 /* Wietse Venema
40 /* Google, Inc.
41 /* 111 8th Avenue
42 /* New York, NY 10011, USA
43 /*--*/
44
45 /* System library. */
46
47 #include <sys_defs.h>
48 #include <stdlib.h>
49 #include <unistd.h>
50 #include <string.h>
51
52 /* Utility library. */
53
54 #include <msg.h>
55 #include <mymalloc.h>
56 #include <argv.h>
57 #include <safe.h>
58 #include <clean_env.h>
59 #include <stringops.h>
60
61 /* clean_env - clean up the environment */
62
clean_env(char ** preserve_list)63 void clean_env(char **preserve_list)
64 {
65 extern char **environ;
66 ARGV *save_list;
67 char *value;
68 char **cpp;
69 char *copy;
70 char *key;
71 char *val;
72 const char *err;
73
74 /*
75 * Preserve or specify selected environment variables.
76 */
77 save_list = argv_alloc(10);
78 for (cpp = preserve_list; *cpp; cpp++) {
79 if (strchr(*cpp, '=') != 0) {
80 copy = mystrdup(*cpp);
81 err = split_nameval(copy, &key, &val);
82 if (err != 0)
83 msg_fatal("clean_env: %s in: %s", err, *cpp);
84 argv_add(save_list, key, val, (char *) 0);
85 myfree(copy);
86 } else if ((value = safe_getenv(*cpp)) != 0) {
87 argv_add(save_list, *cpp, value, (char *) 0);
88 }
89 }
90
91 /*
92 * Truncate the process environment, if available. On some systems
93 * (Ultrix!), environ can be a null pointer.
94 */
95 if (environ)
96 environ[0] = 0;
97
98 /*
99 * Restore preserved environment variables.
100 */
101 for (cpp = save_list->argv; *cpp; cpp += 2)
102 if (setenv(cpp[0], cpp[1], 1))
103 msg_fatal("setenv(%s, %s): %m", cpp[0], cpp[1]);
104
105 /*
106 * Cleanup.
107 */
108 argv_free(save_list);
109 }
110
111 /* update_env - apply name=value settings only */
112
update_env(char ** preserve_list)113 void update_env(char **preserve_list)
114 {
115 char **cpp;
116 ARGV *save_list;
117 char *copy;
118 char *key;
119 char *val;
120 const char *err;
121
122 /*
123 * Extract name=value settings.
124 */
125 save_list = argv_alloc(10);
126 for (cpp = preserve_list; *cpp; cpp++) {
127 if (strchr(*cpp, '=') != 0) {
128 copy = mystrdup(*cpp);
129 err = split_nameval(copy, &key, &val);
130 if (err != 0)
131 msg_fatal("update_env: %s in: %s", err, *cpp);
132 argv_add(save_list, key, val, (char *) 0);
133 myfree(copy);
134 }
135 }
136
137 /*
138 * Apply name=value settings.
139 */
140 for (cpp = save_list->argv; *cpp; cpp += 2)
141 if (setenv(cpp[0], cpp[1], 1))
142 msg_fatal("setenv(%s, %s): %m", cpp[0], cpp[1]);
143
144 /*
145 * Cleanup.
146 */
147 argv_free(save_list);
148 }
149
150 #ifdef TEST
151
152 #include <stdlib.h>
153 #include <vstream.h>
154
main(int argc,char ** argv)155 int main(int argc, char **argv)
156 {
157 extern char **environ;
158 char **cpp;
159
160 clean_env(argv + 1);
161 for (cpp = environ; *cpp; cpp++)
162 vstream_printf("%s\n", *cpp);
163 vstream_fflush(VSTREAM_OUT);
164 exit(0);
165 }
166
167 #endif
168