Rob Shearman : server: Add get_token_impersonation_level server call for retrieving the impersonation level from a token .

Alexandre Julliard julliard at wine.codeweavers.com
Wed Feb 21 13:18:35 CST 2007


Module: wine
Branch: master
Commit: d342d1413cd1ca7ca49e4d42906c4bb51e8fba5e
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=d342d1413cd1ca7ca49e4d42906c4bb51e8fba5e

Author: Rob Shearman <rob at codeweavers.com>
Date:   Wed Feb 21 17:10:45 2007 +0000

server: Add get_token_impersonation_level server call for retrieving the impersonation level from a token.

Add tests for GetTokenInformation(TokenImpersonationLevel).

---

 dlls/advapi32/tests/security.c |   24 ++++++++++++++++++++----
 dlls/ntdll/nt.c                |   15 ++++++++++++++-
 include/wine/server_protocol.h |   17 ++++++++++++++++-
 server/protocol.def            |    7 +++++++
 server/request.h               |    2 ++
 server/token.c                 |   17 +++++++++++++++++
 server/trace.c                 |   13 +++++++++++++
 7 files changed, 89 insertions(+), 6 deletions(-)

diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
index 201c649..95d2f9c 100644
--- a/dlls/advapi32/tests/security.c
+++ b/dlls/advapi32/tests/security.c
@@ -840,7 +840,7 @@ static void test_AccessCheck(void)
 /* test GetTokenInformation for the various attributes */
 static void test_token_attr(void)
 {
-    HANDLE Token;
+    HANDLE Token, ImpersonationToken;
     DWORD Size;
     TOKEN_PRIVILEGES *Privileges;
     TOKEN_GROUPS *Groups;
@@ -848,6 +848,7 @@ static void test_token_attr(void)
     BOOL ret;
     DWORD i, GLE;
     LPSTR SidString;
+    SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
 
     /* cygwin-like use case */
     ret = OpenProcessToken(GetCurrentProcess(), MAXIMUM_ALLOWED, &Token);
@@ -855,16 +856,20 @@ static void test_token_attr(void)
     if (ret)
     {
         BYTE buf[1024];
-        DWORD bufsize = sizeof(buf);
-        ret = GetTokenInformation(Token, TokenUser,(void*)buf, bufsize, &bufsize);
+        Size = sizeof(buf);
+        ret = GetTokenInformation(Token, TokenUser,(void*)buf, Size, &Size);
         ok(ret, "GetTokenInformation failed with error %d\n", GetLastError());
+        Size = sizeof(ImpersonationLevel);
+        ret = GetTokenInformation(Token, TokenImpersonationLevel, &ImpersonationLevel, Size, &Size);
+        GLE = GetLastError();
+        ok(!ret && (GLE == ERROR_INVALID_PARAMETER), "GetTokenInformation(TokenImpersonationLevel) on primary token should have failed with ERROR_INVALID_PARAMETER instead of %d\n", GLE);
         CloseHandle(Token);
     }
 
     if(!pConvertSidToStringSidA)
         return;
 
-    ret = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &Token);
+    ret = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY|TOKEN_DUPLICATE, &Token);
     GLE = GetLastError();
     ok(ret || (GLE == ERROR_CALL_NOT_IMPLEMENTED), 
         "OpenProcessToken failed with error %d\n", GLE);
@@ -928,6 +933,17 @@ static void test_token_attr(void)
         trace("\t%s, 0x%x\n", Name, Privileges->Privileges[i].Attributes);
     }
     HeapFree(GetProcessHeap(), 0, Privileges);
+
+    ret = DuplicateToken(Token, SecurityAnonymous, &ImpersonationToken);
+    ok(ret, "DuplicateToken failed with error %d\n", GetLastError());
+
+    Size = sizeof(ImpersonationLevel);
+    ret = GetTokenInformation(ImpersonationToken, TokenImpersonationLevel, &ImpersonationLevel, Size, &Size);
+    ok(ret, "GetTokenInformation(TokenImpersonationLevel) failed with error %d\n", GetLastError());
+    ok(ImpersonationLevel == SecurityAnonymous, "ImpersonationLevel should have been SecurityAnonymous instead of %d\n", ImpersonationLevel);
+
+    CloseHandle(ImpersonationToken);
+    CloseHandle(Token);
 }
 
 typedef union _MAX_SID
diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c
index 43ce6e1..ce3c31a 100644
--- a/dlls/ntdll/nt.c
+++ b/dlls/ntdll/nt.c
@@ -217,8 +217,10 @@ NTSTATUS WINAPI NtQueryInformationToken(
     case TokenType:
         len = sizeof (TOKEN_TYPE);
         break;
-#if 0
     case TokenImpersonationLevel:
+        len = sizeof(SECURITY_IMPERSONATION_LEVEL);
+        break;
+#if 0
     case TokenStatistics:
 #endif /* 0 */
     default:
@@ -352,6 +354,17 @@ NTSTATUS WINAPI NtQueryInformationToken(
             owner->Owner = sid;
         }
         break;
+    case TokenImpersonationLevel:
+        SERVER_START_REQ( get_token_impersonation_level )
+        {
+            SECURITY_IMPERSONATION_LEVEL *impersonation_level = tokeninfo;
+            req->handle = token;
+            status = wine_server_call( req );
+            if (status == STATUS_SUCCESS)
+                *impersonation_level = reply->impersonation_level;
+        }
+        SERVER_END_REQ;
+        break;
     default:
         {
             ERR("Unhandled Token Information class %d!\n", tokeninfoclass);
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index b5c6201..db13e0c 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -3992,6 +3992,18 @@ struct get_object_info_reply
 };
 
 
+struct get_token_impersonation_level_request
+{
+    struct request_header __header;
+    obj_handle_t   handle;
+};
+struct get_token_impersonation_level_reply
+{
+    struct reply_header __header;
+    int            impersonation_level;
+};
+
+
 enum request
 {
     REQ_new_process,
@@ -4210,6 +4222,7 @@ enum request
     REQ_open_symlink,
     REQ_query_symlink,
     REQ_get_object_info,
+    REQ_get_token_impersonation_level,
     REQ_NB_REQUESTS
 };
 
@@ -4433,6 +4446,7 @@ union generic_request
     struct open_symlink_request open_symlink_request;
     struct query_symlink_request query_symlink_request;
     struct get_object_info_request get_object_info_request;
+    struct get_token_impersonation_level_request get_token_impersonation_level_request;
 };
 union generic_reply
 {
@@ -4654,8 +4668,9 @@ union generic_reply
     struct open_symlink_reply open_symlink_reply;
     struct query_symlink_reply query_symlink_reply;
     struct get_object_info_reply get_object_info_reply;
+    struct get_token_impersonation_level_reply get_token_impersonation_level_reply;
 };
 
-#define SERVER_PROTOCOL_VERSION 277
+#define SERVER_PROTOCOL_VERSION 278
 
 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
diff --git a/server/protocol.def b/server/protocol.def
index e4f16a9..69daab3 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -2862,3 +2862,10 @@ enum message_type
     unsigned int   access;        /* granted access mask */
     unsigned int   ref_count;     /* object ref count */
 @END
+
+/* Query the impersonation level of an impersonation token */
+ at REQ(get_token_impersonation_level)
+    obj_handle_t   handle;        /* handle to the object */
+ at REPLY
+    int            impersonation_level; /* impersonation level of the impersonation token */
+ at END
diff --git a/server/request.h b/server/request.h
index 9119ec1..b24d7c7 100644
--- a/server/request.h
+++ b/server/request.h
@@ -326,6 +326,7 @@ DECL_HANDLER(create_symlink);
 DECL_HANDLER(open_symlink);
 DECL_HANDLER(query_symlink);
 DECL_HANDLER(get_object_info);
+DECL_HANDLER(get_token_impersonation_level);
 
 #ifdef WANT_REQUEST_HANDLERS
 
@@ -548,6 +549,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
     (req_handler)req_open_symlink,
     (req_handler)req_query_symlink,
     (req_handler)req_get_object_info,
+    (req_handler)req_get_token_impersonation_level,
 };
 #endif  /* WANT_REQUEST_HANDLERS */
 
diff --git a/server/token.c b/server/token.c
index c4906a5..573634b 100644
--- a/server/token.c
+++ b/server/token.c
@@ -1386,6 +1386,23 @@ DECL_HANDLER(get_token_groups)
     }
 }
 
+DECL_HANDLER(get_token_impersonation_level)
+{
+    struct token *token;
+
+    if ((token = (struct token *)get_handle_obj( current->process, req->handle,
+                                                 TOKEN_QUERY,
+                                                 &token_ops )))
+    {
+        if (token->primary)
+            set_error( STATUS_INVALID_PARAMETER );
+        else
+            reply->impersonation_level = token->impersonation_level;
+
+        release_object( token );
+    }
+}
+
 DECL_HANDLER(set_security_object)
 {
     data_size_t sd_size = get_req_data_size();
diff --git a/server/trace.c b/server/trace.c
index 50926f5..d4bcf08 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -3443,6 +3443,16 @@ static void dump_get_object_info_reply( const struct get_object_info_reply *req
     fprintf( stderr, " ref_count=%08x", req->ref_count );
 }
 
+static void dump_get_token_impersonation_level_request( const struct get_token_impersonation_level_request *req )
+{
+    fprintf( stderr, " handle=%p", req->handle );
+}
+
+static void dump_get_token_impersonation_level_reply( const struct get_token_impersonation_level_reply *req )
+{
+    fprintf( stderr, " impersonation_level=%d", req->impersonation_level );
+}
+
 static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
     (dump_func)dump_new_process_request,
     (dump_func)dump_get_new_process_info_request,
@@ -3660,6 +3670,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
     (dump_func)dump_open_symlink_request,
     (dump_func)dump_query_symlink_request,
     (dump_func)dump_get_object_info_request,
+    (dump_func)dump_get_token_impersonation_level_request,
 };
 
 static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
@@ -3879,6 +3890,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
     (dump_func)dump_open_symlink_reply,
     (dump_func)dump_query_symlink_reply,
     (dump_func)dump_get_object_info_reply,
+    (dump_func)dump_get_token_impersonation_level_reply,
 };
 
 static const char * const req_names[REQ_NB_REQUESTS] = {
@@ -4098,6 +4110,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
     "open_symlink",
     "query_symlink",
     "get_object_info",
+    "get_token_impersonation_level",
 };
 
 static const struct




More information about the wine-cvs mailing list