+ if (real_uid != root_uid)
+ {
+ #ifdef TRUSTED_CONFIG_PREFIX_LIST
+
+ if (Ustrstr(argrest, "/../"))
+ trusted_config = FALSE;
+ else
+ {
+ FILE *trust_list = Ufopen(TRUSTED_CONFIG_PREFIX_LIST, "rb");
+ if (trust_list)
+ {
+ struct stat statbuf;
+
+ if (fstat(fileno(trust_list), &statbuf) != 0 ||
+ (statbuf.st_uid != root_uid /* owner not root */
+ #ifdef CONFIGURE_OWNER
+ && statbuf.st_uid != config_uid /* owner not the special one */
+ #endif
+ ) || /* or */
+ (statbuf.st_gid != root_gid /* group not root */
+ #ifdef CONFIGURE_GROUP
+ && statbuf.st_gid != config_gid /* group not the special one */
+ #endif
+ && (statbuf.st_mode & 020) != 0 /* group writeable */
+ ) || /* or */
+ (statbuf.st_mode & 2) != 0) /* world writeable */
+ {
+ trusted_config = FALSE;
+ fclose(trust_list);
+ }
+ else
+ {
+ /* Well, the trust list at least is up to scratch... */
+ void *reset_point = store_get(0);
+ uschar *trusted_prefixes[32];
+ int nr_prefixes = 0;
+ int i = 0;
+
+ while (Ufgets(big_buffer, big_buffer_size, trust_list))
+ {
+ uschar *start = big_buffer, *nl;
+ while (*start && isspace(*start))
+ start++;
+ if (*start == '#')
+ continue;
+ nl = Ustrchr(start, '\n');
+ if (nl)
+ *nl = 0;
+ trusted_prefixes[nr_prefixes++] = string_copy(start);
+ if (nr_prefixes == 32)
+ break;
+ }
+ fclose(trust_list);
+
+ if (nr_prefixes)
+ {
+ int sep = 0;
+ uschar *list = argrest;
+ uschar *filename;
+ while (trusted_config && (filename = string_nextinlist(&list,
+ &sep, big_buffer, big_buffer_size)) != NULL)
+ {
+ for (i=0; i < nr_prefixes; i++)
+ {
+ int len = Ustrlen(trusted_prefixes[i]);
+ if (Ustrlen(filename) >= len &&
+ Ustrncmp(filename, trusted_prefixes[i], len) == 0)
+ break;
+ }
+ if (i == nr_prefixes)
+ {
+ trusted_config = FALSE;
+ break;
+ }
+ }
+ }
+ else
+ {
+ /* No valid prefixes found in trust_list file. */
+ trusted_config = FALSE;
+ }
+ }
+ }
+ else
+ {
+ /* Could not open trust_list file. */
+ trusted_config = FALSE;
+ }
+ }
+ #else
+ /* Not root; don't trust config */
+ trusted_config = FALSE;
+ #endif
+ }