server: Extend get_token_user server call to also retrieve SIDs for the token's owner or primary group.
diff --git a/server/protocol.def b/server/protocol.def
index ca44e38..bba6788 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -2924,18 +2924,19 @@
     VARARG(privileges,LUID_AND_ATTRIBUTES); /* privileges used during access check */
 @END
 
-@REQ(get_token_user)
+@REQ(get_token_sid)
     obj_handle_t    handle;       /* handle to the token */
+    unsigned int    which_sid;    /* which SID to retrieve from the token */
 @REPLY
-    data_size_t     user_len;     /* length needed to store user */
-    VARARG(user,SID);             /* sid of the user the token represents */
+    data_size_t     sid_len;      /* length needed to store sid */
+    VARARG(sid,SID);              /* the sid specified by which_sid from the token */
 @END
 
 @REQ(get_token_groups)
     obj_handle_t    handle;       /* handle to the token */
 @REPLY
     data_size_t     user_len;     /* length needed to store user */
-    VARARG(user,token_groups); /* groups the token's user belongs to */
+    VARARG(user,token_groups);    /* groups the token's user belongs to */
 @END
 
 @REQ(get_token_default_dacl)
diff --git a/server/request.h b/server/request.h
index 8aa8a9d..ca5fc88 100644
--- a/server/request.h
+++ b/server/request.h
@@ -317,7 +317,7 @@
 DECL_HANDLER(check_token_privileges);
 DECL_HANDLER(duplicate_token);
 DECL_HANDLER(access_check);
-DECL_HANDLER(get_token_user);
+DECL_HANDLER(get_token_sid);
 DECL_HANDLER(get_token_groups);
 DECL_HANDLER(get_token_default_dacl);
 DECL_HANDLER(set_token_default_dacl);
@@ -564,7 +564,7 @@
     (req_handler)req_check_token_privileges,
     (req_handler)req_duplicate_token,
     (req_handler)req_access_check,
-    (req_handler)req_get_token_user,
+    (req_handler)req_get_token_sid,
     (req_handler)req_get_token_groups,
     (req_handler)req_get_token_default_dacl,
     (req_handler)req_set_token_default_dacl,
@@ -1755,9 +1755,10 @@
 C_ASSERT( FIELD_OFFSET(struct access_check_reply, access_status) == 12 );
 C_ASSERT( FIELD_OFFSET(struct access_check_reply, privileges_len) == 16 );
 C_ASSERT( sizeof(struct access_check_reply) == 24 );
-C_ASSERT( FIELD_OFFSET(struct get_token_user_request, handle) == 12 );
-C_ASSERT( FIELD_OFFSET(struct get_token_user_reply, user_len) == 8 );
-C_ASSERT( sizeof(struct get_token_user_reply) == 16 );
+C_ASSERT( FIELD_OFFSET(struct get_token_sid_request, handle) == 12 );
+C_ASSERT( FIELD_OFFSET(struct get_token_sid_request, which_sid) == 16 );
+C_ASSERT( FIELD_OFFSET(struct get_token_sid_reply, sid_len) == 8 );
+C_ASSERT( sizeof(struct get_token_sid_reply) == 16 );
 C_ASSERT( FIELD_OFFSET(struct get_token_groups_request, handle) == 12 );
 C_ASSERT( FIELD_OFFSET(struct get_token_groups_reply, user_len) == 8 );
 C_ASSERT( sizeof(struct get_token_groups_reply) == 16 );
diff --git a/server/token.c b/server/token.c
index ce896ac..4c45d50 100644
--- a/server/token.c
+++ b/server/token.c
@@ -1225,27 +1225,51 @@
 }
 
 /* retrieves the SID of the user that the token represents */
-DECL_HANDLER(get_token_user)
+DECL_HANDLER(get_token_sid)
 {
     struct token *token;
 
-    reply->user_len = 0;
+    reply->sid_len = 0;
 
     if ((token = (struct token *)get_handle_obj( current->process, req->handle,
                                                  TOKEN_QUERY,
                                                  &token_ops )))
     {
-        const SID *user = token->user;
+        const SID *sid = NULL;
 
-        reply->user_len = FIELD_OFFSET(SID, SubAuthority[user->SubAuthorityCount]);
-        if (reply->user_len <= get_reply_max_size())
+        switch (req->which_sid)
         {
-            SID *user_reply = set_reply_data_size( reply->user_len );
-            if (user_reply)
-                memcpy( user_reply, user, reply->user_len );
+        case TokenUser:
+            assert(token->user);
+            sid = token->user;
+            break;
+        case TokenPrimaryGroup:
+            sid = token->primary_group;
+            break;
+        case TokenOwner:
+        {
+            struct group *group;
+            LIST_FOR_EACH_ENTRY( group, &token->groups, struct group, entry )
+            {
+                if (group->owner)
+                {
+                    sid = &group->sid;
+                    break;
+                }
+            }
+            break;
         }
-        else set_error( STATUS_BUFFER_TOO_SMALL );
+        default:
+            set_error( STATUS_INVALID_PARAMETER );
+            break;
+        }
 
+        if (sid)
+        {
+            reply->sid_len = FIELD_OFFSET(SID, SubAuthority[sid->SubAuthorityCount]);
+            if (reply->sid_len <= get_reply_max_size()) set_reply_data( sid, reply->sid_len );
+            else set_error( STATUS_BUFFER_TOO_SMALL );
+        }
         release_object( token );
     }
 }
diff --git a/server/trace.c b/server/trace.c
index a529e5b..a4b1faa 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -3426,15 +3426,16 @@
     dump_varargs_LUID_AND_ATTRIBUTES( ", privileges=", cur_size );
 }
 
-static void dump_get_token_user_request( const struct get_token_user_request *req )
+static void dump_get_token_sid_request( const struct get_token_sid_request *req )
 {
     fprintf( stderr, " handle=%04x", req->handle );
+    fprintf( stderr, ", which_sid=%08x", req->which_sid );
 }
 
-static void dump_get_token_user_reply( const struct get_token_user_reply *req )
+static void dump_get_token_sid_reply( const struct get_token_sid_reply *req )
 {
-    fprintf( stderr, " user_len=%u", req->user_len );
-    dump_varargs_SID( ", user=", cur_size );
+    fprintf( stderr, " sid_len=%u", req->sid_len );
+    dump_varargs_SID( ", sid=", cur_size );
 }
 
 static void dump_get_token_groups_request( const struct get_token_groups_request *req )
@@ -4012,7 +4013,7 @@
     (dump_func)dump_check_token_privileges_request,
     (dump_func)dump_duplicate_token_request,
     (dump_func)dump_access_check_request,
-    (dump_func)dump_get_token_user_request,
+    (dump_func)dump_get_token_sid_request,
     (dump_func)dump_get_token_groups_request,
     (dump_func)dump_get_token_default_dacl_request,
     (dump_func)dump_set_token_default_dacl_request,
@@ -4256,7 +4257,7 @@
     (dump_func)dump_check_token_privileges_reply,
     (dump_func)dump_duplicate_token_reply,
     (dump_func)dump_access_check_reply,
-    (dump_func)dump_get_token_user_reply,
+    (dump_func)dump_get_token_sid_reply,
     (dump_func)dump_get_token_groups_reply,
     (dump_func)dump_get_token_default_dacl_reply,
     NULL,
@@ -4500,7 +4501,7 @@
     "check_token_privileges",
     "duplicate_token",
     "access_check",
-    "get_token_user",
+    "get_token_sid",
     "get_token_groups",
     "get_token_default_dacl",
     "set_token_default_dacl",