- if(netname)
- {
- if(!pidfilename)
- asprintf(&pidfilename, LOCALSTATEDIR "/run/tinc.%s.pid", netname);
- if(!confbase)
- asprintf(&confbase, "%s/tinc/%s", CONFDIR, netname);
- else
- syslog(LOG_INFO, _("Both netname and configuration directory given, using the latter..."));
- if(!identname)
- asprintf(&identname, "tinc.%s", netname);
- }
- else
- {
- if(!pidfilename)
- pidfilename = LOCALSTATEDIR "/run/tinc.pid";
- if(!confbase)
- asprintf(&confbase, "%s/tinc", CONFDIR);
- if(!identname)
- identname = "tinc";
- }
+#ifdef HAVE_MINGW
+ HKEY key;
+ char installdir[1024] = "";
+ long len = sizeof(installdir);
+#endif
+
+ if(netname)
+ xasprintf(&identname, "tinc.%s", netname);
+ else
+ identname = xstrdup("tinc");
+
+#ifdef HAVE_MINGW
+ if(!RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\tinc", 0, KEY_READ, &key)) {
+ if(!RegQueryValueEx(key, NULL, 0, 0, installdir, &len)) {
+ if(!logfilename)
+ xasprintf(&logfilename, "%s/log/%s.log", identname);
+ if(!confbase) {
+ if(netname)
+ xasprintf(&confbase, "%s/%s", installdir, netname);
+ else
+ xasprintf(&confbase, "%s", installdir);
+ }
+ }
+ RegCloseKey(key);
+ if(*installdir)
+ return;
+ }
+#endif
+
+ if(!pidfilename)
+ xasprintf(&pidfilename, LOCALSTATEDIR "/run/%s.pid", identname);
+
+ if(!logfilename)
+ xasprintf(&logfilename, LOCALSTATEDIR "/log/%s.log", identname);
+
+ if(netname) {
+ if(!confbase)
+ xasprintf(&confbase, CONFDIR "/tinc/%s", netname);
+ else
+ logger(LOG_INFO, _("Both netname and configuration directory given, using the latter..."));
+ } else {
+ if(!confbase)
+ xasprintf(&confbase, CONFDIR "/tinc");
+ }
+}
+
+static void free_names() {
+ if (identname) free(identname);
+ if (netname) free(netname);
+ if (pidfilename) free(pidfilename);
+ if (logfilename) free(logfilename);
+ if (confbase) free(confbase);
+}
+
+static bool drop_privs() {
+#ifdef HAVE_MINGW
+ if (switchuser) {
+ logger(LOG_ERR, _("%s not supported on this platform"), "-U");
+ return false;
+ }
+ if (do_chroot) {
+ logger(LOG_ERR, _("%s not supported on this platform"), "-R");
+ return false;
+ }
+#else
+ uid_t uid = 0;
+ if (switchuser) {
+ struct passwd *pw = getpwnam(switchuser);
+ if (!pw) {
+ logger(LOG_ERR, _("unknown user `%s'"), switchuser);
+ return false;
+ }
+ uid = pw->pw_uid;
+ if (initgroups(switchuser, pw->pw_gid) != 0 ||
+ setgid(pw->pw_gid) != 0) {
+ logger(LOG_ERR, _("System call `%s' failed: %s"),
+ "initgroups", strerror(errno));
+ return false;
+ }
+ endgrent();
+ endpwent();
+ }
+ if (do_chroot) {
+ tzset(); /* for proper timestamps in logs */
+ if (chroot(confbase) != 0 || chdir("/") != 0) {
+ logger(LOG_ERR, _("System call `%s' failed: %s"),
+ "chroot", strerror(errno));
+ return false;
+ }
+ free(confbase);
+ confbase = xstrdup("");
+ }
+ if (switchuser)
+ if (setuid(uid) != 0) {
+ logger(LOG_ERR, _("System call `%s' failed: %s"),
+ "setuid", strerror(errno));
+ return false;
+ }
+#endif
+ return true;