fi
# Checks for header files.
-AC_CHECK_HEADERS([stdarg.h stdbool.h netinet/in.h netinet/tcp.h sys/param.h sys/select.h sys/socket.h sys/un.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h sys/endian.h libkern/OSByteOrder.h sys/ipc.h sys/shm.h ifaddrs.h poll.h],,, [AC_INCLUDES_DEFAULT])
+AC_CHECK_HEADERS([stdarg.h stdbool.h netinet/in.h netinet/tcp.h sys/param.h sys/select.h sys/socket.h sys/un.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h fnmatch.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h sys/endian.h libkern/OSByteOrder.h sys/ipc.h sys/shm.h ifaddrs.h poll.h],,, [AC_INCLUDES_DEFAULT])
# net/if.h portability for Darwin see:
# https://www.gnu.org/software/autoconf/manual/autoconf-2.69/html_node/Header-Portability.html
AC_CHECK_HEADERS([net/if.h],,, [
AC_MSG_RESULT(no))
AC_SEARCH_LIBS([setusercontext], [util])
-AC_CHECK_FUNCS([tzset sigprocmask fcntl getpwnam endpwent getrlimit setrlimit setsid chroot kill chown sleep usleep random srandom recvmsg sendmsg writev socketpair glob initgroups strftime localtime_r setusercontext _beginthreadex endservent endprotoent fsync shmget accept4 getifaddrs if_nametoindex poll gettid])
+AC_CHECK_FUNCS([tzset sigprocmask fcntl getpwnam endpwent getrlimit setrlimit setsid chroot kill chown sleep usleep random srandom recvmsg sendmsg writev socketpair glob fnmatch initgroups strftime localtime_r setusercontext _beginthreadex endservent endprotoent fsync shmget accept4 getifaddrs if_nametoindex poll gettid])
AC_CHECK_FUNCS([setresuid],,[AC_CHECK_FUNCS([setreuid])])
AC_CHECK_FUNCS([setresgid],,[AC_CHECK_FUNCS([setregid])])
#ifdef HAVE_GLOB_H
#include <glob.h>
#endif
+#ifdef HAVE_FNMATCH_H
+#include <fnmatch.h>
+#endif
#ifdef WITH_PYTHONMODULE
#include "pythonmod/pythonmod.h"
#endif
}
}
+/** Compare filename with string, true if it matches the name. */
+static int
+file_string_matches(char* str, char* fname, struct config_file* cfg)
+{
+ char* f;
+ if(!str || str[0] == 0)
+ return 0;
+ /* compare name after chroot and working dir are applied */
+ f = fname_after_chroot(str, cfg, 1);
+ if(!f) fatal_exit("out of memory");
+ if(strcmp(fname, f) == 0) {
+ free(f);
+ return 1;
+ }
+ free(f);
+ return 0;
+}
+
+/** Compare filename with list of files, true if list contains the name. */
+static int
+file_list_contains(struct config_strlist* list, char* fname,
+ struct config_file* cfg)
+{
+ struct config_strlist* s;
+ char* f;
+ for(s = list; s; s = s->next) {
+ if(!s->str || s->str[0] == 0)
+ continue; /* skip if no file name */
+ /* compare names after chroot and working dir are applied */
+ f = fname_after_chroot(s->str, cfg, 1);
+ if(!f) fatal_exit("out of memory");
+ if(strcmp(fname, f) == 0) {
+ free(f);
+ return 1;
+ }
+ free(f);
+ }
+ return 0;
+}
+
+/** Compare filename with list of files, true if list contains the name,
+ * with glob compare. */
+static int
+file_list_contains_wild(struct config_strlist* list, char* fname,
+ struct config_file* cfg)
+{
+ struct config_strlist* s;
+ char* f;
+ for(s = list; s; s = s->next) {
+ if(!s->str || s->str[0] == 0)
+ continue; /* skip if no file name */
+ /* compare names after chroot and working dir are applied */
+ f = fname_after_chroot(s->str, cfg, 1);
+ if(!f) fatal_exit("out of memory");
+ if(strcmp(fname, f) == 0) {
+ free(f);
+ return 1;
+ }
+#ifdef HAVE_FNMATCH
+ if(fnmatch(f, fname, 0) == 0) {
+ log_err("trusted-keys-file: \"%s\" matches zonefile '%s'",
+ s->str, fname);
+ free(f);
+ return 1;
+ }
+#endif
+ free(f);
+ }
+ return 0;
+}
+
+/** Check if the auth-zone/rpz zonefile: conflicts with other files,
+ * so it would overwrite that file. Refuse it aliasing any read-side bootstrap
+ * file. */
+static void
+check_file_clobber(struct config_file* cfg)
+{
+ struct config_auth* p;
+ char* zfile, *sourceopt = NULL;
+ for(p = cfg->auths; p; p = p->next) {
+ if(!p->name || p->name[0] == 0)
+ continue; /* skip if no name */
+ if(!p->zonefile || p->zonefile[0]==0)
+ continue; /* no zone file */
+ zfile = fname_after_chroot(p->zonefile, cfg, 1);
+ if(!zfile) fatal_exit("out of memory");
+ if(file_list_contains(cfg->auto_trust_anchor_file_list, zfile,
+ cfg))
+ sourceopt = "auto-trust-anchor-file";
+ else if(file_list_contains(cfg->trust_anchor_file_list, zfile,
+ cfg))
+ sourceopt = "trust-anchor-file";
+ else if(file_list_contains_wild(cfg->trusted_keys_file_list,
+ zfile, cfg))
+ sourceopt = "trusted-keys-file";
+ else if(file_list_contains(cfg->root_hints, zfile, cfg))
+ sourceopt = "root-hints";
+ else if(file_list_contains(cfg->tls_session_ticket_keys.first,
+ zfile, cfg))
+ sourceopt = "tls-session-ticket-keys";
+#ifdef USE_IPSECMOD
+ if(cfg->ipsecmod_enabled &&
+ file_string_matches(cfg->ipsecmod_hook, zfile, cfg))
+ sourceopt = "ipsecmod-hook";
+#endif
+ if(sourceopt)
+ fatal_exit("auth-zone '%s': zonefile \"%s\" "
+ "is the same path as a %s option. "
+ "The auth-zone transfer would overwrite it.",
+ p->name, p->zonefile, sourceopt);
+ free(zfile);
+ }
+}
+
/** check configuration for errors */
static void
morechecks(struct config_file* cfg)
cfg->chrootdir, cfg);
}
#endif
+ check_file_clobber(cfg);
/* remove chroot setting so that modules are not stripping pathnames */
free(cfg->chrootdir);
cfg->chrootdir = NULL;