diff -urN torque-2.5.12.orig/configure.ac torque-2.5.12/configure.ac
--- torque-2.5.12.orig/configure.ac	2012-04-13 23:07:20.000000000 +0200
+++ torque-2.5.12/configure.ac	2012-07-10 11:55:21.000000000 +0200
@@ -763,6 +763,34 @@
   fi
 fi
 
+dnl compile for munge library based authorization - link with munge library
+dnl instead of using expensive popen() calls. This option requires munge 
+dnl libraries to be installed during compilation.
+
+AC_ARG_ENABLE(munge_library, [ 
+  --enable-munge-library Use MUNGE library calls instead of expensive and slow popen.
+                         Munge library is required. This method is much faster than old munge-auth ] )
+
+AC_MSG_CHECKING([whether to use MUNGE library API for authentication])
+if test  "x$GCC" = "xyes" ; then
+  if test "${enable_munge_library}" = "yes" ; then
+
+    AC_MSG_RESULT([yes])
+    AC_CHECK_LIB(munge,munge_ctx_create,LDFLAGS="$LDFLAGS -lmunge")
+    AC_CHECK_HEADERS([munge.h])
+
+    if test "$ac_cv_header_munge_h" = "yes" && test "$ac_cv_lib_munge_munge_ctx_create" = "yes"; then 
+       CFLAGS="$CFLAGS -DMUNGE_AUTH_LIB -DMUNGE_AUTH"
+    else
+       AC_MSG_ERROR([requested munge library API support is disabled - cannot find library or headers])
+    fi
+  else
+    AC_MSG_RESULT([no])
+  fi
+
+  AM_CONDITIONAL([WITH_MUNGE_LIBRARY], [ test "${enable_munge_library}" = "yes" ])
+
+fi
 
 dnl
 dnl arch-specific libs
diff -urN torque-2.5.12.orig/README.munge torque-2.5.12/README.munge
--- torque-2.5.12.orig/README.munge	1970-01-01 01:00:00.000000000 +0100
+++ torque-2.5.12/README.munge	2012-07-11 12:04:01.000000000 +0200
@@ -0,0 +1,154 @@
+===========================================================
+
+ MUNGE Authentication
+
+===========================================================
+
+
+MUNGE is an authentication service that creates and validates user credentials. 
+It was developed by Lawrence Livermore National Laboratoy (LLNL) to be highly 
+scalable so it can be used in large environments such as HPC clusters. 
+
+To learn more about MUNGE visit: http://code.google.com/p/munge/
+
+MUNGE library was released as GPLv2 licensed code what implied
+that **TORQUE couldn't be linked against the library**
+
+MUNGE library has recently been relicensed to LGPLv3. 
+Starting with munge-5.0.9 it became possible to use munge functions
+by linking to the libraries.
+
+
+MUNGE support in TORQUE is a compile time operation. 
+
+========================================
+ How to enable MUNGE
+========================================
+
+MUNGE Authentication for TORQUE can be built by specifying one of two 
+configure options:
+
+  --enable-munge-auth         - Authentication with munge executable forked by pbs_server
+  --enable-munge-library      - (NEW) Authentication with munge library API calls
+
+
+TIP:  The dominant factor of the munge authentication performance is the hostname resolution.
+      Assure that all hosts involved in communication with server have entires 
+      in the /etc/hosts or use some other caching solution (like nscd).
+
+IMPORTANT: both munge auth methods are fully compatible with each other. 
+           you can use munge-library enabled server with munge-auth clients 
+           and so on.
+
+=========================================
+ --enable-munge-auth:
+=========================================
+
+Provides stable and well tested method of communicating with munge server.
+This option does not require munge libraries and development files to be present on a given host.
+Major drawback of such method is overhead of expensive popen and related calls with 
+piped communication. This can result in significant server slowdowns for big clusters.
+
+ Pros:
+  - stable and tested
+  - does not require linking to libmunge (GPL restriction)
+  
+ Cons:
+  - slower than API (popen,exec,fsync calls penalty)
+ 
+
+========================================
+ --enable-munge-library:
+========================================
+
+Library support patch was provided by:
+
+ Mariusz Mamonski (PSNC) <mamonski@man.poznan.pl> - idea and initial version
+ Lukasz Flis  (CYFRONET) <l.flis@cyfronet.pl>     - integration, fixes and testing
+
+This option enables direct use of API for MUNGE authentication on clients and pbs_server.
+No more popen/fork calls are needed during authentication process.
+Option implies linking library libmunge to TORQUE so additional dependencies are needed.
+
+Make sure that you have development libraries and headers for MUNGE:
+
+   munge-libs and munge-devel for RHEL based distrubutions
+   libmunge-dev libmunge2     for Debian/Ubuntu distributions
+
+LEGAL notice:
+Remember that only munge-0.5.9 or newer allows for linking with non-GPLed code.
+
+ Pros:
+  - faster: no fork/popen overhead resulting in more req/s processed
+  - no need for temporary files on disk - no fsync() call penalty
+  - less code
+  - linking directly to libmunge
+  - better error handling 
+
+ Cons:
+  - still needs testing
+  - requires linking to libmunge
+
+IMPORTANT: API based munge authetication mechanism tries to mimic the exec based implementation
+           (--enable-munge-auth) behavior for compatibility reasons.
+           It implies that user which is unknown to the server is allowed to query for 
+           jobs and nodes (qstat,pbsnodes).
+
+           If you require more strict behaviour please add 
+
+             PBS_MUNGE_STRICT_UID_CHECK=yes
+
+           to /var/torque/pbs_environment and restart pbs_server process
+           This will deny access to all users not present in the server passwd database.
+           
+
+
+========================================
+ MUNGE Troubleshooting 
+========================================
+
+This list addresses most of the problems you may encounter:
+
+1. In case of problems review server log - /var/torque/server_logs
+2. Make sure that clocks on servers and clients are in sync
+3. Keep your username<->uid mapping consistent around the cluster
+4. Make sure that munge server is running on server and clients
+5. Make sure that munge keys are the same around the cluster
+
+
+========================================
+ MUNGE FAQ
+========================================
+
+ Q: how to check if my pbs:server is using munge library?
+ A: Use ldd to check if it is linked to libmunge.so:
+
+    ldd /usr/sbin/pbs_server 
+        linux-vdso.so.1 =>  (0x00007fff15bfd000)
+        libtorque.so.2 => /usr/lib64/libtorque.so.2 (0x00002b7926079000)
+        libmunge.so.2 => /usr/lib64/libmunge.so.2 (0x0000003d46c00000)
+        libc.so.6 => /lib64/libc.so.6 (0x00000035d2a00000)
+        /lib64/ld-linux-x86-64.so.2 (0x00000035d2600000)
+
+    If you see libmunge.so.2 it means the you have library enabled version
+    of TORQUE.
+
+ 
+ Q: I'm geting "Invalid Credential" message during qsub/qstat/qdel/qmgr
+    How to tell what is happening?
+ A: Some of TORQUE client tools need better error reporting. 
+    Check your logs on server for relevant messages.
+    You can try using strace to get some additional information on client:
+
+    $> qstat
+    qstat: Invalid credential 
+
+    $> strace -e trace=read -s512 qstat 
+    ...
+    read(4, "", 256)                        = 0
+    read(3, "+2+15+15021+0+72+46Invalid credential MSG=Credentials from future", 262144) = 65
+    read(3, "+2+15+15021+0+72+18Invalid credential", 262144) = 37
+    qstat: Invalid credential 
+
+    In this particular example problem is caused by significant clock difference.
+
diff -urN torque-2.5.12.orig/src/lib/Libifl/pbsD_connect.c torque-2.5.12/src/lib/Libifl/pbsD_connect.c
--- torque-2.5.12.orig/src/lib/Libifl/pbsD_connect.c	2012-03-08 22:34:58.000000000 +0100
+++ torque-2.5.12/src/lib/Libifl/pbsD_connect.c	2012-07-10 11:31:41.000000000 +0200
@@ -121,7 +121,9 @@
 #include "net_connect.h"
 #include "log.h"
 
-
+#if defined(MUNGE_AUTH_LIB)
+#include <munge.h>
+#endif
 
 #define CNTRETRYDELAY 5
 #define MUNGE_SIZE 256 /* I do not know what the proper size of this should be. My 
@@ -362,7 +364,7 @@
  * PBSD_munge_authenticate - This function will use munge to authenticate 
  * a user connection with the server. 
  */
-#ifdef MUNGE_AUTH
+#if defined(MUNGE_AUTH) && !defined(MUNGE_AUTH_LIB)
 int PBSD_munge_authenticate(
 
   int psock,  /* I */
@@ -456,7 +458,120 @@
     return(PBSE_NONE);
     }
   }
-#endif /* ifdef MUNGE_AUTH */
+#endif /* if defined(MUNGE_AUTH) && !defined(MUNGE_AUTH_LIB) */
+
+
+
+/* MUNGE library supported authentication
+ * PBSD_munge_authenticate - This function will use munge to authenticate 
+ * a user connection with the server. 
+ */
+#if defined(MUNGE_AUTH) && defined(MUNGE_AUTH_LIB)
+int PBSD_munge_cred_destroy(
+	char ** cred) /* I */
+
+  {
+  volatile char *ptr = NULL;
+
+  if (cred == NULL || *cred == NULL)
+    return (-1);
+
+  ptr = *cred;
+
+  while (*ptr != '\0')
+    {
+    *ptr++ = 0; /* Munge memburn replacement */
+    }
+
+  free(*cred);
+  *cred = NULL;
+
+  return 0;
+  }
+
+int PBSD_munge_authenticate(
+
+  int psock,  /* I */
+  int handle) /* I */
+
+  {
+  static char        *id = "PBSD_munge_authenticate";
+  int                 rc;
+
+  munge_ctx_t         mctx = NULL;
+  munge_err_t         mret = EMUNGE_SNAFU;
+  char               *mcred = NULL;
+
+
+  /* user id and name stuff */
+  struct passwd      *pwent;
+  uid_t               myrealuid;
+  struct batch_reply *reply;
+  unsigned short      user_port = 0;
+  struct sockaddr_in  sockname;
+  socklen_t           socknamelen = sizeof(sockname);
+
+  if ((mctx = munge_ctx_create()) == NULL)
+    {
+	return(-1);
+    }
+
+  if ((mret = munge_encode (&mcred, mctx, NULL, 0)) != EMUNGE_SUCCESS)
+    {
+      const char *merrmsg = NULL;
+      if (!(merrmsg = munge_ctx_strerror(mctx)))
+        {
+        merrmsg = munge_strerror(mret);
+        }
+      fprintf(stderr, "munge_encode failed: %s (%d)\n", merrmsg, mret);
+      munge_ctx_destroy(mctx);
+      return(PBSE_MUNGE_NOT_FOUND); /*TODO more fine-grained error codes? */
+    }
+  
+  munge_ctx_destroy(mctx);
+
+  /* We got the certificate. Now make the PBS_BATCH_AltAuthenUser request */
+  myrealuid = getuid();
+  pwent = getpwuid(myrealuid);
+  
+  rc = getsockname(psock, (struct sockaddr *)&sockname, &socknamelen);
+  
+  if (rc == -1)
+    {
+    fprintf(stderr, "getsockname failed: %d\n", errno);
+    return(-1);
+    }
+  
+  user_port = ntohs(sockname.sin_port);
+  
+  DIS_tcp_setup(psock);
+  
+  if ((rc = encode_DIS_ReqHdr(psock, PBS_BATCH_AltAuthenUser, pwent->pw_name)) ||
+      (rc = diswui(psock, user_port)) ||
+      (rc = diswst(psock, mcred)) ||
+      (rc = encode_DIS_ReqExtend(psock, NULL)) ||
+      (rc = DIS_tcp_wflush(psock)))
+    {
+    PBSD_munge_cred_destroy(&mcred);
+    /* ERROR */
+    return(rc);
+    }
+  else
+    {
+    PBSD_munge_cred_destroy(&mcred);
+    /* read the reply */
+    if ((reply = PBSD_rdrpy(handle)) != NULL)
+      free(reply);
+    
+    return(PBSE_NONE);
+    }
+  }
+#endif /* if defined(MUNGE_AUTH) && defined(MUNGE_AUTH_LIB) */
+
+
+
+
+
 
 
 /*
diff -urN torque-2.5.12.orig/src/server/req_getcred.c torque-2.5.12/src/server/req_getcred.c
--- torque-2.5.12.orig/src/server/req_getcred.c	2012-01-13 19:19:17.000000000 +0100
+++ torque-2.5.12/src/server/req_getcred.c	2012-07-11 11:34:06.000000000 +0200
@@ -107,6 +107,11 @@
 #include "batch_request.h"
 #include "errno.h"
 
+#if defined(MUNGE_AUTH_LIB)
+#include <munge.h> 
+#include <pwd.h>
+#endif
+
 #define SPACE 32 /* ASCII space character */
 
 /* External Global Data Items Referenced */
@@ -145,6 +150,14 @@
   return;
   }  /* END req_connect() */
 
+
+#if !defined(MUNGE_AUTH_LIB)
+
+/* 
+ * MUNGE Authentication helper function - non-library version
+ * get_encode_host -
+ */ 
+
 int get_encode_host(int s, char *munge_buf, struct batch_request *preq)
 {
   char *ptr;
@@ -215,9 +228,6 @@
 
   }
 
-
-
-
 int write_munge_temp_file(
 
   struct batch_request *preq,          /* I */
@@ -388,6 +398,139 @@
   return(rc);
   } /* END unmunge_request() */
 
+#elif defined(MUNGE_AUTH_LIB) /* MUNGE library support */
+
+/*
+ * MUNGE Authentication helper function - library enabled version
+ * get_encode_host
+ *
+ */
+
+int get_encode_host(int s, munge_ctx_t mctx, struct batch_request *preq)
+{
+  struct in_addr  addr;
+  struct hostent *hptr;
+  munge_err_t mret = EMUNGE_SNAFU;
+
+  mret = munge_ctx_get(mctx, MUNGE_OPT_ADDR4, &addr);
+  if (mret != EMUNGE_SUCCESS)
+  {
+	req_reject(PBSE_BADCRED, 0, preq, NULL, "Unable to read IP address from message");
+	return (-1);
+  }
+
+  if ((hptr = gethostbyaddr ((char *) &addr, sizeof (addr), AF_INET)) == NULL || hptr->h_name == NULL)
+  {
+		req_reject(PBSE_SYSTEM, 0, preq, NULL, "Unable to resolve IP address");
+		return (-1);
+  }
+
+  strncpy(conn_credent[s].hostname, hptr->h_name, PBS_MAXHOSTNAME - 1);
+  conn_credent[s].hostname[PBS_MAXHOSTNAME - 1] = '\0';
+  return(0);
+
+}
+
+/* MUNGE Authentication helper function - library enabled version
+ * get_UID
+ *
+ */
+
+int get_UID(int s, uid_t uid, struct batch_request *preq)
+  {
+	struct passwd *passwd_ptr = NULL;
+        /* 
+         * By default we allow users unknown to pbs_server to do queries 
+         * this is for compatibility with --enable-munge-auth in >= 2.5.10
+         * 
+         * To force more restrictive mode set PBS_MUNGE_STRICT_UID_CHECK 
+         *  environment variable in /var/torque/pbs_environment
+         * 
+         */
+        if ((passwd_ptr = getpwuid(uid)) == NULL && getenv("PBS_MUNGE_STRICT_UID_CHECK") != NULL )
+	{
+		req_reject(PBSE_BADCRED, 0, preq, NULL, "unknown user");
+		return (-1);
+	}
+        /* try to simulate unmunge command behavior */
+        strncpy(conn_credent[s].username, (passwd_ptr ? passwd_ptr->pw_name : "???"), PBS_MAXUSER - 1);
+	conn_credent[s].username[PBS_MAXUSER - 1] = '\0';
+
+	return PBSE_NONE;
+
+  }
+
+/* MUNGE authentication - library enabled function
+ * 
+ * unmunge_request - process and verify MUNGE credentials for a given request 
+ */
+
+
+int unmunge_request(
+    
+  int                   s,
+  struct batch_request *preq)
+
+  {
+  int             rc = -1;
+  munge_ctx_t mctx = NULL;
+  munge_err_t mret = EMUNGE_SNAFU;
+  uid_t uid;
+  gid_t gid;
+
+  if ((mctx = munge_ctx_create()) == NULL)
+  {
+    req_reject(PBSE_SYSTEM, 0, preq, NULL, "couldn't create munge ctxt");
+    return (-1);
+  }
+
+  mret = munge_decode (preq->rq_ind.rq_authen.rq_cred, mctx, NULL, NULL, &uid, &gid);
+
+  switch (mret)
+  {
+  	  case EMUNGE_SUCCESS:
+  		  break;
+  	  case EMUNGE_CRED_EXPIRED:
+  		  req_reject(PBSE_BADCRED, 0, preq, NULL, "Expired credentials");
+  		  munge_ctx_destroy(mctx);
+  		  return (-1);
+  	  case EMUNGE_CRED_REWOUND:
+  		  req_reject(PBSE_BADCRED, 0, preq, NULL, "Credentials from future");
+  		  munge_ctx_destroy(mctx);
+  		  return (-1);
+  	  case EMUNGE_CRED_REPLAYED:
+  		  req_reject(PBSE_BADCRED, 0, preq, NULL, "Credentials replayed");
+  		  munge_ctx_destroy(mctx);
+  		  return (-1);
+  	  default:
+  	  	  {
+  	  		const char *msg = NULL;
+  	        if (!(msg = munge_ctx_strerror(mctx)))
+  	            msg = munge_strerror (mret);
+  	        req_reject(PBSE_SYSTEM, 0, preq, NULL, (char*)msg); /* it's safe cast req_reject has wrong signature */
+    		munge_ctx_destroy(mctx);
+    		return (-1);
+  	  	  }
+  }
+
+  if ((rc = get_encode_host(s, mctx, preq)) != PBSE_NONE)
+  {
+	  munge_ctx_destroy(mctx);
+	  return (-1);
+  }
+
+  if ((rc = get_UID(s, uid, preq)) != PBSE_NONE)
+  {
+	  munge_ctx_destroy(mctx);
+	  return (-1);
+  }
+
+  munge_ctx_destroy(mctx);
+
+  return PBSE_NONE;
+  } /* END unmunge_request() */
+
+#endif /* END MUNGE library enabled functions */
 
 /*
  * Check if the host names match
