diff --git a/NEWS b/NEWS
index e307dd35690ec13fa79f97fa3462d3ba9eda51f5..d516ea0dd203996222763b6cef08f2be6c0182f5 100644
--- a/NEWS
+++ b/NEWS
@@ -536,6 +536,10 @@ documents those changes that are of interest to users and admins.
  -- Remove some use of cr_enabled flag in slurmctld job record, use 
     new flag "test_only" in select_g_job_test() instead.
 
+* Changes in SLURM 1.0.17
+=========================
+ -- Set correct user groups for task epilogs.
+
 * Changes in SLURM 1.0.16
 =========================
  -- For "srun --attach=X" to other users job, report an error and exit (it
diff --git a/src/slurmd/common/run_script.c b/src/slurmd/common/run_script.c
index 0d4d10606c75d9fcc02ce2ac60766046c91670a8..0759d150a04f3d23f306766a30c5351614f2848e 100644
--- a/src/slurmd/common/run_script.c
+++ b/src/slurmd/common/run_script.c
@@ -52,18 +52,17 @@
 
 
 /*
- * Run a prolog or epilog script
- * name IN: class of program (prolog, epilog, etc.), 
- *	if prefix is "user" then also set uid
+ * Run a prolog or epilog script (does NOT drop privileges)
+ * name IN: class of program (prolog, epilog, etc.),
  * path IN: pathname of program to run
- * jobid, uid IN: info on associated job
+ * jobid IN: info on associated job
  * max_wait IN: maximum time to wait in seconds, -1 for no limit
- * env IN: environment variables to use on exec, sets minimal environment
+ * env IN: environment variables to use on exec, sets minimal environment 
  *	if NULL
- * RET 0 on success, -1 on failure. 
+ * RET 0 on success, -1 on failure.
  */
 int
-run_script(const char *name, const char *path, uint32_t jobid, uid_t uid, 
+run_script(const char *name, const char *path, uint32_t jobid,
 	   int max_wait, char **env)
 {
 	int status, rc, opt;
@@ -90,8 +89,6 @@ run_script(const char *name, const char *path, uint32_t jobid, uid_t uid,
 		argv[0] = (char *)xstrdup(path);
 		argv[1] = NULL;
 
-		if (strncmp(name, "user", 4) == 0)
-			setuid(uid);
 #ifdef SETPGRP_TWO_ARGS
 		setpgrp(0, 0);
 #else
diff --git a/src/slurmd/common/run_script.h b/src/slurmd/common/run_script.h
index c5fc807ec331d38155a00350436cee325c5bb59f..f910043c59ab4734661f0b42afe0683fff7ab2b8 100644
--- a/src/slurmd/common/run_script.h
+++ b/src/slurmd/common/run_script.h
@@ -43,17 +43,16 @@
 #include <inttypes.h>
 
 /*
- * Run a prolog or epilog script
+ * Run a prolog or epilog script (does NOT drop privileges)
  * name IN: class of program (prolog, epilog, etc.),
- *	if prefix is "user" then also set uid
  * path IN: pathname of program to run
- * jobid, uidIN: info on associated job
+ * jobid IN: info on associated job
  * max_wait IN: maximum time to wait in seconds, -1 for no limit
  * env IN: environment variables to use on exec, sets minimal environment 
  *	if NULL
  * RET 0 on success, -1 on failure.
  */
 int run_script(const char *name, const char *path, uint32_t jobid, 
-	       uid_t uid, int max_wait, char **env);
+	       int max_wait, char **env);
 
 #endif /* _RUN_SCRIPT_H */
diff --git a/src/slurmd/slurmd/req.c b/src/slurmd/slurmd/req.c
index 0384ba8468aefc927a9bf9d619dfd11599c6b973..5add24739059774863dfa9ffe930ff02741c58ce 100644
--- a/src/slurmd/slurmd/req.c
+++ b/src/slurmd/slurmd/req.c
@@ -2207,8 +2207,7 @@ _run_prolog(uint32_t jobid, uid_t uid, char *bg_part_id)
 	my_prolog = xstrdup(conf->prolog);
 	slurm_mutex_unlock(&conf->config_mutex);
 
-	error_code = run_script("prolog", my_prolog, jobid, uid, 
-			-1, my_env);
+	error_code = run_script("prolog", my_prolog, jobid, -1, my_env);
 	xfree(my_prolog);
 	_destroy_env(my_env);
 
@@ -2226,8 +2225,7 @@ _run_epilog(uint32_t jobid, uid_t uid, char *bg_part_id)
 	my_epilog = xstrdup(conf->epilog);
 	slurm_mutex_unlock(&conf->config_mutex);
 
-	error_code = run_script("epilog", my_epilog, jobid, uid, 
-			-1, my_env);
+	error_code = run_script("epilog", my_epilog, jobid, -1, my_env);
 	xfree(my_epilog);
 	_destroy_env(my_env);
 
diff --git a/src/slurmd/slurmstepd/mgr.c b/src/slurmd/slurmstepd/mgr.c
index 37aecf773e2925984c22a701bc6c43c4c2a1c9a7..554e952e5f04cc1eafa75c13ed0b8b33a9e58018 100644
--- a/src/slurmd/slurmstepd/mgr.c
+++ b/src/slurmd/slurmstepd/mgr.c
@@ -173,6 +173,8 @@ static void _setargs(slurmd_job_t *job);
 
 static void _random_sleep(slurmd_job_t *job);
 static char *_sprint_task_cnt(batch_job_launch_msg_t *msg);
+static int  _run_script_as_user(const char *name, const char *path,
+				slurmd_job_t *job, int max_wait, char **env);
 
 /*
  * Batch job mangement prototypes:
@@ -1099,17 +1101,18 @@ _wait_for_any_task(slurmd_job_t *job, bool waitflag)
 			setup_env(job->envtp);
 			job->env = job->envtp->env;
 			if (job->task_epilog) {
-				run_script("user task_epilog", 
-					   job->task_epilog, 
-					   job->jobid, job->uid, 2, job->env);
+				_run_script_as_user("user task_epilog",
+						    job->task_epilog,
+						    job, 2, job->env);
 			}
 			if (conf->task_epilog) {
 				char *my_epilog;
 				slurm_mutex_lock(&conf->config_mutex);
 				my_epilog = xstrdup(conf->task_epilog);
 				slurm_mutex_unlock(&conf->config_mutex);
-				run_script("slurm task_epilog", my_epilog, 
-					job->jobid, job->uid, -1, job->env);
+				_run_script_as_user("slurm task_epilog",
+						    my_epilog,
+						    job, -1, job->env);
 				xfree(my_epilog);
 			}
 			job->envtp->procid = i;
@@ -1125,7 +1128,6 @@ _wait_for_any_task(slurmd_job_t *job, bool waitflag)
 done:
 	return completed;
 }
-	
 
 static void
 _wait_for_all_tasks(slurmd_job_t *job)
@@ -1598,3 +1600,85 @@ _initgroups(slurmd_job_t *job)
 	}
 	return 0;
 }
+
+/*
+ * Run a script as a specific user, with the specified uid, gid, and 
+ * extended groups.
+ *
+ * name IN: class of program (task prolog, task epilog, etc.), 
+ * path IN: pathname of program to run
+ * job IN: slurd job structue, used to get uid, gid, and groups
+ * max_wait IN: maximum time to wait in seconds, -1 for no limit
+ * env IN: environment variables to use on exec, sets minimal environment
+ *	if NULL
+ *
+ * RET 0 on success, -1 on failure. 
+ */
+int
+_run_script_as_user(const char *name, const char *path, slurmd_job_t *job,
+		    int max_wait, char **env)
+{
+	int status, rc, opt;
+	pid_t cpid;
+
+	xassert(env);
+	if (path == NULL || path[0] == '\0')
+		return 0;
+
+	debug("[job %u] attempting to run %s [%s]", job->jobid, name, path);
+
+	if ((cpid = fork()) < 0) {
+		error ("executing %s: fork: %m", name);
+		return -1;
+	}
+	if (cpid == 0) {
+		struct priv_state sprivs;
+		char *argv[2];
+
+		argv[0] = (char *)xstrdup(path);
+		argv[1] = NULL;
+
+		if (_drop_privileges(job, true, &sprivs) < 0) {
+			error("run_script_as_user _drop_privileges: %m");
+			/* child process, should not return */
+			exit(127);
+		}
+
+		if (_become_user(job, &sprivs) < 0) {
+			error("run_script_as_user _become_user failed: %m");
+			/* child process, should not return */
+			exit(127);
+		}
+	
+		setpgrp();
+		execve(path, argv, env);
+		error("execve(): %m");
+		exit(127);
+	}
+
+	if (max_wait < 0)
+		opt = 0;
+	else
+		opt = WNOHANG;
+
+	while (1) {
+		rc = waitpid(cpid, &status, opt);
+		if (rc < 0) {
+			if (errno == EINTR)
+				continue;
+			error("waidpid: %m");
+			return 0;
+		} else if (rc == 0) {
+			sleep(1);
+			if ((--max_wait) == 0) {
+				killpg(cpid, SIGKILL);
+				opt = 0;
+			}
+		} else  {
+			killpg(cpid, SIGKILL);	/* kill children too */
+			return status;
+		}
+	}
+
+	/* NOTREACHED */
+}
diff --git a/src/slurmd/slurmstepd/task.c b/src/slurmd/slurmstepd/task.c
index a54c7d69cd3b638e708e4fbd8841dff332d51a9a..dce2e536f11fbee7f6f505c15a3e9b0775f0707c 100644
--- a/src/slurmd/slurmstepd/task.c
+++ b/src/slurmd/slurmstepd/task.c
@@ -89,8 +89,8 @@
  * Static prototype definitions.
  */
 static void  _make_tmpdir(slurmd_job_t *job);
-static int   _run_script(const char *name, const char *path, 
-		slurmd_job_t *job);
+static int   _run_script_and_set_env(const char *name, const char *path, 
+				     slurmd_job_t *job);
 static void  _update_env(char *buf, char ***env);
 
 /* Search for "export NAME=value" records in buf and 
@@ -127,16 +127,17 @@ _update_env(char *buf, char ***env)
 }
 
 /*
- * Run a task prolog script
- * name IN: class of program ("system prolog", "user prolog", etc.),
- *	if prefix is "user" then also set uid
+ * Run a task prolog script.  Also read the stdout of the script and set
+ * 	environment variables in the task's environment as specified
+ *	in the script's standard output.
+ * name IN: class of program ("system prolog", "user prolog", etc.)
  * path IN: pathname of program to run
  * job IN/OUT: pointer to associated job, can update job->env 
  *	if prolog
  * RET 0 on success, -1 on failure.
  */
 static int
-_run_script(const char *name, const char *path, slurmd_job_t *job)
+_run_script_and_set_env(const char *name, const char *path, slurmd_job_t *job)
 {
 	int status, rc, nread;
 	pid_t cpid;
@@ -348,11 +349,13 @@ exec_task(slurmd_job_t *job, int i, int waitfd)
 		slurm_mutex_lock(&conf->config_mutex);
 		my_prolog = xstrdup(conf->task_prolog);
 		slurm_mutex_unlock(&conf->config_mutex);
-		_run_script("slurm task_prolog", my_prolog, job);
+		_run_script_and_set_env("slurm task_prolog",
+					my_prolog, job);
 		xfree(my_prolog);
 	}
 	if (job->task_prolog) {
-		_run_script("user task_prolog", job->task_prolog, job); 
+		_run_script_and_set_env("user task_prolog",
+					job->task_prolog, job); 
 	}
 
 	if (job->env == NULL) {