summaryrefslogtreecommitdiffstats
path: root/crypto/kerberosIV/appl/bsd/sysv_environ.c
blob: 3df800eb1333e6a69aa388c316b41dae1b4133ed (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
/* Author: Wietse Venema <wietse@wzv.win.tue.nl> */

#include "bsd_locl.h"

RCSID("$Id: sysv_environ.c,v 1.23 1997/12/14 23:50:44 assar Exp $");

#ifdef HAVE_ULIMIT_H
#include <ulimit.h>
#endif

#ifndef UL_SETFSIZE
#define UL_SETFSIZE 2
#endif

#include "sysv_default.h"

/*
 * Set 
 */

static void
read_etc_environment (void)
{
    FILE *f;
    char buf[BUFSIZ];

    f = fopen(_PATH_ETC_ENVIRONMENT, "r");
    if (f) {
	char *val;

	while (fgets (buf, sizeof(buf), f) != NULL) {
	    if (buf[0] == '\n' || buf[0] == '#')
		continue;
	    buf[strlen(buf) - 1] = '\0';
	    val = strchr (buf, '=');
	    if (val == NULL)
		continue;
	    *val = '\0';
	    setenv(buf, val + 1, 1);
	}
	fclose (f);
    }
}

 /*
  * Environment variables that are preserved (but may still be overruled by
  * other means). Only TERM and TZ appear to survive (SunOS 5.1). These are
  * typically inherited from the ttymon process.
  */

static struct preserved {
    char   *name;
    char   *value;
} preserved[] = {
    {"TZ", 0},
    {"TERM", 0},
    {0},
};

 /*
  * Environment variables that are not preserved and that cannot be specified
  * via commandline or stdin. Except for the LD_xxx (runtime linker) stuff,
  * the list applies to most SYSV systems. The manpage mentions only that
  * SHELL and PATH are censored. HOME, LOGNAME and MAIL are always
  * overwritten; they are in the list to make the censoring explicit.
  */

static struct censored {
    char   *prefix;
    int     length;
} censored[] = {
  {"SHELL=",	sizeof("SHELL=") - 1},
     {"HOME=",	sizeof("HOME=") - 1},
     {"LOGNAME=",	sizeof("LOGNAME=") - 1},
     {"MAIL=",	sizeof("MAIL=") - 1},
     {"CDPATH=",	sizeof("CDPATH=") - 1},
     {"IFS=",	sizeof("IFS=") - 1},
     {"PATH=",	sizeof("PATH=") - 1},
    {"LD_",	sizeof("LD_") - 1},
    {0},
};

/* sysv_newenv - set up final environment after logging in */

void sysv_newenv(int argc, char **argv, struct passwd *pwd,
		 char *term, int pflag)
{
    unsigned umask_val;
    char    buf[BUFSIZ];
    int     count = 0;
    struct censored *cp;
    struct preserved *pp;

    /* Preserve a selection of the environment. */

    for (pp = preserved; pp->name; pp++)
	pp->value = getenv(pp->name);

    /*
     * Note: it is a bad idea to assign a static array to the global environ
     * variable. Reason is that putenv() can run into problems when it tries
     * to realloc() the environment table. Instead, we just clear environ[0]
     * and let putenv() work things out.
     */

    if (!pflag && environ)
	environ[0] = 0;

    /* Restore preserved environment variables. */

    for (pp = preserved; pp->name; pp++)
	if (pp->value)
	    setenv(pp->name, pp->value, 1);

    /* The TERM definition from e.g. rlogind can override an existing one. */

    if (term[0])
	setenv("TERM", term, 1);

    /*
     * Environment definitions from the command line overrule existing ones,
     * but can be overruled by definitions from stdin. Some variables are
     * censored.
     * 
     * Omission: we do not support environment definitions from stdin.
     */

#define STREQN(x,y,l) (x[0] == y[0] && strncmp(x,y,l) == 0)

    while (argc && *argv) {
	if (strchr(*argv, '=') == 0) {
	    snprintf(buf, sizeof(buf), "L%d", count++);
	    setenv(buf, *argv, 1);
	} else {
	    for (cp = censored; cp->prefix; cp++)
		if (STREQN(*argv, cp->prefix, cp->length))
		    break;
	    if (cp->prefix == 0)
		putenv(*argv);
	}
	argc--, argv++;
    }

    /* PATH is always reset. */

    setenv("PATH", pwd->pw_uid ? default_path : default_supath, 1);

    /* Undocumented: HOME, MAIL and LOGNAME are always reset (SunOS 5.1). */

    setenv("HOME", pwd->pw_dir, 1);
    {
	char *sep = "/";
	if(KRB4_MAILDIR[strlen(KRB4_MAILDIR) - 1] == '/')
	    sep = "";
	roken_concat(buf, sizeof(buf), KRB4_MAILDIR, sep, pwd->pw_name, NULL);
    }
    setenv("MAIL", buf, 1);
    setenv("LOGNAME", pwd->pw_name, 1);
    setenv("USER", pwd->pw_name, 1);

    /*
     * Variables that may be set according to specifications in the defaults
     * file. HZ and TZ are set only if they are still uninitialized.
     * 
     * Extension: when ALTSHELL=YES, we set the SHELL variable even if it is
     * /bin/sh.
     */

    if (strcasecmp(default_altsh, "YES") == 0)
	setenv("SHELL", pwd->pw_shell, 1);
    if (default_hz)
	setenv("HZ", default_hz, 0);
    if (default_timezone)
	setenv("TZ", default_timezone, 0);

    /* Non-environment stuff. */

    if (default_umask) {
	if (sscanf(default_umask, "%o", &umask_val) == 1 && umask_val)
	    umask(umask_val);
    }
#ifdef HAVE_ULIMIT
    if (default_ulimit) {
	long    limit_val;

	if (sscanf(default_ulimit, "%ld", &limit_val) == 1 && limit_val)
	    if (ulimit(UL_SETFSIZE, limit_val) < 0)
	        warn ("ulimit(UL_SETFSIZE, %ld)", limit_val);
    }
#endif
    read_etc_environment();
}

OpenPOWER on IntegriCloud