Description: set ssh-agent real GID to ssh group GID
 If ssh-agent is installed setgid wrt to the ssh group,
 as for Debian distributions, setting its real GID to
 the ssh GID allows to pass (and to honour) environment
 variables otherwise discarded by glibc, as TMPDIR.
 For Debian distributions, read subsection entitled
 `Setgid ssh-agent and environment variables' in
 /usr/share/doc/openssh-server/README.Debian .
Origin: debian
Author: Jerome Benoit <calculus@rezozer.net>
Last-Update: 2013-07-14

--- a/pam_ssh.c
+++ b/pam_ssh.c
@@ -71,6 +71,10 @@
 #include <time.h>
 #include <grp.h>
 
+#ifndef SSH_GROUP_NAME
+#define SSH_GROUP_NAME "ssh"
+#endif
+
 #define PAM_SM_AUTH
 #define PAM_SM_SESSION
 #if !HAVE_OPENPAM
@@ -334,6 +338,8 @@
 static int
 start_ssh_agent(pam_handle_t *pamh, uid_t uid, gid_t gid, const char * name, FILE **env_read)
 {
+	struct group *ssh_grp; /* ssh group holder, if any */
+	gid_t rgid; /* ssh GID if ssh group exist, gid otherwise */
 	pid_t child_pid;		/* child process that spawns agent */
 	int child_pipe[2];		/* pipe to child process */
 	int child_status;		/* child process status */
@@ -354,15 +360,24 @@
 	case 0:		/* child */
 
 		/* Permanently drop privileges using setuid(),
-			 setguid(), and initgroups()
+			 setregid(), and initgroups()
 			 before executing ssh-agent so that root
 			 privileges can't possibly be regained (some
-			 ssh-agents insist that euid == ruid
-			 anyway).  System V won't let us use
-			 setuid() unless euid == 0, so we
-			 temporarily regain root privileges first
-			 with openpam_restore_cred() (which calls
-			 seteuid()). */
+			 ssh-agents insist that euid == ruid anyway).
+			 Some distributions, as Debian, set'gid ssh-agent
+			 wrt to a ssh dedicated group to prevent ptrace()
+			 attacks retrieving private key material,
+			 so we first check the existence of such a group
+			 and assume surch a policy if applicable.
+			 System V won't let us use setuid() unless
+			 euid == 0, so we temporarily regain root
+			 privileges first with openpam_restore_cred()
+			 (which calls seteuid()). */
+
+		if ((ssh_grp = getgrnam(SSH_GROUP_NAME)) != NULL)
+			rgid = ssh_grp->gr_gid;
+		else
+			rgid = gid;
 
 		switch (openpam_restore_cred(pamh)) {
 		case PAM_SYSTEM_ERR:
@@ -370,7 +385,7 @@
 			_exit(EX_OSERR);
 			/* NOTREACHED */
 		case PAM_SUCCESS:
-			if ((initgroups(name, gid) == -1) || (setgid(gid) == -1) || (setuid(uid) == -1)) {
+			if ((initgroups(name, gid) == -1) || (setregid(rgid, gid) == -1) || (setuid(uid) == -1)) {
 				pam_ssh_log(LOG_ERR, "can't drop privileges: %m", uid);
 				_exit(EX_NOPERM);
 			}
