| 
					
				 | 
			
			
				@@ -920,61 +920,215 @@ set_max_file_descriptors(rlim_t limit, int *max_out) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-/** Call setuid and setgid to run as <b>user</b>:<b>group</b>.  Return 0 on 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- * success.  On failure, log and return -1. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** Log details of current user and group credentials. Return 0 on 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * success. Logs and return -1 on failure. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 int 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-switch_id(const char *user, const char *group) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+log_credential_status() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define CREDENTIAL_LOG_LEVEL LOG_INFO 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#ifndef MS_WINDOWS 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* Real, effective and saved UIDs */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  uid_t ruid, euid, suid; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* Read, effective and saved GIDs */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  gid_t rgid, egid, sgid; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* Supplementary groups */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  gid_t sup_gids[NGROUPS_MAX + 1]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* Number of supplementary groups */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  int ngids; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* log UIDs */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#ifdef HAVE_GETRESUID 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (getresuid(&ruid, &euid, &suid) != 0 ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    log_warn(LD_GENERAL, "Error getting changed UIDs: %s", strerror(errno)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    log_fn(CREDENTIAL_LOG_LEVEL, LD_GENERAL, "UID is %u (real), %u (effective), %u (saved)", ruid, euid, suid); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* getresuid is not present on MacOS X, so we can't get the saved (E)UID */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ruid = getuid(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  euid = geteuid(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  (void)suid; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  log_fn(CREDENTIAL_LOG_LEVEL, LD_GENERAL, "UID is %u (real), %u (effective), unknown (saved)", ruid, euid); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* log GIDs */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#ifdef HAVE_GETRESGID 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (getresgid(&rgid, &egid, &sgid) != 0 ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    log_warn(LD_GENERAL, "Error getting changed GIDs: %s", strerror(errno)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    log_fn(CREDENTIAL_LOG_LEVEL, LD_GENERAL, "GID is %u (real), %u (effective), %u (saved)", rgid, egid, sgid); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* getresgid is not present on MacOS X, so we can't get the saved (E)GID */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  rgid = getgid(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  egid = getegid(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  (void)sgid; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  log_fn(CREDENTIAL_LOG_LEVEL, LD_GENERAL, "GID is %u (real), %u (effective), unknown (saved)", rgid, egid); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* log supplementary groups */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if((ngids = getgroups(NGROUPS_MAX + 1, sup_gids)) < 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    log_warn(LD_GENERAL, "Error getting supplementary GIDs: %s", strerror(errno)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    int i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    char *strgid; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    char *s = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    int formatting_error = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    smartlist_t *elts = smartlist_create(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (i = 0; i<ngids; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      strgid = tor_malloc(11); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (tor_snprintf(strgid, 11, "%u", (unsigned)sup_gids[i]) == -1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        log_warn(LD_GENERAL, "Error printing supplementary GIDs"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        formatting_error = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        goto error; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      smartlist_add(elts, strgid); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    s = smartlist_join_strings(elts, " ", 0, NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    log_fn(CREDENTIAL_LOG_LEVEL, LD_GENERAL, "Supplementary groups are: %s", s); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   error: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    tor_free(s); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SMARTLIST_FOREACH(elts, char *, cp, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      tor_free(cp); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    smartlist_free(elts); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (formatting_error) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** Call setuid and setgid to run as <b>user</b> and only switch to their 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * primary group.  Return 0 on success.  On failure, log and return -1. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+int 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+switch_id(const char *user) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #ifndef MS_WINDOWS 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   struct passwd *pw = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  struct group *gr = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  uid_t old_uid; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  gid_t old_gid; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  tor_assert(user); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* Log the initial credential state */  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if (user) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    pw = getpwnam(user); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (pw == NULL) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      log_warn(LD_CONFIG,"User '%s' not found.", user); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (log_credential_status()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  log_fn(CREDENTIAL_LOG_LEVEL, LD_GENERAL, "Changing user and groups"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  /* switch the group first, while we still have the privileges to do so */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  if (group) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    gr = getgrnam(group); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (gr == NULL) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      log_warn(LD_CONFIG,"Group '%s' not found.", group); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* Get old UID/GID to check if we changed correctly */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  old_uid = getuid(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  old_gid = getgid(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* Lookup the user and group information, if we have a problem, bail out. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (user) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    pw = getpwnam(user); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (pw == NULL) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      log_warn(LD_CONFIG, "Error setting configured user: " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      "'%s' not found.", user); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /* We have no user supplied and so we'll bail out. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    log_warn(LD_CONFIG, "Error setting configured user: No user supplied."); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (setgid(gr->gr_gid) != 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      log_warn(LD_GENERAL,"Error setting to configured GID: %s", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-               strerror(errno)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* Properly switch egid,gid,euid,uid here or bail out */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (setgroups(1, &pw->pw_gid)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    log_warn(LD_GENERAL, "Error setting configured groups: %s", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    strerror(errno)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (setegid(pw->pw_gid)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    log_warn(LD_GENERAL, "Error setting configured egid: %s", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    strerror(errno)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (setgid(pw->pw_gid)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    log_warn(LD_GENERAL, "Error setting configured gid: %s", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    strerror(errno)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (setuid(pw->pw_uid)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    log_warn(LD_GENERAL, "Error setting configured uid: %s", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    strerror(errno)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (seteuid(pw->pw_uid)){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    log_warn(LD_GENERAL, "Error setting configured euid: %s", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    strerror(errno)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* This is how OpenBSD rolls: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (setgroups(1, &pw->pw_gid) || setegid(pw->pw_gid) || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      setgid(pw->pw_gid) || setuid(pw->pw_uid) || seteuid(pw->pw_uid)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      setgid(pw->pw_gid) || seteuid(pw->pw_uid) || setuid(pw->pw_uid)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    log_warn(LD_GENERAL, "Error setting configured UID/GID: %s", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    strerror(errno)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* We've properly switched egid, gid, euid, uid, and supplementary groups if 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * we're here. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#if !defined(CYGWIN) && !defined(__CYGWIN__) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* If we tried to drop privilege to a group/user other than root, attempt to 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * restore root (E)(U|G)ID, and abort if the operation succeeds */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* Only check for privilege dropping if we were asked to be non-root */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (pw->pw_uid) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /* Try changing GID/EGID */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (pw->pw_gid != old_gid && (setgid(old_gid) != -1 || setegid(old_gid) != -1)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      log_warn(LD_GENERAL, "Was able to restore group credentials"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } else if (user) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (setgid(pw->pw_gid) != 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      log_warn(LD_GENERAL,"Error setting to user GID: %s", strerror(errno)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /* Try changing UID/EUID */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (pw->pw_uid != old_uid && (setuid(old_uid) != -1 || seteuid(old_uid) != -1)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      log_warn(LD_GENERAL, "Was able to restore user credentials"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  /* now that the group is switched, we can switch users and lose 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     privileges */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* Check what really happened */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if (user) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (setuid(pw->pw_uid) != 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      log_warn(LD_GENERAL,"Error setting UID: %s", strerror(errno)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (log_credential_status()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   (void)user; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  (void)group; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   log_warn(LD_CONFIG, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-           "User or group specified, but switching users is not supported."); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           "User specified but switching users is unsupported on your OS."); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 |