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 5e0b281b83bf3451473c1aae836f2abb3857497d..e559a5ec80d70346315997d7e9544b8a86a80cb2 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
@@ -68,6 +68,20 @@
  */
 package ca.nrc.cadc.ac.server.ldap;
 
+import java.security.AccessControlException;
+import java.security.Principal;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+
+import javax.security.auth.x500.X500Principal;
+
+import org.apache.log4j.Logger;
+
 import ca.nrc.cadc.ac.PersonalDetails;
 import ca.nrc.cadc.ac.PosixDetails;
 import ca.nrc.cadc.ac.User;
@@ -77,7 +91,9 @@ import ca.nrc.cadc.ac.UserNotFoundException;
 import ca.nrc.cadc.ac.UserRequest;
 import ca.nrc.cadc.auth.AuthenticationUtil;
 import ca.nrc.cadc.auth.HttpPrincipal;
+import ca.nrc.cadc.auth.NumericPrincipal;
 import ca.nrc.cadc.net.TransientException;
+
 import com.unboundid.ldap.sdk.AddRequest;
 import com.unboundid.ldap.sdk.Attribute;
 import com.unboundid.ldap.sdk.BindRequest;
@@ -100,17 +116,6 @@ import com.unboundid.ldap.sdk.SimpleBindRequest;
 import com.unboundid.ldap.sdk.controls.ProxiedAuthorizationV2RequestControl;
 import com.unboundid.ldap.sdk.extensions.PasswordModifyExtendedRequest;
 import com.unboundid.ldap.sdk.extensions.PasswordModifyExtendedResult;
-import org.apache.log4j.Logger;
-
-import javax.security.auth.x500.X500Principal;
-import java.security.AccessControlException;
-import java.security.Principal;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
 
 
 public class LdapUserDAO<T extends Principal> extends LdapDAO
@@ -129,6 +134,7 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO
     protected static final String LDAP_ENTRYDN = "entrydn";
     protected static final String LDAP_COMMON_NAME = "cn";
     protected static final String LDAP_DISTINGUISHED_NAME = "distinguishedName";
+    protected static final String LDAP_NUMERICID = "numericid";
     protected static final String LADP_USER_PASSWORD = "userPassword";
     protected static final String LDAP_FIRST_NAME = "givenName";
     protected static final String LDAP_LAST_NAME = "sn";
@@ -138,6 +144,7 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO
     protected static final String LDAP_EMAIL = "email";
     protected static final String LDAP_INSTITUTE = "institute";
     protected static final String LDAP_UID = "uid";
+    
 
     private String[] userAttribs = new String[]
             {
@@ -155,6 +162,7 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO
         super(config);
         this.userLdapAttrib.put(HttpPrincipal.class, LDAP_UID);
         this.userLdapAttrib.put(X500Principal.class, LDAP_DISTINGUISHED_NAME);
+        this.userLdapAttrib.put(NumericPrincipal.class, LDAP_NUMERICID);
 
         // add the id attributes to user and member attributes
         String[] princs = userLdapAttrib.values()
@@ -350,16 +358,25 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO
         try
         {
             // add new user
+
+            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_CADC_ACCOUNT);
             addAttribute(attributes, LDAP_COMMON_NAME, user.getUserID()
                 .getName());
-            addAttribute(attributes, LDAP_DISTINGUISHED_NAME, userDN
-                .toNormalizedString());
             addAttribute(attributes, LADP_USER_PASSWORD, userRequest
-                .getPassword());
-
+                    .getPassword());
+            addAttribute(attributes, LDAP_NUMERICID, 
+                    String.valueOf(genNextNumericId()));
+            for (Principal princ : user.getIdentities())
+            {
+                if (princ instanceof X500Principal)
+                {
+                    addAttribute(attributes, LDAP_DISTINGUISHED_NAME, 
+                            princ.getName());
+                }
+            }
             for (UserDetails details : user.details)
             {
                 if (details.getClass() == PersonalDetails.class)
@@ -462,9 +479,15 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO
             throw new UserNotFoundException(msg);
         }
         User<T> user = new User<T>(userID);
-        user.getIdentities().add(new HttpPrincipal(searchResult.getAttributeValue(
-            userLdapAttrib.get(HttpPrincipal.class))));
-
+        user.getIdentities().add(new HttpPrincipal(
+                searchResult.getAttributeValue(
+                       userLdapAttrib.get(HttpPrincipal.class))));
+        user.getIdentities().add(new NumericPrincipal(
+                searchResult.getAttributeValueAsLong(
+                        userLdapAttrib.get(NumericPrincipal.class))));
+        user.getIdentities().add(new X500Principal(
+                searchResult.getAttributeValue(
+                        userLdapAttrib.get(X500Principal.class))));
         String fname = searchResult.getAttributeValue(LDAP_FIRST_NAME);
         String lname = searchResult.getAttributeValue(LDAP_LAST_NAME);
         PersonalDetails personaDetails = new PersonalDetails(fname, lname);
@@ -772,10 +795,9 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO
                         "Unsupported principal type " + userID.getClass());
             }
 
-            User<T> user = getUser(userID);
             Filter filter = Filter.createANDFilter(
                     Filter.createEqualityFilter(searchField,
-                                                user.getUserID().getName()),
+                                                userID.getName()),
                     Filter.createEqualityFilter(LDAP_MEMBEROF, groupID));
 
             SearchRequest searchRequest =
@@ -972,4 +994,18 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO
             LdapDAO.checkLdapResult(code);
         }
     }
+    
+    /**
+     * Method to return a randomly generated user numeric ID. The default 
+     * implementation returns a value between 10000 and Integer.MAX_VALUE.
+     * @return
+     */
+    protected int genNextNumericId()
+    {
+        Random rand = new Random();
+
+        // nextInt is normally exclusive of the top value,
+        // so add 1 to make it inclusive
+        return rand.nextInt(Integer.MAX_VALUE - 10000) + 10000;
+    }
 }
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 0e592c8012b889cd4b425b5bae0b3089a647f1f4..78a63a13285e89e87d18806b24dfcbae0c4953f8 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
@@ -68,39 +68,47 @@
  */
 package ca.nrc.cadc.ac.server.ldap;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.security.Principal;
+import java.security.PrivilegedExceptionAction;
+import java.util.Collection;
+import java.util.Random;
+
+import javax.security.auth.Subject;
+import javax.security.auth.x500.X500Principal;
+
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
 import ca.nrc.cadc.ac.PersonalDetails;
 import ca.nrc.cadc.ac.User;
 import ca.nrc.cadc.ac.UserDetails;
 import ca.nrc.cadc.ac.UserRequest;
 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 org.apache.log4j.Level;
-import org.apache.log4j.Logger;
-import org.junit.BeforeClass;
-import org.junit.Test;
 
-import javax.security.auth.Subject;
-import javax.security.auth.x500.X500Principal;
-import java.security.Principal;
-import java.security.PrivilegedExceptionAction;
-import java.util.Collection;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import com.unboundid.ldap.sdk.DN;
 
 public class LdapUserDAOTest<T extends Principal> extends AbstractLdapDAOTest
 {
     private static final Logger log = Logger.getLogger(LdapUserDAOTest.class);
 
     static final String testUserX509DN = "cn=cadcdaotest1,ou=cadc,o=hia,c=ca";
+    static int nextUserNumericID = 666;
 
     static String testUserDN;
     static User<X500Principal> testUser;
+    static User<X500Principal> testMember;
     static LdapConfig config;
+    static Random ran = new Random(); // source of randomness for numeric ids
 
     @BeforeClass
     public static void setUpBeforeClass()
@@ -110,17 +118,32 @@ public class LdapUserDAOTest<T extends Principal> extends AbstractLdapDAOTest
 
         // get the configuration of the development server from and config files...
         config = getLdapConfig();
-
-        testUser = new User<X500Principal>(new X500Principal(testUserX509DN));
+        X500Principal testUserX500Princ = new X500Principal(testUserX509DN);
+        testUser = new User<X500Principal>(testUserX500Princ);
         testUser.details.add(new PersonalDetails("CADC", "DAOTest1"));
         testUser.getIdentities().add(new HttpPrincipal("CadcDaoTest1"));
+        testUser.getIdentities().add(testUserX500Princ);
+        testUser.getIdentities().add(new NumericPrincipal(666));
 
         testUserDN = "uid=cadcdaotest1," + config.getUsersDN();
+        
+        
+        // member returned by getMember contains only the fields required by
+        // the GMS
+        testMember = new User<X500Principal>(testUserX500Princ);
+        testMember.details.add(new PersonalDetails("CADC", "DAOTest1"));
+        testMember.getIdentities().add(new HttpPrincipal("CadcDaoTest1"));
+        
     }
 
     LdapUserDAO getUserDAO()
     {
-        return new LdapUserDAO(config);
+        return new LdapUserDAO(config){
+            protected int genNextNumericId()
+            {
+                return nextUserNumericID;
+            }
+        };
     }
 
     String getUserID()
@@ -134,8 +157,13 @@ public class LdapUserDAOTest<T extends Principal> extends AbstractLdapDAOTest
     @Test
     public void testAddUser() throws Exception
     {
-        final User<HttpPrincipal> expected = new User<HttpPrincipal>(new HttpPrincipal(getUserID()));
-        expected.getIdentities().add(new HttpPrincipal(getUserID()));
+        String userID = getUserID();
+        final User<HttpPrincipal> expected = new User<HttpPrincipal>(new HttpPrincipal(userID));
+        expected.getIdentities().add(new HttpPrincipal(userID));
+        expected.getIdentities().add(new X500Principal("cn=" + userID + ",ou=cadc,o=hia,c=ca"));
+        nextUserNumericID = ran.nextInt(Integer.MAX_VALUE);
+        expected.getIdentities().add(new NumericPrincipal(nextUserNumericID));
+        
         expected.details.add(new PersonalDetails("foo", "bar"));
 
         final UserRequest<HttpPrincipal> userRequest =
@@ -265,6 +293,7 @@ public class LdapUserDAOTest<T extends Principal> extends AbstractLdapDAOTest
         Subject subject = new Subject();
         subject.getPrincipals().add(testUser.getUserID());
 
+        
         // do everything as owner
         Subject.doAs(subject, new PrivilegedExceptionAction<Object>()
         {
@@ -273,7 +302,7 @@ public class LdapUserDAOTest<T extends Principal> extends AbstractLdapDAOTest
                 try
                 {
                     User<X500Principal> actual = getUserDAO().getMember(new DN(testUserDN));
-                    check(testUser, actual);
+                    check(testMember, actual);
                     return null;
                 }
                 catch (Exception e)
@@ -296,7 +325,7 @@ public class LdapUserDAOTest<T extends Principal> extends AbstractLdapDAOTest
                 try
                 {
                     User<X500Principal> actual = getUserDAO().getMember(new DN(testUserDN));
-                    check(testUser, actual);
+                    check(testMember, actual);
                     return null;
                 }
                 catch (Exception e)
@@ -490,6 +519,10 @@ public class LdapUserDAOTest<T extends Principal> extends AbstractLdapDAOTest
         HttpPrincipal principal = new HttpPrincipal(username);
         testUser2 = new User<HttpPrincipal>(principal);
         testUser2.getIdentities().add(principal);
+        testUser2.getIdentities().add(new X500Principal("cn=" + username + ",ou=cadc,o=hia,c=ca"));
+        // update nextNumericId
+        nextUserNumericID = ran.nextInt(Integer.MAX_VALUE);
+        testUser2.getIdentities().add(new NumericPrincipal(nextUserNumericID));
         testUser2.details.add(new PersonalDetails("firstName", "lastName"));
         final UserRequest userRequest = new UserRequest(testUser2, password);
 
@@ -575,8 +608,21 @@ public class LdapUserDAOTest<T extends Principal> extends AbstractLdapDAOTest
         assertEquals(user1, user2);
         assertEquals(user1.details, user2.details);
         assertEquals(user1.details.size(), user2.details.size());
-        assertEquals(user1.getIdentities(), user2.getIdentities());
-        for (UserDetails d1 : user1.details)
+        assertEquals(user1.getIdentities().size(), user2.getIdentities().size());
+        for( Principal princ1 : user1.getIdentities())
+        {
+            boolean found = false;
+            for( Principal princ2 : user2.getIdentities())
+            {
+                if (princ2.getClass() == princ1.getClass())
+                {
+                    assertEquals(princ1, princ2);
+                    found = true;
+                }
+            }
+            assertTrue(princ1.getName(), found);
+        }
+        for(UserDetails d1 : user1.details)
         {
             assertTrue(user2.details.contains(d1));
             if (d1 instanceof PersonalDetails)