diff --git a/projects/cadcAccessControl-Server/build.xml b/projects/cadcAccessControl-Server/build.xml
index e0c3d437bd12e91bc5d87e5548d35b5cfc66d065..c9b7e5c538100ffbf94bf9bf5c529ecfd8b66de1 100644
--- a/projects/cadcAccessControl-Server/build.xml
+++ b/projects/cadcAccessControl-Server/build.xml
@@ -149,7 +149,7 @@
         <pathelement path="${jars}:${testingJars}"/>
       </classpath>
       <sysproperty key="ca.nrc.cadc.util.PropertiesReader.dir" value="test"/>
-      <test name="ca.nrc.cadc.ac.server.web.users.UserActionFactoryTest" />
+      <test name="ca.nrc.cadc.ac.server.ldap.LdapUserDAOTest" />
       <formatter type="plain" usefile="false" />
     </junit>
   </target>
diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/UserPersistence.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/UserPersistence.java
index 070080806602418dc3d0b5cacfc8849e375b0869..a384111bc699d2365af43f5f19b25bf123ba7570 100755
--- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/UserPersistence.java
+++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/UserPersistence.java
@@ -133,7 +133,22 @@ public interface UserPersistence<T extends Principal>
     User<T> getPendingUser(T userID)
             throws UserNotFoundException, TransientException,
                    AccessControlException;
-    
+
+    /**
+     * Get the user specified by userID with all of the users identities.
+     *
+     * @param userID The userID.
+     *
+     * @return User instance.
+     *
+     * @throws UserNotFoundException when the user is not found.
+     * @throws TransientException If an temporary, unexpected problem occurred.
+     * @throws AccessControlException If the operation is not permitted.
+     */
+    User<T> getAugmentedUser(T userID)
+        throws UserNotFoundException, TransientException,
+               AccessControlException;
+
     /**
      * Attempt to login the specified user.
      *
@@ -148,7 +163,7 @@ public interface UserPersistence<T extends Principal>
      */
     Boolean doLogin(String userID, String password)
             throws UserNotFoundException, TransientException, 
-            AccessControlException;
+                   AccessControlException;
    
     /**
      * Updated the user specified by User.
diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapDAO.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapDAO.java
index dae9d245d651331b3a0994cbbfa5d63141c60eaf..9df8ef92109a19d612bd3aab99630494bce9a301 100755
--- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapDAO.java
+++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapDAO.java
@@ -68,22 +68,17 @@
  */
 package ca.nrc.cadc.ac.server.ldap;
 
-import ca.nrc.cadc.auth.HttpPrincipal;
-import ca.nrc.cadc.auth.NumericPrincipal;
-import ca.nrc.cadc.auth.OpenIdPrincipal;
+import ca.nrc.cadc.auth.DNPrincipal;
 import ca.nrc.cadc.net.TransientException;
 import com.unboundid.ldap.sdk.DN;
 import com.unboundid.ldap.sdk.LDAPConnection;
 import com.unboundid.ldap.sdk.LDAPException;
 import com.unboundid.ldap.sdk.ResultCode;
-import com.unboundid.ldap.sdk.SearchResult;
-import com.unboundid.ldap.sdk.SearchScope;
 import org.apache.log4j.Logger;
 
 import javax.net.SocketFactory;
 import javax.net.ssl.SSLSocketFactory;
 import javax.security.auth.Subject;
-import javax.security.auth.x500.X500Principal;
 import java.security.AccessControlException;
 import java.security.AccessController;
 import java.security.GeneralSecurityException;
@@ -159,12 +154,12 @@ public abstract class LdapDAO
         }
     }
 
-    protected DN getSubjectDN() throws LDAPException
+    protected DN getSubjectDN()
+        throws LDAPException
     {
         if (subjDN == null)
         {
-            Subject callerSubject =
-                    Subject.getSubject(AccessController.getContext());
+            Subject callerSubject = getSubject();
             if (callerSubject == null)
             {
                 throw new AccessControlException("Caller not authenticated.");
@@ -176,48 +171,18 @@ public abstract class LdapDAO
                 throw new AccessControlException("Caller not authenticated.");
             }
 
-            String ldapField = null;
             for (Principal p : principals)
             {
-                if (p instanceof HttpPrincipal)
+                if (p instanceof DNPrincipal)
                 {
-                    ldapField = "(uid=" + p.getName() + ")";
-                    break;
-                }
-                if (p instanceof NumericPrincipal)
-                {
-                    ldapField = "(numericid=" + p.getName() + ")";
-                    break;
-                }
-                if (p instanceof X500Principal)
-                {
-                    ldapField = "(distinguishedname=" + p.getName() + ")";
-                    break;
-                }
-                if (p instanceof OpenIdPrincipal)
-                {
-                    ldapField = "(openid=" + p.getName() + ")";
-                    break;
+                    subjDN = new DN(p.getName());
                 }
             }
 
-            if (ldapField == null)
+            if (subjDN == null)
             {
                 throw new AccessControlException("Identity of caller unknown.");
             }
-
-            SearchResult searchResult =
-                    getConnection().search(config.getUsersDN(), SearchScope.ONE,
-                            ldapField, "entrydn");
-
-            if (searchResult.getEntryCount() < 1)
-            {
-                throw new AccessControlException(
-                        "No LDAP account when search with rule " + ldapField);
-            }
-
-            subjDN = (searchResult.getSearchEntries().get(0))
-                    .getAttributeValueAsDN("entrydn");
         }
         return subjDN;
     }
@@ -268,4 +233,9 @@ public abstract class LdapDAO
         throw new RuntimeException("Ldap error (" + code.getName() + ")");
     }
 
+    protected Subject getSubject()
+    {
+        return Subject.getSubject(AccessController.getContext());
+    }
+
 }
diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapUserDAO.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapUserDAO.java
index 5108b0828c2c1618262d3aa22e63eedc69057829..a886b900f76e043157b596a0f45c147d62effac4 100755
--- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapUserDAO.java
+++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapUserDAO.java
@@ -80,6 +80,7 @@ import java.util.Random;
 
 import javax.security.auth.x500.X500Principal;
 
+import ca.nrc.cadc.auth.DNPrincipal;
 import org.apache.log4j.Logger;
 
 import ca.nrc.cadc.ac.PersonalDetails;
@@ -146,7 +147,7 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO
     protected static final String LDAP_INSTITUTE = "institute";
     protected static final String LDAP_UID = "uid";
 
-    
+
     private String[] userAttribs = new String[]
             {
                     LDAP_FIRST_NAME, LDAP_LAST_NAME, LDAP_ADDRESS, LDAP_CITY,
@@ -156,6 +157,10 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO
             {
                     LDAP_FIRST_NAME, LDAP_LAST_NAME
             };
+    private String[] identityAttribs = new String[]
+        {
+            LDAP_UID, LDAP_DISTINGUISHED_NAME, LDAP_NUMERICID, LDAP_ENTRYDN
+        };
 
     public LdapUserDAO(LdapConfig config)
     {
@@ -307,7 +312,7 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO
             catch (UserNotFoundException e)
             {
                 throw new RuntimeException("BUG: new user " + userDN.toNormalizedString() +
-                    " not found because " + e.getMessage());
+                    " not found");
             }
         }
         catch (LDAPException e)
@@ -367,8 +372,8 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO
         try
         {
             // add new user
-        	
-            DN userX500DN = getUserRequestsDN(user.getUserID().getName());        	
+
+            DN userX500DN = getUserRequestsDN(user.getUserID().getName());
             List<Attribute> attributes = new ArrayList<Attribute>();
             addAttribute(attributes, LDAP_OBJECT_CLASS, LDAP_INET_ORG_PERSON);
             addAttribute(attributes, LDAP_OBJECT_CLASS, LDAP_INET_USER);
@@ -377,13 +382,13 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO
                 .getName());
             addAttribute(attributes, LADP_USER_PASSWORD, new String(userRequest
                     .getPassword()));
-            addAttribute(attributes, LDAP_NUMERICID, 
+            addAttribute(attributes, LDAP_NUMERICID,
                     String.valueOf(genNextNumericId()));
             for (Principal princ : user.getIdentities())
             {
                 if (princ instanceof X500Principal)
                 {
-                    addAttribute(attributes, LDAP_DISTINGUISHED_NAME, 
+                    addAttribute(attributes, LDAP_DISTINGUISHED_NAME,
                             princ.getName());
                 }
             }
@@ -545,6 +550,57 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO
         return user;
     }
 
+    public User<T> getAugmentedUser(final T userID)
+        throws UserNotFoundException, TransientException
+    {
+        String searchField = userLdapAttrib.get(userID.getClass());
+        if (searchField == null)
+        {
+            throw new IllegalArgumentException(
+                "Unsupported principal type " + userID.getClass());
+        }
+
+        try
+        {
+
+            searchField = "(" + searchField + "=" + userID.getName() + ")";
+
+            logger.debug("search field: " + searchField);
+
+            // TODO: Search must take into account deleted users (nsaccountlock attr)
+
+            SearchRequest searchRequest =
+                    new SearchRequest(config.getUsersDN(), SearchScope.ONE,
+                        searchField, identityAttribs);
+
+            SearchResultEntry searchResult = getConnection().searchForEntry(searchRequest);
+
+            if (searchResult == null)
+            {
+                String msg = "User not found " + userID.toString();
+                logger.debug(msg);
+                throw new UserNotFoundException(msg);
+            }
+
+            User<T> user = new User<T>(userID);
+            user.getIdentities().add(new HttpPrincipal(
+                searchResult.getAttributeValue(LDAP_UID)));
+            user.getIdentities().add(new NumericPrincipal(
+                searchResult.getAttributeValueAsLong(LDAP_NUMERICID)));
+            user.getIdentities().add(new X500Principal(
+                searchResult.getAttributeValue(LDAP_DISTINGUISHED_NAME)));
+            user.getIdentities().add(new DNPrincipal(
+                searchResult.getAttributeValue(LDAP_ENTRYDN)));
+            return user;
+        }
+        catch (LDAPException e)
+        {
+            logger.debug("getGroup Exception: " + e, e);
+            LdapDAO.checkLdapResult(e.getResultCode());
+            throw new RuntimeException("BUG: checkLdapResult didn't throw an exception");
+        }
+    }
+
     /**
      * Obtain whether the given DN tree requires authentication.
      *
@@ -1037,9 +1093,9 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO
             LdapDAO.checkLdapResult(code);
         }
     }
-    
+
     /**
-     * Method to return a randomly generated user numeric ID. The default 
+     * Method to return a randomly generated user numeric ID. The default
      * implementation returns a value between 10000 and Integer.MAX_VALUE.
      * Services that support a different mechanism for generating numeric
      * IDs overide this method.
diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapUserPersistence.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapUserPersistence.java
index fd8b41ec1abb427b629fc026f53eda34b767937a..f39a41af9f1c305945416d3b2961b559a5938bd3 100755
--- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapUserPersistence.java
+++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapUserPersistence.java
@@ -115,14 +115,14 @@ public class LdapUserPersistence<T extends Principal>
             }
         }
     }
-    
+
     /**
      * Add the new user.
      *
      * @param user
      *
      * @return User instance.
-     * 
+     *
      * @throws TransientException If an temporary, unexpected problem occurred.
      * @throws AccessControlException If the operation is not permitted.
      */
@@ -151,7 +151,7 @@ public class LdapUserPersistence<T extends Principal>
      * @param userID The userID.
      *
      * @return User instance.
-     * 
+     *
      * @throws UserNotFoundException when the user is not found.
      * @throws TransientException If an temporary, unexpected problem occurred.
      * @throws AccessControlException If the operation is not permitted.
@@ -202,13 +202,42 @@ public class LdapUserPersistence<T extends Principal>
         }
     }
 
+    /**
+     * Get the user specified by userID with all of the users identities.
+     *
+     * @param userID The userID.
+     *
+     * @return User instance.
+     *
+     * @throws UserNotFoundException when the user is not found.
+     * @throws TransientException If an temporary, unexpected problem occurred.
+     * @throws AccessControlException If the operation is not permitted.
+     */
+    public User<T> getAugmentedUser(T userID)
+        throws UserNotFoundException, TransientException
+    {
+        LdapUserDAO<T> userDAO = null;
+        try
+        {
+            userDAO = new LdapUserDAO<T>(this.config);
+            return userDAO.getAugmentedUser(userID);
+        }
+        finally
+        {
+            if (userDAO != null)
+            {
+                userDAO.close();
+            }
+        }
+    }
+
     /**
      * Get the user specified by userID.
      *
      * @param userID The userID.
      *
      * @return Boolean.
-     * 
+     *
      * @throws UserNotFoundException when the user is not found.
      * @throws TransientException If an temporary, unexpected problem occurred.
      * @throws AccessControlException If the operation is not permitted.
@@ -237,13 +266,13 @@ public class LdapUserPersistence<T extends Principal>
      * @param user          The user to update.
      *
      * @return User instance.
-     * 
+     *
      * @throws UserNotFoundException when the user is not found.
      * @throws TransientException If an temporary, unexpected problem occurred.
      * @throws AccessControlException If the operation is not permitted.
      */
     public User<T> modifyUser(User<T> user)
-        throws UserNotFoundException, TransientException, 
+        throws UserNotFoundException, TransientException,
                AccessControlException
     {
         LdapUserDAO<T> userDAO = null;
@@ -288,18 +317,18 @@ public class LdapUserPersistence<T extends Principal>
             }
         }
     }
-    
+
     /**
      * Delete the user specified by userID.
      *
      * @param userID The userID.
-     * 
+     *
      * @throws UserNotFoundException when the user is not found.
      * @throws TransientException If an temporary, unexpected problem occurred.
      * @throws AccessControlException If the operation is not permitted.
      */
     public void deleteUser(T userID)
-        throws UserNotFoundException, TransientException, 
+        throws UserNotFoundException, TransientException,
                AccessControlException
     {
         LdapUserDAO<T> userDAO = null;
@@ -316,17 +345,17 @@ public class LdapUserPersistence<T extends Principal>
             }
         }
     }
-    
+
     /**
      * Get all groups the user specified by userID belongs to. This method is created
      * to provide optimization for the LDAP server.
-     * 
+     *
      * @param userID The userID.
      * @param isAdmin return only admin Groups when true, else return non-admin
      *                Groups.
-     * 
+     *
      * @return Collection of Group DN.
-     * 
+     *
      * @throws UserNotFoundException  when the user is not found.
      * @throws TransientException If an temporary, unexpected problem occurred.
      * @throws AccessControlException If the operation is not permitted.
@@ -348,7 +377,7 @@ public class LdapUserPersistence<T extends Principal>
             }
         }
     }
-    
+
     /**
      * Check whether the user is a member of the group. This method is created
      * to provide optimization for the LDAP server.
diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/AbstractUserAction.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/AbstractUserAction.java
index af79d45ffa72d6f8adcbe4db50a154d006aca303..0bc7392038066642dccb6dc7d7dca583a7f68042 100644
--- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/AbstractUserAction.java
+++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/AbstractUserAction.java
@@ -108,7 +108,7 @@ public abstract class AbstractUserAction implements PrivilegedExceptionAction<Ob
     static final String DEFAULT_CONTENT_TYPE = "text/xml";
     static final String JSON_CONTENT_TYPE = "application/json";
 
-    protected String augmentUserDN;
+    protected boolean isAugmentUser;
     protected UserLogInfo logInfo;
     protected SyncOutput syncOut;
 
@@ -116,18 +116,19 @@ public abstract class AbstractUserAction implements PrivilegedExceptionAction<Ob
 
     AbstractUserAction()
     {
+        this.isAugmentUser = false;
     }
 
     public abstract void doAction() throws Exception;
 
-    public void setAugmentUserDN(final String dn)
+    public void setAugmentUser(final boolean isAugmentUser)
     {
-    	this.augmentUserDN = dn;
+    	this.isAugmentUser = isAugmentUser;
     }
     
-    public String getAugmentUserDN()
+    public boolean isAugmentUser()
     {
-    	return this.augmentUserDN;
+    	return this.isAugmentUser;
     }
     
     public void setLogInfo(UserLogInfo logInfo)
diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/GetUserAction.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/GetUserAction.java
index 7442a6896a6438ea878d7809a69645198be3af7f..ee81cfd60b063125547483e437c89e58a1d5cb13 100644
--- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/GetUserAction.java
+++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/GetUserAction.java
@@ -71,25 +71,18 @@ import ca.nrc.cadc.ac.PersonalDetails;
 import ca.nrc.cadc.ac.User;
 import ca.nrc.cadc.ac.UserNotFoundException;
 import ca.nrc.cadc.ac.server.UserPersistence;
-import ca.nrc.cadc.auth.HttpPrincipal;
-import ca.nrc.cadc.auth.NumericPrincipal;
+import org.apache.log4j.Logger;
 
-import java.security.AccessControlContext;
+import javax.security.auth.Subject;
 import java.security.AccessController;
 import java.security.Principal;
-import java.security.PrivilegedExceptionAction;
 import java.util.Set;
 
-import javax.security.auth.Subject;
-import javax.security.auth.x500.X500Principal;
-
-import org.apache.log4j.Logger;
-
-
 
 public class GetUserAction extends AbstractUserAction
 {
     private static final Logger log = Logger.getLogger(GetUserAction.class);
+
     private final Principal userID;
     private final String detail;
 
@@ -102,56 +95,58 @@ public class GetUserAction extends AbstractUserAction
 
 	public void doAction() throws Exception
     {
-        User<Principal> user;
- 
-        if (isAugmentUser())
-        {
-    		Subject subject = new Subject();
-        	subject.getPrincipals().add(this.userID);
-        	user = Subject.doAs(subject, new PrivilegedExceptionAction<User<Principal>>()
-        	{
-				@Override
-				public User<Principal> run() throws Exception 
-				{
-					return getUser(userID);
-				}
-        		
-        	});
-        }
-        else
-        {
-        	user = getUser(this.userID);
-        }
-
+        User<Principal> user = getUser(this.userID);
         writeUser(user);
     }
 
     protected User<Principal> getUser(Principal principal) throws Exception
     {
+        User<Principal> user;
         final UserPersistence<Principal> userPersistence = getUserPersistence();
-    	User<Principal> user;
-    	
-    	try
+
+        /**
+         * Special case 1
+         * If the calling Subject user is the notAugmentedX500User, AND it is
+         * a GET, call the userDAO to get the User with all identities.
+         */
+        if (isAugmentUser())
         {
-            user = userPersistence.getUser(principal);
+            log.debug("getting augmented user " + principal.getName());
+            user = userPersistence.getAugmentedUser(principal);
         }
-        catch (UserNotFoundException e)
+
+        /**
+         * Special case 2
+         * If detail=identity, AND if the calling Subject user is the same as
+         * the requested User, then return the User with the principals from the
+         * Subject which has already been augmented.
+         */
+        else if (detail != null &&
+                 detail.equalsIgnoreCase("identity") &&
+                 isSubjectUser(principal))
         {
-            user = userPersistence.getPendingUser(principal);
+            log.debug("augmenting " + principal.getName() + " from subject");
+            Subject subject = Subject.getSubject(AccessController.getContext());
+            user = new User<Principal>(principal);
+            user.getIdentities().addAll(subject.getPrincipals());
         }
-    	
-        if (detail != null)
+        else
         {
-            // Only return user principals
-            if (detail.equals("identity"))
+            log.debug("getting user " + principal.getName());
+            try
             {
-                user.details.clear();
+                user = userPersistence.getUser(principal);
             }
+            catch (UserNotFoundException e)
+            {
+                user = userPersistence.getPendingUser(principal);
+            }
+
             // Only return user profile info, first and last name.
-            else if (detail.equals("display"))
+            if (detail != null && detail.equalsIgnoreCase("display"))
             {
                 user.getIdentities().clear();
-                Set<PersonalDetails> details =  user.getDetails(PersonalDetails.class);
+                Set<PersonalDetails> details = user.getDetails(PersonalDetails.class);
                 if (details.isEmpty())
                 {
                     String error = principal.getName() + " missing required PersonalDetails";
@@ -161,30 +156,27 @@ public class GetUserAction extends AbstractUserAction
                 user.details.clear();
                 user.details.add(new PersonalDetails(pd.getFirstName(), pd.getLastName()));
             }
-            else
-            {
-                throw new IllegalArgumentException("Illegal detail parameter " + detail);
-            }
+
         }
 
-        return user;
+    	return user;
     }
-    
-    protected boolean isAugmentUser()
+
+    protected boolean isSubjectUser(Principal userPrincipal)
     {
-        AccessControlContext acc = AccessController.getContext();
-        Subject subject = Subject.getSubject(acc);
+    	boolean isSubjectUser = false;
+        Subject subject = Subject.getSubject(AccessController.getContext());
         if (subject != null)
         {
-        	for (Principal principal : subject.getPrincipals(HttpPrincipal.class))
+        	for (Principal subjectPrincipal : subject.getPrincipals())
         	{
-            	if (principal.getName().equals(this.getAugmentUserDN()))
+        		if (subjectPrincipal.getName().equals(userPrincipal.getName()))
         		{
-        			return true;
+                    isSubjectUser = true;
+        			break;
         		}
         	}
         }
-        
-        return false;
+        return isSubjectUser;
     }
 }
diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UserActionFactory.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UserActionFactory.java
index 30583c7ff083819565324705e964097eb6cc743f..a369ac4944ab4cfbe55bf02dcabbf13ada37a5dd 100644
--- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UserActionFactory.java
+++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UserActionFactory.java
@@ -75,16 +75,14 @@ import ca.nrc.cadc.auth.HttpPrincipal;
 import ca.nrc.cadc.auth.IdentityType;
 import ca.nrc.cadc.auth.NumericPrincipal;
 import ca.nrc.cadc.auth.OpenIdPrincipal;
+import org.apache.log4j.Logger;
 
+import javax.security.auth.x500.X500Principal;
+import javax.servlet.http.HttpServletRequest;
 import java.io.IOException;
 import java.net.URL;
 import java.security.Principal;
 
-import javax.security.auth.x500.X500Principal;
-import javax.servlet.http.HttpServletRequest;
-
-import org.apache.log4j.Logger;
-
 
 public abstract class UserActionFactory
 {
diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UserServlet.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UserServlet.java
index 6dedcc71833bd72d4206f9e0b989b17e05b2a046..e73a9ae960f0fe30961108681ca9c8964c1b34b3 100644
--- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UserServlet.java
+++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UserServlet.java
@@ -68,30 +68,37 @@
  */
 package ca.nrc.cadc.ac.server.web.users;
 
-import java.io.IOException;
-import java.security.PrivilegedActionException;
+import ca.nrc.cadc.ac.server.web.SyncOutput;
+import ca.nrc.cadc.auth.AuthenticationUtil;
+import ca.nrc.cadc.auth.ServletPrincipalExtractor;
+import ca.nrc.cadc.auth.X509CertificateChain;
+import ca.nrc.cadc.util.ArrayUtil;
+import ca.nrc.cadc.util.StringUtil;
+import org.apache.log4j.Logger;
 
 import javax.security.auth.Subject;
+import javax.security.auth.x500.X500Principal;
 import javax.servlet.ServletConfig;
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
-
-import ca.nrc.cadc.util.StringUtil;
-
-import org.apache.log4j.Logger;
-
-import ca.nrc.cadc.ac.server.web.SyncOutput;
-import ca.nrc.cadc.auth.AuthenticationUtil;
+import java.io.IOException;
+import java.security.AccessController;
+import java.security.Principal;
+import java.security.PrivilegedActionException;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+import java.util.Set;
 
 public class UserServlet extends HttpServlet
 {
 
     private static final long serialVersionUID = 5289130885807305288L;
     private static final Logger log = Logger.getLogger(UserServlet.class);
-    private String augmentUser;
-    
+
+    private String notAugmentedX500User;
+
     @Override
     public void init(final ServletConfig config) throws ServletException
     {
@@ -99,8 +106,8 @@ public class UserServlet extends HttpServlet
 
         try
         {
-        	this.augmentUser = config.getInitParameter(UserServlet.class.getName() + ".augmentUser");
-            log.info("augmentUser: " + augmentUser);
+        	this.notAugmentedX500User = config.getInitParameter(UserServlet.class.getName() + ".NotAugmentedX500User");
+            log.info("notAugmentedX500User: " + notAugmentedX500User);
         }
         catch(Exception ex)
         {
@@ -120,13 +127,25 @@ public class UserServlet extends HttpServlet
         try
         {
             log.info(logInfo.start());
-            Subject subject = AuthenticationUtil.getSubject(request);
+            AbstractUserAction action = factory.createAction(request);
+
+            // Special case: if the calling subject has a servops X500Principal,
+            // AND it is a GET request, do not augment the subject.
+            Subject subject;
+            if (action instanceof GetUserAction && isNotAugmentedSubject(request))
+            {
+                subject = Subject.getSubject(AccessController.getContext());
+                log.debug("subject not augmented: " + subject);
+                action.setAugmentUser(true);
+            }
+            else
+            {
+                subject = AuthenticationUtil.getSubject(request);
+                log.debug("augmented subject: " + subject);
+            }
             logInfo.setSubject(subject);
 
-            AbstractUserAction action = factory.createAction(request);
             SyncOutput syncOut = new SyncOutput(response);
-
-            action.setAugmentUserDN(this.augmentUser);
             action.setLogInfo(logInfo);
             action.setSyncOut(syncOut);
             action.setAcceptedContentType(getAcceptedContentType(request));
@@ -236,4 +255,25 @@ public class UserServlet extends HttpServlet
             return AbstractUserAction.DEFAULT_CONTENT_TYPE;
         }
     }
+
+    protected boolean isNotAugmentedSubject(HttpServletRequest request)
+    {
+        ServletPrincipalExtractor extractor = new ServletPrincipalExtractor(request);
+        Set<Principal> principals = extractor.getPrincipals();
+        log.debug("Principals: " + principals);
+
+        for (Principal principal : principals)
+        {
+            if (principal instanceof X500Principal)
+            {
+                if (principal.getName().equalsIgnoreCase(notAugmentedX500User))
+                {
+                    return true;
+                }
+            }
+        }
+
+        return false;
+
+    }
 }
diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/auth/AuthenticatorImpl.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/auth/AuthenticatorImpl.java
index 024549e6ea3053593c4734ac608638b875154193..1812fc7eaa9cc6704f2022fe4b3085fda9eb5a5e 100644
--- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/auth/AuthenticatorImpl.java
+++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/auth/AuthenticatorImpl.java
@@ -72,10 +72,13 @@ package ca.nrc.cadc.auth;
 import ca.nrc.cadc.ac.User;
 import ca.nrc.cadc.ac.UserNotFoundException;
 import ca.nrc.cadc.ac.server.ldap.LdapUserPersistence;
+import ca.nrc.cadc.net.TransientException;
 import ca.nrc.cadc.profiler.Profiler;
 import org.apache.log4j.Logger;
 
 import javax.security.auth.Subject;
+
+import java.security.AccessControlException;
 import java.security.Principal;
 import java.security.PrivilegedActionException;
 import java.security.PrivilegedExceptionAction;
@@ -123,34 +126,31 @@ public class AuthenticatorImpl implements Authenticator
 
     protected void augmentSubject(final Subject subject)
     {
+
         try
         {
-            PrivilegedExceptionAction<Object> action =
-                new PrivilegedExceptionAction<Object>()
-                {
-                    public Object run() throws Exception
-                    {
-                        try
-                        {
-                            LdapUserPersistence<Principal> dao = new LdapUserPersistence<Principal>();
-                            User<Principal> user = dao.getUser(subject.getPrincipals().iterator().next());
-                            subject.getPrincipals().addAll(user.getIdentities());
-                        }
-                        catch (UserNotFoundException e)
-                        {
-                            // ignore, could be an anonymous user
-                        }
-                        return null;
-                    }
-                };
-
-            Subject.doAs(subject, action);
+            LdapUserPersistence<Principal> dao = new LdapUserPersistence<Principal>();
+            User<Principal> user = dao.getAugmentedUser(subject.getPrincipals().iterator().next());
+            if (user.getIdentities() != null)
+            {
+                log.debug("Found " + user.getIdentities().size() + " principals after agument");
+            }
+            else
+            {
+                log.debug("Null identities after augment");
+            }
+            subject.getPrincipals().addAll(user.getIdentities());
         }
-        catch (PrivilegedActionException e)
+        catch (UserNotFoundException e)
         {
-            String msg = "Error augmenting subject " + subject;
-            throw new RuntimeException(msg, e);
+            // ignore, could be an anonymous user
+            log.debug("could not find user for augmenting", e);
         }
+        catch (TransientException e)
+        {
+            throw new IllegalStateException("Internal error", e);
+        }
+
     }
 
 }
diff --git a/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/ldap/LdapDAOTest.java b/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/ldap/LdapDAOTest.java
index 05e33b33e00b65a6d6cc2a48201937f339377647..18b0b109aa38cbf9f89a699d67225b18e522527b 100644
--- a/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/ldap/LdapDAOTest.java
+++ b/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/ldap/LdapDAOTest.java
@@ -68,22 +68,23 @@
 
 package ca.nrc.cadc.ac.server.ldap;
 
-import java.security.PrivilegedExceptionAction;
-
-import javax.net.ssl.SSLSocketFactory;
-import javax.security.auth.Subject;
-import javax.security.auth.x500.X500Principal;
-
+import ca.nrc.cadc.auth.DNPrincipal;
 import ca.nrc.cadc.auth.HttpPrincipal;
 import ca.nrc.cadc.auth.NumericPrincipal;
 import ca.nrc.cadc.util.Log4jInit;
-
+import com.unboundid.ldap.sdk.DN;
 import com.unboundid.ldap.sdk.LDAPConnection;
-
 import org.apache.log4j.Level;
-import org.junit.Test;
 import org.junit.BeforeClass;
-import static org.junit.Assert.*;
+import org.junit.Test;
+
+import javax.security.auth.Subject;
+import javax.security.auth.x500.X500Principal;
+import java.security.PrivilegedExceptionAction;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 
 
 public class LdapDAOTest extends AbstractLdapDAOTest
@@ -172,6 +173,31 @@ public class LdapDAOTest extends AbstractLdapDAOTest
 
     }
 
+    @Test
+    public void testGetSubjectDN() throws Exception
+    {
+        DN expected = new DN("uid=foo,ou=bar,dc=net");
+        final DNPrincipal dnPrincipal = new DNPrincipal(expected.toNormalizedString());
+
+        LdapConfig config = LdapConfig.getLdapConfig("LdapConfig.test.properties");
+        LdapDAO ldapDAO = new LdapDAO(config)
+        {
+            @Override
+            protected Subject getSubject()
+            {
+                Subject subject = new Subject();
+                subject.getPrincipals().add(new HttpPrincipal("foo"));
+                subject.getPrincipals().add(new X500Principal("uid=foo,o=bar"));
+                subject.getPrincipals().add(dnPrincipal);
+                return subject;
+            }
+        };
+
+        DN actual = ldapDAO.getSubjectDN();
+        assertNotNull("DN is null", actual);
+        assertEquals("DN's do not match", expected.toNormalizedString(), actual.toNormalizedString());
+    }
+
     private void testConnection(final LDAPConnection ldapCon)
     {
         assertTrue("Not connected but should be.", ldapCon.isConnected());
diff --git a/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/ldap/LdapGroupDAOTest.java b/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/ldap/LdapGroupDAOTest.java
index 24b055459faa0ebe77d4fb669f3431118b147869..5ec862782981d86de578bb287bb8e6c234e82a8e 100644
--- a/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/ldap/LdapGroupDAOTest.java
+++ b/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/ldap/LdapGroupDAOTest.java
@@ -74,6 +74,7 @@ import ca.nrc.cadc.ac.GroupNotFoundException;
 import ca.nrc.cadc.ac.GroupProperty;
 import ca.nrc.cadc.ac.Role;
 import ca.nrc.cadc.ac.User;
+import ca.nrc.cadc.auth.DNPrincipal;
 import ca.nrc.cadc.auth.HttpPrincipal;
 import ca.nrc.cadc.util.Log4jInit;
 import org.apache.log4j.Level;
@@ -104,7 +105,13 @@ public class LdapGroupDAOTest extends AbstractLdapDAOTest
     static String daoTestDN2 = "cn=" + daoTestUid2 + ",ou=cadc,o=hia,c=ca";
     static String daoTestDN3 = "cn=" + daoTestUid3 + ",ou=cadc,o=hia,c=ca";
     static String unknownDN = "cn=foo,ou=cadc,o=hia,c=ca";
-    
+
+    static String daoTestEntryDN1 = "uid=cadcdaotest1,ou=users,ou=ds,dc=testcanfar";
+    static String daoTestEntryDN2 = "uid=cadcdaotest2,ou=users,ou=ds,dc=testcanfar";
+
+    static DNPrincipal daoDNPrincipal1;
+    static DNPrincipal daoDNPrincipal2;
+
     static X500Principal daoTestPrincipal1;
     static X500Principal daoTestPrincipal2;
     static X500Principal daoTestPrincipal3;
@@ -135,6 +142,9 @@ public class LdapGroupDAOTest extends AbstractLdapDAOTest
         daoTestPrincipal3 = new X500Principal(daoTestDN3);
         unknownPrincipal = new X500Principal(unknownDN);
 
+        daoDNPrincipal1 = new DNPrincipal(daoTestEntryDN1);
+        daoDNPrincipal2 = new DNPrincipal(daoTestEntryDN2);
+
         daoTestUser1 = new User<X500Principal>(daoTestPrincipal1);
         daoTestUser2 = new User<X500Principal>(daoTestPrincipal2);
         daoTestUser3 = new User<X500Principal>(daoTestPrincipal3);
@@ -142,9 +152,11 @@ public class LdapGroupDAOTest extends AbstractLdapDAOTest
         
         daoTestUser1Subject = new Subject();
         daoTestUser1Subject.getPrincipals().add(daoTestUser1.getUserID());
+        daoTestUser1Subject.getPrincipals().add(daoDNPrincipal1);
         
         daoTestUser2Subject = new Subject();
         daoTestUser2Subject.getPrincipals().add(daoTestUser2.getUserID());
+        daoTestUser2Subject.getPrincipals().add(daoDNPrincipal2);
         
         anonSubject = new Subject();
         anonSubject.getPrincipals().add(unknownUser.getUserID());
diff --git a/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/ldap/LdapUserDAOTest.java b/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/ldap/LdapUserDAOTest.java
index cb143e90e8fedc9c87677763f09ac55b3c23b67f..68ca8ae3855d9854db2b82281ac95d13f1de7bfb 100644
--- a/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/ldap/LdapUserDAOTest.java
+++ b/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/ldap/LdapUserDAOTest.java
@@ -82,6 +82,7 @@ import java.util.Random;
 import javax.security.auth.Subject;
 import javax.security.auth.x500.X500Principal;
 
+import ca.nrc.cadc.auth.DNPrincipal;
 import org.apache.log4j.Level;
 import org.apache.log4j.Logger;
 import org.junit.BeforeClass;
@@ -103,12 +104,16 @@ public class LdapUserDAOTest extends AbstractLdapDAOTest
     private static final Logger log = Logger.getLogger(LdapUserDAOTest.class);
 
     static final String testUserX509DN = "cn=cadcdaotest1,ou=cadc,o=hia,c=ca";
+    static final String testUser1EntryDN = "uid=cadcdaotest1,ou=users,ou=ds,dc=testcanfar";
+    static final String testUser2EntryDN = "uid=cadcdaotest2,ou=users,ou=ds,dc=testcanfar";
     static int nextUserNumericID = 666;
 
     static String testUserDN;
     static User<X500Principal> testUser;
     static User<X500Principal> testMember;
     static User<HttpPrincipal> testPendingUser;
+    static DNPrincipal testUser1DNPrincipal;
+    static DNPrincipal testUser2DNPrincipal;
     static LdapConfig config;
     static Random ran = new Random(); // source of randomness for numeric ids
 
@@ -117,7 +122,7 @@ public class LdapUserDAOTest extends AbstractLdapDAOTest
     public static void setUpBeforeClass()
             throws Exception
     {
-        Log4jInit.setLevel("ca.nrc.cadc.ac", Level.DEBUG);
+        Log4jInit.setLevel("ca.nrc.cadc.ac", Level.INFO);
 
         // get the configuration of the development server from and config files...
         config = getLdapConfig();
@@ -128,10 +133,10 @@ public class LdapUserDAOTest extends AbstractLdapDAOTest
                 new User<HttpPrincipal>(new HttpPrincipal("CADCtestRequest"));
         testPendingUser.details.add(new PersonalDetails("CADCtest", "Request"));
         testPendingUser.getIdentities().add(
-                new HttpPrincipal("CADCtestRequest"));
+            new HttpPrincipal("CADCtestRequest"));
         testPendingUser.getIdentities().add(
-                new X500Principal(
-                        "uid=CADCtestRequest,ou=userrequests,ou=ds,dc=testcanfar"));
+            new X500Principal(
+                "uid=CADCtestRequest,ou=userrequests,ou=ds,dc=testcanfar"));
         testPendingUser.getIdentities().add(new NumericPrincipal(66666));
 
         testUser.details.add(new PersonalDetails("CADC", "DAOTest1"));
@@ -147,7 +152,9 @@ public class LdapUserDAOTest extends AbstractLdapDAOTest
         testMember = new User<X500Principal>(testUserX500Princ);
         testMember.details.add(new PersonalDetails("CADC", "DAOTest1"));
         testMember.getIdentities().add(new HttpPrincipal("CadcDaoTest1"));
-        
+
+        testUser1DNPrincipal = new DNPrincipal(testUser1EntryDN);
+        testUser2DNPrincipal = new DNPrincipal(testUser2EntryDN);
     }
 
     <T extends Principal> LdapUserDAO<T> getUserDAO() throws Exception
@@ -227,6 +234,7 @@ public class LdapUserDAOTest extends AbstractLdapDAOTest
     {
         Subject subject = new Subject();
         subject.getPrincipals().add(testUser.getUserID());
+        subject.getPrincipals().add(testUser1DNPrincipal);
 
         // do everything as owner
         Subject.doAs(subject, new PrivilegedExceptionAction<Object>()
@@ -258,6 +266,7 @@ public class LdapUserDAOTest extends AbstractLdapDAOTest
     {
         Subject subject = new Subject();
         subject.getPrincipals().add(testUser.getUserID());
+        subject.getPrincipals().add(testUser1DNPrincipal);
 
         // do everything as owner
         Subject.doAs(subject, new PrivilegedExceptionAction<Object>()
@@ -267,7 +276,7 @@ public class LdapUserDAOTest extends AbstractLdapDAOTest
                 try
                 {
                     Collection<DN> groups = getUserDAO().getUserGroups(testUser.getUserID(),
-                                                       false);
+                        false);
                     assertNotNull("Groups should not be null.", groups);
 
                     for (DN groupDN : groups)
@@ -301,6 +310,7 @@ public class LdapUserDAOTest extends AbstractLdapDAOTest
     {
         Subject subject = new Subject();
         subject.getPrincipals().add(testUser.getUserID());
+        subject.getPrincipals().add(testUser1DNPrincipal);
 
         // do everything as owner
         Subject.doAs(subject, new PrivilegedExceptionAction<Object>()
@@ -314,7 +324,7 @@ public class LdapUserDAOTest extends AbstractLdapDAOTest
 
                     String  groupDN = "cn=cadcdaotestgroup1," + config.getGroupsDN();
                     isMember = getUserDAO().isMember(testUser.getUserID(),
-                                                     groupDN);
+                        groupDN);
                     assertTrue("Membership should exist.", isMember);
 
                     return null;
@@ -335,7 +345,7 @@ public class LdapUserDAOTest extends AbstractLdapDAOTest
     {
         Subject subject = new Subject();
         subject.getPrincipals().add(testUser.getUserID());
-
+        subject.getPrincipals().add(testUser1DNPrincipal);
         
         // do everything as owner
         Subject.doAs(subject, new PrivilegedExceptionAction<Object>()
@@ -579,6 +589,7 @@ public class LdapUserDAOTest extends AbstractLdapDAOTest
         // add the user
         Subject subject = new Subject();
         subject.getPrincipals().add(testUser2.getUserID());
+        subject.getPrincipals().add(testUser2DNPrincipal);
         Subject.doAs(subject, new PrivilegedExceptionAction<Object>()
         {
             public Object run()
@@ -633,6 +644,7 @@ public class LdapUserDAOTest extends AbstractLdapDAOTest
 
         // update the user
         subject.getPrincipals().add(testUser2.getUserID());
+        subject.getPrincipals().add(testUser2DNPrincipal);
         User<? extends Principal> updatedUser =
             (User<? extends Principal>) Subject.doAs(subject, new PrivilegedExceptionAction<Object>()
         {
@@ -662,7 +674,7 @@ public class LdapUserDAOTest extends AbstractLdapDAOTest
         assertEquals(user1, user2);
         assertEquals(user1.details, user2.details);
         assertEquals(user1.details.size(), user2.details.size());
-        assertEquals(user1.getIdentities().size(), user2.getIdentities().size());
+        assertEquals("# principals not equal", user1.getIdentities().size(), user2.getIdentities().size());
         for( Principal princ1 : user1.getIdentities())
         {
             boolean found = false;
diff --git a/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/users/GetUserActionTest.java b/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/users/GetUserActionTest.java
index 7727194981084f8d071205b6861e394b99762e28..8c77cf530780e5e285dd29a49a376cedbd12ea85 100644
--- a/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/users/GetUserActionTest.java
+++ b/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/users/GetUserActionTest.java
@@ -78,12 +78,14 @@ import ca.nrc.cadc.auth.HttpPrincipal;
 import ca.nrc.cadc.auth.NumericPrincipal;
 import org.junit.Test;
 
+import javax.security.auth.Subject;
 import javax.security.auth.x500.X500Principal;
 import javax.servlet.http.HttpServletResponse;
 import java.io.PrintWriter;
 import java.io.StringWriter;
 import java.io.Writer;
 import java.security.Principal;
+import java.security.PrivilegedExceptionAction;
 import java.util.HashSet;
 import java.util.Set;
 
@@ -135,13 +137,85 @@ public class GetUserActionTest
 
     @Test
     public void writeUserWithDetailIdentity() throws Exception
+    {
+        final HttpPrincipal httpPrincipal = new HttpPrincipal("CADCtest");
+        final NumericPrincipal numericPrincipal = new NumericPrincipal(789);
+        final X500Principal x500Principal = new X500Principal("cn=foo,o=bar");
+
+        Subject testUser = new Subject();
+        testUser.getPrincipals().add(httpPrincipal);
+        testUser.getPrincipals().add(numericPrincipal);
+        testUser.getPrincipals().add(x500Principal);
+
+        Subject.doAs(testUser, new PrivilegedExceptionAction<Object>()
+        {
+            public Object run() throws Exception
+            {
+
+                final HttpServletResponse mockResponse = createMock(HttpServletResponse.class);
+                final UserPersistence<HttpPrincipal> mockUserPersistence =
+                    createMock(UserPersistence.class);
+
+
+                final GetUserAction testSubject = new GetUserAction(httpPrincipal, "identity")
+                {
+                    @Override
+                    UserPersistence<HttpPrincipal> getUserPersistence()
+                    {
+                        return mockUserPersistence;
+                    }
+                };
+
+                final User<HttpPrincipal> expected = new User<HttpPrincipal>(httpPrincipal);
+                expected.getIdentities().add(httpPrincipal);
+                expected.getIdentities().add(numericPrincipal);
+                expected.getIdentities().add(x500Principal);
+
+                StringBuilder sb = new StringBuilder();
+                UserWriter userWriter = new UserWriter();
+                userWriter.write(expected, sb);
+                String expectedUser = sb.toString();
+
+                final PersonalDetails personalDetails = new PersonalDetails("cadc", "test");
+                personalDetails.city = "city";
+                expected.details.add(personalDetails);
+
+                final PosixDetails posixDetails = new PosixDetails(123L, 456L, "/dev/null");
+                expected.details.add(posixDetails);
+
+                final Writer writer = new StringWriter();
+                final PrintWriter printWriter = new PrintWriter(writer);
+
+                mockResponse.setHeader("Content-Type", "text/xml");
+                expectLastCall().once();
+                expect(mockResponse.getWriter()).andReturn(printWriter).once();
+
+                replay(mockUserPersistence, mockResponse);
+
+                SyncOutput syncOutput = new SyncOutput(mockResponse);
+                testSubject.setSyncOut(syncOutput);
+                testSubject.doAction();
+
+                String actualUser = writer.toString();
+
+                assertEquals(expectedUser, actualUser);
+
+                verify(mockUserPersistence, mockResponse);
+
+                return null;
+            }
+        });
+    }
+
+    @Test
+    public void writeUserWithDetailDisplay() throws Exception
     {
         final HttpServletResponse mockResponse = createMock(HttpServletResponse.class);
         final UserPersistence<HttpPrincipal> mockUserPersistence =
             createMock(UserPersistence.class);
         final HttpPrincipal userID = new HttpPrincipal("CADCtest");
 
-        final GetUserAction testSubject = new GetUserAction(userID, "identity")
+        final GetUserAction testSubject = new GetUserAction(userID, "display")
         {
             @Override
             UserPersistence<HttpPrincipal> getUserPersistence()
@@ -151,17 +225,21 @@ public class GetUserActionTest
         };
 
         final User<HttpPrincipal> expected = new User<HttpPrincipal>(userID);
-        expected.getIdentities().add(new NumericPrincipal(789));
-        expected.getIdentities().add(new X500Principal("cn=foo,o=bar"));
+
+        final PersonalDetails personalDetails = new PersonalDetails("cadc", "test");
+        expected.details.add(personalDetails);
 
         StringBuilder sb = new StringBuilder();
         UserWriter userWriter = new UserWriter();
         userWriter.write(expected, sb);
         String expectedUser = sb.toString();
 
-        final PersonalDetails personalDetails = new PersonalDetails("cadc", "test");
-        personalDetails.city = "city";
-        expected.details.add(personalDetails);
+        Set<PersonalDetails> details = expected.getDetails(PersonalDetails.class);
+        PersonalDetails pd = details.iterator().next();
+        pd.city = "city";
+
+        expected.getIdentities().add(new NumericPrincipal(789));
+        expected.getIdentities().add(new X500Principal("cn=foo,o=bar"));
 
         final PosixDetails posixDetails = new PosixDetails(123L, 456L, "/dev/null");
         expected.details.add(posixDetails);
@@ -188,46 +266,40 @@ public class GetUserActionTest
     }
 
     @Test
-    public void writeUserWithDetailDisplay() throws Exception
+    public void writeAugmentedUser() throws Exception
     {
-        final HttpServletResponse mockResponse = createMock(HttpServletResponse.class);
-        final UserPersistence<HttpPrincipal> mockUserPersistence =
+        final UserPersistence<Principal> mockUserPersistence =
             createMock(UserPersistence.class);
-        final HttpPrincipal userID = new HttpPrincipal("CADCtest");
+        final HttpServletResponse mockResponse = createMock(HttpServletResponse.class);
 
-        final GetUserAction testSubject = new GetUserAction(userID, "display")
+        final HttpPrincipal userID = new HttpPrincipal("CADCtest");
+        final GetUserAction testSubject = new GetUserAction(userID, null)
         {
             @Override
-            UserPersistence<HttpPrincipal> getUserPersistence()
+            UserPersistence<Principal> getUserPersistence()
             {
                 return mockUserPersistence;
             }
         };
+        testSubject.setAugmentUser(true);
 
-        final User<HttpPrincipal> expected = new User<HttpPrincipal>(userID);
+        final NumericPrincipal numericPrincipal = new NumericPrincipal(789);
+        final X500Principal x500Principal = new X500Principal("cn=foo,o=bar");
 
-        final PersonalDetails personalDetails = new PersonalDetails("cadc", "test");
-        expected.details.add(personalDetails);
+        final User<Principal> expected = new User<Principal>(userID);
+        expected.getIdentities().add(userID);
+        expected.getIdentities().add(numericPrincipal);
+        expected.getIdentities().add(x500Principal);
 
         StringBuilder sb = new StringBuilder();
         UserWriter userWriter = new UserWriter();
         userWriter.write(expected, sb);
         String expectedUser = sb.toString();
 
-        Set<PersonalDetails> details = expected.getDetails(PersonalDetails.class);
-        PersonalDetails pd = details.iterator().next();
-        pd.city = "city";
-
-        expected.getIdentities().add(new NumericPrincipal(789));
-        expected.getIdentities().add(new X500Principal("cn=foo,o=bar"));
-
-        final PosixDetails posixDetails = new PosixDetails(123L, 456L, "/dev/null");
-        expected.details.add(posixDetails);
-
         final Writer writer = new StringWriter();
         final PrintWriter printWriter = new PrintWriter(writer);
 
-        expect(mockUserPersistence.getUser(userID)).andReturn(expected).once();
+        expect(mockUserPersistence.getAugmentedUser(userID)).andReturn(expected).once();
         mockResponse.setHeader("Content-Type", "text/xml");
         expectLastCall().once();
         expect(mockResponse.getWriter()).andReturn(printWriter).once();
diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/AbstractReaderWriter.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/AbstractReaderWriter.java
index 732e406596b8cadc758526c86342742ebd4ccd1c..2e64ba5f286d43d54fc6d9f6d2573d121de8c981 100644
--- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/AbstractReaderWriter.java
+++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/AbstractReaderWriter.java
@@ -79,6 +79,7 @@ import ca.nrc.cadc.ac.User;
 import ca.nrc.cadc.ac.UserDetails;
 import ca.nrc.cadc.ac.UserRequest;
 import ca.nrc.cadc.ac.WriterException;
+import ca.nrc.cadc.auth.DNPrincipal;
 import ca.nrc.cadc.auth.HttpPrincipal;
 import ca.nrc.cadc.auth.IdentityType;
 import ca.nrc.cadc.auth.NumericPrincipal;
@@ -266,6 +267,10 @@ public abstract class AbstractReaderWriter
         {
             principal = new X500Principal(identity);
         }
+        else if (type.equals(IdentityType.ENTRY_DN.getValue()))
+        {
+            principal = new DNPrincipal(identity);
+        }
         else
         {
             String error = "Unknown type attribute: " + type;
@@ -729,6 +734,10 @@ public abstract class AbstractReaderWriter
         {
             identityElement.setAttribute("type", IdentityType.X500.getValue());
         }
+        else if ((identity instanceof DNPrincipal))
+        {
+            identityElement.setAttribute("type", IdentityType.ENTRY_DN.getValue());
+        }
         else
         {
             String error = "Unsupported Principal type " +
diff --git a/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/client/UserClientTest.java b/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/client/UserClientTest.java
index 6a84fb04bcb8e5c1789b0d3a160dd3df356937ec..8b7f3a617ef2c673b5d81ebd28de329bc7fc3506 100644
--- a/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/client/UserClientTest.java
+++ b/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/client/UserClientTest.java
@@ -69,9 +69,22 @@
 
 package ca.nrc.cadc.ac.client;
 
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.security.Principal;
+
+import javax.management.remote.JMXPrincipal;
+import javax.security.auth.Subject;
+
 import org.apache.log4j.Level;
 import org.apache.log4j.Logger;
-import ca.nrc.cadc.ac.client.UserClient;
+
+import ca.nrc.cadc.ac.AC;
+import ca.nrc.cadc.auth.HttpPrincipal;
+import ca.nrc.cadc.auth.NumericPrincipal;
+import ca.nrc.cadc.reg.client.RegistryClient;
 import ca.nrc.cadc.util.Log4jInit;
 
 import org.junit.Assert;
@@ -123,4 +136,75 @@ public class UserClientTest
         	Assert.fail("Unexpected exception: " + t.getMessage());
         }
     }
+    
+    @Test
+    public void testSubjectWithNoPrincipal()
+    {
+    	try
+    	{
+	        // test subject augmentation given a subject with no principal
+	    	Subject subject = new Subject();
+	    	this.createUserClient().augmentSubject(subject);
+	    	Assert.assertEquals("Should have no principal.", 0, subject.getPrincipals().size());
+    	}
+    	catch(Throwable t)
+    	{
+    		Assert.fail("Unexpected exception: " + t.getMessage());
+    	}
+    }
+    
+    @Test
+    public void testSubjectWithMultiplePrincipal() 
+    {
+        try
+        {
+            // test subject augmentation given a subject with more than one principal
+            Subject subject = new Subject();
+            subject.getPrincipals().add(new NumericPrincipal(4));
+            subject.getPrincipals().add(new HttpPrincipal("cadcauthtest1"));
+            this.createUserClient().augmentSubject(subject);
+            Assert.fail("Expecting an IllegalArgumentException.");
+        }
+        catch(IllegalArgumentException e)
+        {
+            String expected = "Subject has more than one principal.";
+            Assert.assertEquals(expected, e.getMessage());
+        }
+    	catch(Throwable t)
+    	{
+    		Assert.fail("Unexpected exception: " + t.getMessage());
+    	}
+    }
+    
+    @Test
+    public void testSubjectWithUnsupportedPrincipal() 
+    {
+    	Principal principal = new JMXPrincipal("APIName");
+        try
+        {
+            // test subject augmentation given a subject with more than one principal
+            Subject subject = new Subject();
+            subject.getPrincipals().add(principal);
+            this.createUserClient().augmentSubject(subject);
+            Assert.fail("Expecting an IllegalArgumentException.");
+        }
+        catch(IllegalArgumentException e)
+        {
+            String expected = "Subject has unsupported principal " + principal.getName();
+            Assert.assertEquals(expected, e.getMessage());
+        }
+    	catch(Throwable t)
+    	{
+    		Assert.fail("Unexpected exception: " + t.getMessage());
+    	}
+    }
+   
+    protected UserClient createUserClient() throws URISyntaxException, MalformedURLException
+    {
+    	RegistryClient regClient = new RegistryClient();
+    	URI serviceURI = new URI(AC.GMS_SERVICE_URI);
+    	URL baseURL = regClient.getServiceURL(serviceURI, "https");
+    	return new UserClient(baseURL.toString());
+
+    }
 }