Postfix3.3.1
mail_conf.c
[詳解]
1 /*++
2 /* NAME
3 /* mail_conf 3
4 /* SUMMARY
5 /* global configuration parameter management
6 /* SYNOPSIS
7 /* #include <mail_conf.h>
8 /*
9 /* void mail_conf_read()
10 /*
11 /* void mail_conf_suck()
12 /*
13 /* void mail_conf_flush()
14 /*
15 /* void mail_conf_checkdir(config_dir)
16 /* const char *config_dir;
17 /*
18 /* void mail_conf_update(name, value)
19 /* const char *name;
20 /* const char *value;
21 /*
22 /* const char *mail_conf_lookup(name)
23 /* const char *name;
24 /*
25 /* const char *mail_conf_eval(string)
26 /* const char *string;
27 /*
28 /* const char *mail_conf_eval_once(string)
29 /* const char *string;
30 /*
31 /* const char *mail_conf_lookup_eval(name)
32 /* const char *name;
33 /* DESCRIPTION
34 /* mail_conf_suck() reads the global Postfix configuration
35 /* file, and stores its values into a global configuration
36 /* dictionary. When the configuration directory name is not
37 /* trusted, this function requires that the directory name is
38 /* authorized with the alternate_config_directories setting
39 /* in the default main.cf file.
40 /*
41 /* This function requires that all configuration directory
42 /* override mechanisms set the MAIL_CONFIG environment variable,
43 /* even if the override was specified via the command line.
44 /* This reduces the number of pathways that need to be checked
45 /* for possible security attacks.
46 /*
47 /* mail_conf_read() invokes mail_conf_suck() and assigns the values
48 /* to global variables by calling mail_params_init().
49 /*
50 /* mail_conf_flush() discards the global configuration dictionary.
51 /* This is needed in programs that read main.cf multiple times, to
52 /* ensure that deleted parameter settings are handled properly.
53 /*
54 /* mail_conf_checkdir() verifies that configuration directory
55 /* is authorized through settings in the default main.cf file,
56 /* and terminates the program if it is not.
57 /*
58 /* The following routines are wrappers around the generic dictionary
59 /* access routines.
60 /*
61 /* mail_conf_update() updates the named global parameter. This has
62 /* no effect on parameters whose value has already been looked up.
63 /* The update succeeds or the program terminates with fatal error.
64 /*
65 /* mail_conf_lookup() looks up the value of the named parameter.
66 /* A null pointer result means the parameter was not found.
67 /* The result is volatile and should be copied if it is to be
68 /* used for any appreciable amount of time.
69 /*
70 /* mail_conf_eval() recursively expands any $parameters in the
71 /* string argument. The result is volatile and should be copied
72 /* if it is to be used for any appreciable amount of time.
73 /*
74 /* mail_conf_eval_once() non-recursively expands any $parameters
75 /* in the string argument. The result is volatile and should
76 /* be copied if it is to be used for any appreciable amount
77 /* of time.
78 /*
79 /* mail_conf_lookup_eval() looks up the named parameter, and expands any
80 /* $parameters in the result. The result is volatile and should be
81 /* copied if it is to be used for any appreciable amount of time.
82 /* DIAGNOSTICS
83 /* Fatal errors: malformed numerical value.
84 /* ENVIRONMENT
85 /* MAIL_CONFIG, non-default configuration database
86 /* MAIL_VERBOSE, enable verbose mode
87 /* FILES
88 /* /etc/postfix: default Postfix configuration directory.
89 /* SEE ALSO
90 /* dict(3) generic dictionary manager
91 /* mail_conf_int(3) integer-valued parameters
92 /* mail_conf_str(3) string-valued parameters
93 /* LICENSE
94 /* .ad
95 /* .fi
96 /* The Secure Mailer license must be distributed with this software.
97 /* AUTHOR(S)
98 /* Wietse Venema
99 /* IBM T.J. Watson Research
100 /* P.O. Box 704
101 /* Yorktown Heights, NY 10598, USA
102 /*
103 /* Wietse Venema
104 /* Google, Inc.
105 /* 111 8th Avenue
106 /* New York, NY 10011, USA
107 /*--*/
108 
109 /* System library. */
110 
111 #include <sys_defs.h>
112 #include <unistd.h>
113 #include <stdlib.h>
114 #include <string.h>
115 
116 /* Utility library. */
117 
118 #include <msg.h>
119 #include <mymalloc.h>
120 #include <vstream.h>
121 #include <vstring.h>
122 #include <dict.h>
123 #include <safe.h>
124 #include <stringops.h>
125 #include <readlline.h>
126 
127 /* Global library. */
128 
129 #include "mail_params.h"
130 #include "mail_conf.h"
131 
132 /* mail_conf_checkdir - authorize non-default directory */
133 
134 void mail_conf_checkdir(const char *config_dir)
135 {
136  VSTRING *buf;
137  VSTREAM *fp;
138  char *path;
139  char *name;
140  char *value;
141  char *cp;
142  int found = 0;
143 
144  /*
145  * If running set-[ug]id, require that a non-default configuration
146  * directory name is blessed as a bona fide configuration directory in
147  * the default main.cf file.
148  */
149  path = concatenate(DEF_CONFIG_DIR, "/", "main.cf", (char *) 0);
150  if ((fp = vstream_fopen(path, O_RDONLY, 0)) == 0)
151  msg_fatal("open file %s: %m", path);
152 
153  buf = vstring_alloc(1);
154  while (found == 0 && readlline(buf, fp, (int *) 0)) {
155  if (split_nameval(vstring_str(buf), &name, &value) == 0
156  && (strcmp(name, VAR_CONFIG_DIRS) == 0
157  || strcmp(name, VAR_MULTI_CONF_DIRS) == 0)) {
158  while (found == 0 && (cp = mystrtok(&value, CHARS_COMMA_SP)) != 0)
159  if (strcmp(cp, config_dir) == 0)
160  found = 1;
161  }
162  }
163  if (vstream_fclose(fp))
164  msg_fatal("read file %s: %m", path);
165  vstring_free(buf);
166 
167  if (found == 0) {
168  msg_error("unauthorized configuration directory name: %s", config_dir);
169  msg_fatal("specify \"%s = %s\" or \"%s = %s\" in %s",
170  VAR_CONFIG_DIRS, config_dir,
171  VAR_MULTI_CONF_DIRS, config_dir, path);
172  }
173  myfree(path);
174 }
175 
176 /* mail_conf_read - read global configuration file */
177 
178 void mail_conf_read(void)
179 {
180  mail_conf_suck();
182 }
183 
184 /* mail_conf_suck - suck in the global configuration file */
185 
186 void mail_conf_suck(void)
187 {
188  char *config_dir;
189  char *path;
190 
191  /*
192  * The code below requires that all configuration directory override
193  * mechanisms set the CONF_ENV_PATH environment variable, even if the
194  * override was specified via the command line. This reduces the number
195  * of pathways that need to be checked for possible security attacks.
196  *
197  * Note: this code necessarily runs before cleanenv() can enforce the
198  * import_environment scrubbing policy.
199  */
200 
201  /*
202  * Permit references to unknown configuration variable names. We rely on
203  * a separate configuration checking tool to spot misspelled names and
204  * other kinds of trouble. Enter the configuration directory into the
205  * default dictionary.
206  */
207  if (var_config_dir)
209  if ((config_dir = getenv(CONF_ENV_PATH)) == 0)
210  config_dir = DEF_CONFIG_DIR;
211  var_config_dir = mystrdup(config_dir);
213 
214  /*
215  * If the configuration directory name comes from an untrusted source,
216  * require that it is listed in the default main.cf file.
217  */
218  if (strcmp(var_config_dir, DEF_CONFIG_DIR) != 0 /* non-default */
219  && unsafe()) /* untrusted env and cli */
221  path = concatenate(var_config_dir, "/", "main.cf", (char *) 0);
222  if (dict_load_file_xt(CONFIG_DICT, path) == 0)
223  msg_fatal("open %s: %m", path);
224  myfree(path);
225 }
226 
227 /* mail_conf_flush - discard configuration dictionary */
228 
229 void mail_conf_flush(void)
230 {
231  if (dict_handle(CONFIG_DICT) != 0)
233 }
234 
235 /* mail_conf_eval - expand macros in string */
236 
237 const char *mail_conf_eval(const char *string)
238 {
239 #define RECURSIVE 1
240 
241  return (dict_eval(CONFIG_DICT, string, RECURSIVE));
242 }
243 
244 /* mail_conf_eval_once - expand one level of macros in string */
245 
246 const char *mail_conf_eval_once(const char *string)
247 {
248 #define NONRECURSIVE 0
249 
250  return (dict_eval(CONFIG_DICT, string, NONRECURSIVE));
251 }
252 
253 /* mail_conf_lookup - lookup named variable */
254 
255 const char *mail_conf_lookup(const char *name)
256 {
257  return (dict_lookup(CONFIG_DICT, name));
258 }
259 
260 /* mail_conf_lookup_eval - expand named variable */
261 
262 const char *mail_conf_lookup_eval(const char *name)
263 {
264  const char *value;
265 
266 #define RECURSIVE 1
267 
268  if ((value = dict_lookup(CONFIG_DICT, name)) != 0)
269  value = dict_eval(CONFIG_DICT, value, RECURSIVE);
270  return (value);
271 }
272 
273 /* mail_conf_update - update parameter */
274 
275 void mail_conf_update(const char *key, const char *value)
276 {
277  dict_update(CONFIG_DICT, key, value);
278 }
void msg_error(const char *fmt,...)
Definition: msg.c:231
void mail_params_init()
Definition: mail_params.c:658
void myfree(void *ptr)
Definition: mymalloc.c:207
char * mystrdup(const char *str)
Definition: mymalloc.c:225
int dict_load_file_xt(const char *dict_name, const char *path)
Definition: dict.c:441
void set_mail_conf_str(const char *, const char *)
#define vstring_str(vp)
Definition: vstring.h:71
#define VAR_CONFIG_DIRS
Definition: mail_params.h:330
const char * mail_conf_eval(const char *string)
Definition: mail_conf.c:237
#define NONRECURSIVE
void mail_conf_flush(void)
Definition: mail_conf.c:229
char * var_config_dir
Definition: mail_params.c:241
int unsafe(void)
Definition: unsafe.c:59
const char * mail_conf_lookup(const char *name)
Definition: mail_conf.c:255
#define CONFIG_DICT
Definition: mail_conf.h:17
char * mystrtok(char **src, const char *sep)
Definition: mystrtok.c:54
const char * split_nameval(char *buf, char **name, char **value)
Definition: split_nameval.c:61
void dict_unregister(const char *dict_name)
Definition: dict.c:354
void mail_conf_suck(void)
Definition: mail_conf.c:186
void mail_conf_read(void)
Definition: mail_conf.c:178
VSTREAM * vstream_fopen(const char *path, int flags, mode_t mode)
Definition: vstream.c:1241
const char * dict_lookup(const char *dict_name, const char *member)
Definition: dict.c:382
#define CONF_ENV_PATH
Definition: mail_conf.h:22
DEF_CONFIG_DIR
Definition: install_table.h:1
#define VAR_MULTI_CONF_DIRS
Definition: mail_params.h:3554
void mail_conf_checkdir(const char *config_dir)
Definition: mail_conf.c:134
int vstream_fclose(VSTREAM *stream)
Definition: vstream.c:1268
DICT * dict_handle(const char *dict_name)
Definition: dict.c:333
#define RECURSIVE
VSTRING * vstring_alloc(ssize_t len)
Definition: vstring.c:353
VAR_CONFIG_DIR
Definition: install_table.h:1
NORETURN msg_fatal(const char *fmt,...)
Definition: msg.c:249
const char * mail_conf_lookup_eval(const char *name)
Definition: mail_conf.c:262
int dict_update(const char *dict_name, const char *member, const char *value)
Definition: dict.c:369
#define CHARS_COMMA_SP
Definition: sys_defs.h:1761
char * concatenate(const char *arg0,...)
Definition: concatenate.c:42
const char * dict_eval(const char *dict_name, const char *value, int recursive)
Definition: dict.c:536
VSTRING * vstring_free(VSTRING *vp)
Definition: vstring.c:380
void mail_conf_update(const char *key, const char *value)
Definition: mail_conf.c:275
const char * mail_conf_eval_once(const char *string)
Definition: mail_conf.c:246
#define readlline(bp, fp, lp)
Definition: readlline.h:25