+ if (!(pw = getpwnam(AVAHI_USER))) {
+ avahi_log_error( "Failed to find user '"AVAHI_USER"'.");
+ return -1;
+ }
+
+ if (!(gr = getgrnam(AVAHI_GROUP))) {
+ avahi_log_error( "Failed to find group '"AVAHI_GROUP"'.");
+ return -1;
+ }
+
+ avahi_log_info("Found user '"AVAHI_USER"' (UID %lu) and group '"AVAHI_GROUP"' (GID %lu).", (unsigned long) pw->pw_uid, (unsigned long) gr->gr_gid);
+
+ if (initgroups(AVAHI_USER, gr->gr_gid) != 0) {
+ avahi_log_error("Failed to change group list: %s", strerror(errno));
+ return -1;
+ }
+
+#if defined(HAVE_SETRESGID)
+ r = setresgid(gr->gr_gid, gr->gr_gid, gr->gr_gid);
+#elif defined(HAVE_SETEGID)
+ if ((r = setgid(gr->gr_gid)) >= 0)
+ r = setegid(gr->gr_gid);
+#elif defined(HAVE_SETREGID)
+ r = setregid(gr->gr_gid, gr->gr_gid);
+#else
+#error "No API to drop priviliges"
+#endif
+
+ if (r < 0) {
+ avahi_log_error("Failed to change GID: %s", strerror(errno));
+ return -1;
+ }
+
+#if defined(HAVE_SETRESUID)
+ r = setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid);
+#elif defined(HAVE_SETEUID)
+ if ((r = setuid(pw->pw_uid)) >= 0)
+ r = seteuid(pw->pw_uid);
+#elif defined(HAVE_SETREUID)
+ r = setreuid(pw->pw_uid, pw->pw_uid);
+#else
+#error "No API to drop priviliges"
+#endif
+
+ if (r < 0) {
+ avahi_log_error("Failed to change UID: %s", strerror(errno));
+ return -1;
+ }
+
+ set_env("USER", pw->pw_name);
+ set_env("LOGNAME", pw->pw_name);
+ set_env("HOME", pw->pw_dir);
+
+ avahi_log_info("Successfully dropped root privileges.");
+
+ return 0;
+}
+
+static const char* pid_file_proc(void) {
+ return AVAHI_DAEMON_RUNTIME_DIR"/pid";
+}
+
+static int make_runtime_dir(void) {
+ int r = -1;
+ mode_t u;
+ int reset_umask = 0;
+ struct passwd *pw;
+ struct group * gr;
+ struct stat st;
+
+ if (!(pw = getpwnam(AVAHI_USER))) {
+ avahi_log_error( "Failed to find user '"AVAHI_USER"'.");
+ goto fail;
+ }
+
+ if (!(gr = getgrnam(AVAHI_GROUP))) {
+ avahi_log_error( "Failed to find group '"AVAHI_GROUP"'.");
+ goto fail;
+ }
+
+ u = umask(0000);
+ reset_umask = 1;
+
+ if (mkdir(AVAHI_DAEMON_RUNTIME_DIR, 0755) < 0 && errno != EEXIST) {
+ avahi_log_error("mkdir(\""AVAHI_DAEMON_RUNTIME_DIR"\"): %s", strerror(errno));
+ goto fail;
+ }
+
+ chown(AVAHI_DAEMON_RUNTIME_DIR, pw->pw_uid, gr->gr_gid);
+
+ if (stat(AVAHI_DAEMON_RUNTIME_DIR, &st) < 0) {
+ avahi_log_error("stat(): %s\n", strerror(errno));
+ goto fail;
+ }
+
+ if (!S_ISDIR(st.st_mode) || st.st_uid != pw->pw_uid || st.st_gid != gr->gr_gid) {
+ avahi_log_error("Failed to create runtime directory "AVAHI_DAEMON_RUNTIME_DIR".");
+ goto fail;
+ }
+
+ r = 0;
+
+fail:
+ if (reset_umask)
+ umask(u);