diff --git a/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapUserDAO.java b/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapUserDAO.java
index 21fa459b2b57228d047c066b262c64918dcf4158..53b6fbc2ae397fbbe0e2fe54afe3bca63c596248 100755
--- a/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapUserDAO.java
+++ b/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapUserDAO.java
@@ -1109,30 +1109,53 @@ public class LdapUserDAO extends LdapDAO
         }
     }
 
+    private Principal getPreferredPrincipal(User user)
+    {
+        Principal ret = null;
+        Principal next = null;
+        Iterator<Principal> i = user.getIdentities().iterator();
+        while (i.hasNext())
+        {
+            next = i.next();
+            if (next instanceof NumericPrincipal)
+            {
+                return next;
+            }
+            ret = next;
+        }
+        return ret;
+    }
+
     DN getUserDN(User user)
-        throws UserNotFoundException, TransientException
+        throws UserNotFoundException, TransientException, LDAPException
     {
-        // Could be a DNPrincipal from a memberOf or uniquemember entrydn
-        Principal userID = user.getHttpPrincipal();
-        String searchField = userLdapAttrib.get(userID.getClass());
+        Principal p = getPreferredPrincipal(user);
+        if (p == null)
+        {
+            throw new UserNotFoundException("No identities");
+        }
+
+        // DN can be formulated if it is the numeric id
+        if (p instanceof NumericPrincipal)
+            return this.getUserDN(p.getName(), config.getUsersDN());
+
+        // Otherwise we need to search for the numeric id
+        String searchField = userLdapAttrib.get(p.getClass());
         if (searchField == null)
         {
             throw new IllegalArgumentException(
-                    "Unsupported principal type " + userID.getClass());
+                    "Unsupported principal type " + p.getClass());
         }
 
-        // change the DN to be in the 'java' format
-        Filter filter;
-//        if (userID instanceof X500Principal)
-//        {
-//            X500Principal orderedPrincipal = AuthenticationUtil.getOrderedForm(
-//                (X500Principal) userID);
-//            filter = Filter.createEqualityFilter(searchField, orderedPrincipal.toString());
-//        }
-//        else
-//        {
-            filter = Filter.createEqualityFilter(searchField, userID.getName());
-//        }
+//      change the DN to be in the 'java' format
+//      if (userID instanceof X500Principal)
+//      {
+//          X500Principal orderedPrincipal = AuthenticationUtil.getOrderedForm(
+//              (X500Principal) userID);
+//          filter = Filter.createEqualityFilter(searchField, orderedPrincipal.toString());
+//      }
+
+        Filter filter = Filter.createEqualityFilter(searchField, p.getName());
         logger.debug("search filter: " + filter);
 
         SearchResultEntry searchResult = null;
@@ -1141,7 +1164,7 @@ public class LdapUserDAO extends LdapDAO
             SearchRequest searchRequest = new SearchRequest(
                 config.getUsersDN(), SearchScope.ONE, filter, LDAP_ENTRYDN);
             searchResult = getReadOnlyConnection().searchForEntry(searchRequest);
-            logger.info("getUserDN: got " + userID.getName() + " from " + config.getUsersDN());
+            logger.debug("getUserDN: got " + p.getName() + " from " + config.getUsersDN());
         }
         catch (LDAPException e)
         {
@@ -1150,26 +1173,17 @@ public class LdapUserDAO extends LdapDAO
 
         if (searchResult == null)
         {
-            String msg = "User not found " + userID.getName() + " in " + config.getUsersDN();
+            String msg = "User not found " + p.getName() + " in " + config.getUsersDN();
             logger.debug(msg);
             throw new UserNotFoundException(msg);
         }
         return searchResult.getAttributeValueAsDN(LDAP_ENTRYDN);
     }
 
-    protected DN getUserDN(final String userID, final String usersDN)
+    protected DN getUserDN(String numericID, String usersDN)
             throws LDAPException, TransientException
     {
-        try
-        {
-            return new DN(LDAP_UID + "=" + userID + "," + usersDN);
-        }
-        catch (LDAPException e)
-        {
-            logger.debug("getUserDN Exception: " + e, e);
-            LdapDAO.checkLdapResult(e.getResultCode());
-        }
-        throw new IllegalArgumentException(userID + " not a valid user ID");
+        return new DN(LDAP_UID + "=" + numericID + "," + usersDN);
     }
 
     private void addAttribute(List<Attribute> attributes, final String name, final String value)
diff --git a/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/AbstractGroupAction.java b/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/AbstractGroupAction.java
index d384f4a4212c084fec436d7c87cd239b2aa70d3e..e7466c9cf395698026fe0b049342e15367c9fca8 100755
--- a/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/AbstractGroupAction.java
+++ b/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/AbstractGroupAction.java
@@ -69,12 +69,14 @@
 package ca.nrc.cadc.ac.server.web.groups;
 
 import java.io.IOException;
-import java.lang.reflect.Field;
 import java.security.AccessControlException;
+import java.security.Principal;
 import java.security.PrivilegedActionException;
 import java.security.PrivilegedExceptionAction;
+import java.util.Iterator;
 import java.util.List;
 
+import javax.security.auth.x500.X500Principal;
 import javax.servlet.http.HttpServletRequest;
 
 import org.apache.log4j.Logger;
@@ -83,9 +85,11 @@ import ca.nrc.cadc.ac.GroupAlreadyExistsException;
 import ca.nrc.cadc.ac.GroupNotFoundException;
 import ca.nrc.cadc.ac.MemberAlreadyExistsException;
 import ca.nrc.cadc.ac.MemberNotFoundException;
+import ca.nrc.cadc.ac.User;
 import ca.nrc.cadc.ac.UserNotFoundException;
 import ca.nrc.cadc.ac.server.GroupPersistence;
 import ca.nrc.cadc.ac.server.web.SyncOutput;
+import ca.nrc.cadc.auth.HttpPrincipal;
 import ca.nrc.cadc.net.TransientException;
 
 public abstract class AbstractGroupAction implements PrivilegedExceptionAction<Object>
@@ -233,27 +237,26 @@ public abstract class AbstractGroupAction implements PrivilegedExceptionAction<O
         this.logInfo.deletedMembers = deletedMembers;
     }
 
-    // set private field using reflection
-    protected void setField(Object object, Object value, String name)
+    protected String getUseridForLogging(User u)
     {
-        try
-        {
-            Field field = object.getClass().getDeclaredField(name);
-            field.setAccessible(true);
-            field.set(object, value);
-        }
-        catch (NoSuchFieldException e)
-        {
-            final String error = object.getClass().getSimpleName() +
-                " field " + name + "not found";
-            throw new RuntimeException(error, e);
-        }
-        catch (IllegalAccessException e)
+        if (u.getIdentities().isEmpty())
+            return "anonUser";
+
+        Iterator<Principal> i = u.getIdentities().iterator();
+        String ret = null;
+        Principal next = null;
+        while (i.hasNext())
         {
-            final String error = "unable to update " + name + " in " +
-                object.getClass().getSimpleName();
-            throw new RuntimeException(error, e);
+            next = i.next();
+            if (next instanceof HttpPrincipal)
+                return next.getName();
+            if (next instanceof X500Principal)
+                ret = next.getName();
+            else if (ret == null)
+                ret = next.getName();
         }
+        return ret;
     }
 
+
 }
diff --git a/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/AddUserMemberAction.java b/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/AddUserMemberAction.java
index 8f8cfe81763511a503e12a95053682e19192157c..5f43eadbbe00d29203b7ac5c5b47de3c432651b0 100755
--- a/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/AddUserMemberAction.java
+++ b/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/AddUserMemberAction.java
@@ -107,7 +107,7 @@ public class AddUserMemberAction extends AbstractGroupAction
         groupPersistence.modifyGroup(group);
 
         List<String> addedMembers = new ArrayList<String>();
-        addedMembers.add(toAdd.getHttpPrincipal().getName());
+        addedMembers.add(getUseridForLogging(toAdd));
         logGroupInfo(group.getID(), null, addedMembers);
     }
 
diff --git a/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/ModifyGroupAction.java b/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/ModifyGroupAction.java
index f02fe03b74b747ecd2748c7c48baba60d6a4711f..e676063153a80ec1474821930bf43ec44c88d24f 100755
--- a/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/ModifyGroupAction.java
+++ b/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/ModifyGroupAction.java
@@ -102,7 +102,7 @@ public class ModifyGroupAction extends AbstractGroupAction
         {
             if (!oldGroup.getUserMembers().remove(member))
             {
-                addedMembers.add(member.getHttpPrincipal().getName());
+                addedMembers.add(getUseridForLogging(member));
             }
         }
         for (Group gr : group.getGroupMembers())
@@ -119,7 +119,7 @@ public class ModifyGroupAction extends AbstractGroupAction
         List<String> deletedMembers = new ArrayList<String>();
         for (User member : oldGroup.getUserMembers())
         {
-            deletedMembers.add(member.getHttpPrincipal().getName());
+            deletedMembers.add(getUseridForLogging(member));
         }
         for (Group gr : oldGroup.getGroupMembers())
         {
diff --git a/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/RemoveUserMemberAction.java b/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/RemoveUserMemberAction.java
index 87c1148e281723cce6aca948ddb93383e1f2be77..1bda22da92a2d9b4dbb52c744c9e3678b6ecf2c6 100755
--- a/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/RemoveUserMemberAction.java
+++ b/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/RemoveUserMemberAction.java
@@ -71,9 +71,6 @@ package ca.nrc.cadc.ac.server.web.groups;
 import java.security.Principal;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Set;
-
-import javax.security.auth.x500.X500Principal;
 
 import ca.nrc.cadc.ac.Group;
 import ca.nrc.cadc.ac.MemberNotFoundException;
@@ -110,7 +107,7 @@ public class RemoveUserMemberAction extends AbstractGroupAction
         groupPersistence.modifyGroup(group);
 
         List<String> deletedMembers = new ArrayList<String>();
-        deletedMembers.add(toRemove.getHttpPrincipal().getName());
+        deletedMembers.add(getUseridForLogging(toRemove));
         logGroupInfo(group.getID(), deletedMembers, null);
     }
 
diff --git a/cadcAccessControl/src/ca/nrc/cadc/ac/client/GMSClient.java b/cadcAccessControl/src/ca/nrc/cadc/ac/client/GMSClient.java
index 0d0b4a9bf6b71c12f216910ab355351400e4420e..43dd4e50b5dec364ba4479a60dd8f15698829a69 100755
--- a/cadcAccessControl/src/ca/nrc/cadc/ac/client/GMSClient.java
+++ b/cadcAccessControl/src/ca/nrc/cadc/ac/client/GMSClient.java
@@ -68,6 +68,30 @@
  */
 package ca.nrc.cadc.ac.client;
 
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URL;
+import java.security.AccessControlContext;
+import java.security.AccessControlException;
+import java.security.AccessController;
+import java.security.Principal;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLSocketFactory;
+import javax.security.auth.Subject;
+
+import org.apache.log4j.Logger;
+
 import ca.nrc.cadc.ac.Group;
 import ca.nrc.cadc.ac.GroupAlreadyExistsException;
 import ca.nrc.cadc.ac.GroupNotFoundException;
@@ -90,28 +114,6 @@ import ca.nrc.cadc.net.NetUtil;
 import ca.nrc.cadc.net.event.TransferEvent;
 import ca.nrc.cadc.net.event.TransferListener;
 import ca.nrc.cadc.reg.client.RegistryClient;
-import org.apache.log4j.Logger;
-
-import javax.net.ssl.HttpsURLConnection;
-import javax.net.ssl.SSLSocketFactory;
-import javax.security.auth.Subject;
-import java.io.BufferedReader;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.net.HttpURLConnection;
-import java.net.MalformedURLException;
-import java.net.URI;
-import java.net.URL;
-import java.security.AccessControlContext;
-import java.security.AccessControlException;
-import java.security.AccessController;
-import java.security.Principal;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
 
 
 /**
@@ -129,7 +131,7 @@ public class GMSClient implements TransferListener
     // client needs to know which service it is bound to and lookup
     // endpoints using RegistryClient
     private URI serviceURI;
-    
+
     // storing baseURL is now considered bad form but fix is out of scope right now
     private String baseURL;
 
@@ -679,6 +681,12 @@ public class GMSClient implements TransferListener
     public void addUserMember(String targetGroupName, Principal userID)
         throws GroupNotFoundException, UserNotFoundException, AccessControlException, IOException
     {
+        if (targetGroupName == null)
+            throw new IllegalArgumentException("targetGroupName required");
+
+        if (userID == null)
+            throw new IllegalArgumentException("userID required");
+
         log.debug("addUserMember: " + targetGroupName + " + " + userID.getName());
 
         String userIDType = AuthenticationUtil.getPrincipalType(userID);
@@ -889,7 +897,7 @@ public class GMSClient implements TransferListener
         return getMemberships(null, role);
     }
 
-    
+
     private List<Group> getMemberships(Principal ignore, Role role)
         throws UserNotFoundException, AccessControlException, IOException
     {
@@ -1098,15 +1106,15 @@ public class GMSClient implements TransferListener
     {
         return isMember(groupName, Role.MEMBER);
     }
-    
+
     /**
-     * 
+     *
      * @param groupName
      * @param role
      * @return
      * @throws UserNotFoundException
      * @throws AccessControlException
-     * @throws IOException 
+     * @throws IOException
      */
     public boolean isMember(String groupName, Role role)
         throws UserNotFoundException, AccessControlException, IOException