1/*++
2/* NAME
3/*	clean_env 3
4/* SUMMARY
5/*	clean up the environment
6/* SYNOPSIS
7/*	#include <clean_env.h>
8/*
9/*	void	clean_env(preserve_list)
10/*	const char **preserve_list;
11/* DESCRIPTION
12/*	clean_env() reduces the process environment to the bare minimum.
13/*	The function takes a null-terminated list of arguments.
14/*	Each argument specifies the name of an environment variable
15/*	that should be preserved, or specifies a name=value that should
16/*	be entered into the new environment.
17/* DIAGNOSTICS
18/*	Fatal error: out of memory.
19/* SEE ALSO
20/*	safe_getenv(3), guarded getenv()
21/* LICENSE
22/* .ad
23/* .fi
24/*	The Secure Mailer license must be distributed with this software.
25/* AUTHOR(S)
26/*	Wietse Venema
27/*	IBM T.J. Watson Research
28/*	P.O. Box 704
29/*	Yorktown Heights, NY 10598, USA
30/*--*/
31
32/* System library. */
33
34#include <sys_defs.h>
35#include <stdlib.h>
36#include <unistd.h>
37#include <string.h>
38
39/* Utility library. */
40
41#include <msg.h>
42#include <argv.h>
43#include <safe.h>
44#include <clean_env.h>
45
46/* clean_env - clean up the environment */
47
48void    clean_env(char **preserve_list)
49{
50    extern char **environ;
51    ARGV   *save_list;
52    char   *value;
53    char  **cpp;
54    char   *eq;
55
56    /*
57     * Preserve or specify selected environment variables.
58     */
59#define STRING_AND_LENGTH(x, y) (x), (ssize_t) (y)
60
61    save_list = argv_alloc(10);
62    for (cpp = preserve_list; *cpp; cpp++)
63	if ((eq = strchr(*cpp, '=')) != 0)
64	    argv_addn(save_list, STRING_AND_LENGTH(*cpp, eq - *cpp),
65		      STRING_AND_LENGTH(eq + 1, strlen(eq + 1)), (char *) 0);
66	else if ((value = safe_getenv(*cpp)) != 0)
67	    argv_add(save_list, *cpp, value, (char *) 0);
68
69    /*
70     * Truncate the process environment, if available. On some systems
71     * (Ultrix!), environ can be a null pointer.
72     */
73    if (environ)
74	environ[0] = 0;
75
76    /*
77     * Restore preserved environment variables.
78     */
79    for (cpp = save_list->argv; *cpp; cpp += 2)
80	if (setenv(cpp[0], cpp[1], 1))
81	    msg_fatal("setenv(%s, %s): %m", cpp[0], cpp[1]);
82
83    /*
84     * Cleanup.
85     */
86    argv_free(save_list);
87}
88