Add TokenType attribute to specify whether the token is a primary or
impersonation token.

diff --git a/server/token.c b/server/token.c
index 9483d32..cba6782 100644
--- a/server/token.c
+++ b/server/token.c
@@ -73,6 +73,7 @@
     struct list    privileges;      /* privileges available to the token */
     struct list    groups;          /* groups that the user of this token belongs to (sid_and_attributes) */
     SID           *user;            /* SID of user this token represents */
+    unsigned       primary;         /* is this a primary or impersonation token? */
 };
 
 struct privilege
@@ -353,7 +354,7 @@
     }
 }
 
-static struct token *create_token( const SID *user,
+static struct token *create_token( unsigned primary, const SID *user,
                                    const SID_AND_ATTRIBUTES *groups, unsigned int group_count,
                                    const LUID_AND_ATTRIBUTES *privs, unsigned int priv_count )
 {
@@ -361,8 +362,11 @@
     if (token)
     {
         int i;
+
         list_init( &token->privileges );
         list_init( &token->groups );
+        token->primary = primary;
+
         /* copy user */
         token->user = memdup( user, FIELD_OFFSET(SID, SubAuthority[user->SubAuthorityCount]) );
         if (!token->user)
@@ -462,7 +466,7 @@
         };
         /* note: we just set the user sid to be the local system builtin sid -
          * telling us what this should be is the job of a client-side program */
-        token = create_token( &local_system_sid,
+        token = create_token( TRUE, &local_system_sid,
                             admin_groups, sizeof(admin_groups)/sizeof(admin_groups[0]),
                             admin_privs, sizeof(admin_privs)/sizeof(admin_privs[0]) );
     }
@@ -879,15 +883,24 @@
                                                      TOKEN_DUPLICATE,
                                                      &token_ops )))
     {
-        /* FIXME: use req->primary and req->impersonation_level */
-        struct token *token = create_token( src_token->user, NULL, 0, NULL, 0 );
+        /* FIXME: use req->impersonation_level */
+        struct token *token = create_token( req->primary, src_token->user, NULL, 0, NULL, 0 );
         if (token)
         {
             struct privilege *privilege;
+            struct sid_and_attributes *group;
             unsigned int access;
 
-            /* FIXME: copy groups */
+            /* copy groups */
+            LIST_FOR_EACH_ENTRY( group, &src_token->groups, struct sid_and_attributes, entry )
+            {
+                size_t size = FIELD_OFFSET( struct sid_and_attributes, sid.SubAuthority[group->sid.SubAuthorityCount] );
+                struct sid_and_attributes *newgroup = mem_alloc( size );
+                memcpy( newgroup, group, size );
+                list_add_tail( &token->groups, &newgroup->entry );
+            }
 
+            /* copy privileges */
             LIST_FOR_EACH_ENTRY( privilege, &src_token->privileges, struct privilege, entry )
                 privilege_add( token, &privilege->luid, privilege->enabled );