From f483f71ad2bac670c2f2c297c3e096d623164aa3 Mon Sep 17 00:00:00 2001 From: Hans Leidekker Date: Tue, 21 Apr 2009 09:53:49 +0200 Subject: [PATCH] ntdll: Implement NtQuery/SetInformationToken(TokenDefaultDacl). --- dlls/advapi32/tests/security.c | 49 +++++++++++++++++++++++- dlls/ntdll/nt.c | 69 +++++++++++++++++++++++++++++++--- 2 files changed, 110 insertions(+), 8 deletions(-) diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c index f775d10d746..b68629d3916 100644 --- a/dlls/advapi32/tests/security.c +++ b/dlls/advapi32/tests/security.c @@ -1176,14 +1176,16 @@ static void test_AccessCheck(void) static void test_token_attr(void) { HANDLE Token, ImpersonationToken; - DWORD Size; + DWORD Size, Size2; TOKEN_PRIVILEGES *Privileges; TOKEN_GROUPS *Groups; TOKEN_USER *User; + TOKEN_DEFAULT_DACL *Dacl; BOOL ret; DWORD i, GLE; LPSTR SidString; SECURITY_IMPERSONATION_LEVEL ImpersonationLevel; + ACL *acl; /* cygwin-like use case */ SetLastError(0xdeadbeef); @@ -1214,7 +1216,7 @@ static void test_token_attr(void) } SetLastError(0xdeadbeef); - ret = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY|TOKEN_DUPLICATE, &Token); + ret = OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &Token); ok(ret, "OpenProcessToken failed with error %d\n", GetLastError()); /* groups */ @@ -1283,6 +1285,49 @@ static void test_token_attr(void) ok(ImpersonationLevel == SecurityAnonymous, "ImpersonationLevel should have been SecurityAnonymous instead of %d\n", ImpersonationLevel); CloseHandle(ImpersonationToken); + + /* default dacl */ + ret = GetTokenInformation(Token, TokenDefaultDacl, NULL, 0, &Size); + ok(!ret && (GetLastError() == ERROR_INSUFFICIENT_BUFFER), + "GetTokenInformation(TokenDefaultDacl) failed with error %u\n", GetLastError()); + + Dacl = HeapAlloc(GetProcessHeap(), 0, Size); + ret = GetTokenInformation(Token, TokenDefaultDacl, Dacl, Size, &Size); + ok(ret, "GetTokenInformation(TokenDefaultDacl) failed with error %u\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = SetTokenInformation(Token, TokenDefaultDacl, NULL, 0); + GLE = GetLastError(); + ok(!ret, "SetTokenInformation(TokenDefaultDacl) succeeded\n"); + ok(GLE == ERROR_BAD_LENGTH, "expected ERROR_BAD_LENGTH got %u\n", GLE); + + SetLastError(0xdeadbeef); + ret = SetTokenInformation(Token, TokenDefaultDacl, NULL, Size); + GLE = GetLastError(); + ok(!ret, "SetTokenInformation(TokenDefaultDacl) succeeded\n"); + ok(GLE == ERROR_NOACCESS, "expected ERROR_NOACCESS got %u\n", GLE); + + acl = Dacl->DefaultDacl; + Dacl->DefaultDacl = NULL; + + ret = SetTokenInformation(Token, TokenDefaultDacl, Dacl, Size); + ok(ret, "SetTokenInformation(TokenDefaultDacl) succeeded\n"); + + Size2 = 0; + Dacl->DefaultDacl = (ACL *)0xdeadbeef; + ret = GetTokenInformation(Token, TokenDefaultDacl, Dacl, Size, &Size2); + ok(ret, "GetTokenInformation(TokenDefaultDacl) failed with error %u\n", GetLastError()); + ok(Dacl->DefaultDacl == NULL, "expected NULL, got %p\n", Dacl->DefaultDacl); + ok(Size2 == sizeof(TOKEN_DEFAULT_DACL), "got %u expected sizeof(TOKEN_DEFAULT_DACL)\n", Size2); + + Dacl->DefaultDacl = acl; + ret = SetTokenInformation(Token, TokenDefaultDacl, Dacl, Size); + ok(ret, "SetTokenInformation(TokenDefaultDacl) failed with error %u\n", GetLastError()); + + ret = GetTokenInformation(Token, TokenDefaultDacl, Dacl, Size, &Size2); + ok(ret, "GetTokenInformation(TokenDefaultDacl) failed with error %u\n", GetLastError()); + + HeapFree(GetProcessHeap(), 0, Dacl); CloseHandle(Token); } diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c index d2e133cae46..8ffa9e02352 100644 --- a/dlls/ntdll/nt.c +++ b/dlls/ntdll/nt.c @@ -242,9 +242,6 @@ NTSTATUS WINAPI NtQueryInformationToken( case TokenPrimaryGroup: len = sizeof(TOKEN_PRIMARY_GROUP); break; - case TokenDefaultDacl: - len = sizeof(TOKEN_DEFAULT_DACL); - break; case TokenSource: len = sizeof(TOKEN_SOURCE); break; @@ -441,6 +438,31 @@ NTSTATUS WINAPI NtQueryInformationToken( } SERVER_END_REQ; break; + case TokenDefaultDacl: + SERVER_START_REQ( get_token_default_dacl ) + { + TOKEN_DEFAULT_DACL *default_dacl = tokeninfo; + ACL *acl = (ACL *)(default_dacl + 1); + DWORD acl_len; + + if (tokeninfolength < sizeof(TOKEN_DEFAULT_DACL)) acl_len = 0; + else acl_len = tokeninfolength - sizeof(TOKEN_DEFAULT_DACL); + + req->handle = wine_server_obj_handle( token ); + wine_server_set_reply( req, acl, acl_len ); + status = wine_server_call( req ); + + if (retlen) *retlen = reply->acl_len + sizeof(TOKEN_DEFAULT_DACL); + if (status == STATUS_SUCCESS) + { + if (reply->acl_len) + default_dacl->DefaultDacl = acl; + else + default_dacl->DefaultDacl = NULL; + } + } + SERVER_END_REQ; + break; default: { ERR("Unhandled Token Information class %d!\n", tokeninfoclass); @@ -460,9 +482,44 @@ NTSTATUS WINAPI NtSetInformationToken( PVOID TokenInformation, ULONG TokenInformationLength) { - FIXME("%p %d %p %u\n", TokenHandle, TokenInformationClass, - TokenInformation, TokenInformationLength); - return STATUS_NOT_IMPLEMENTED; + NTSTATUS ret = STATUS_NOT_IMPLEMENTED; + + TRACE("%p %d %p %u\n", TokenHandle, TokenInformationClass, + TokenInformation, TokenInformationLength); + + switch (TokenInformationClass) + { + case TokenDefaultDacl: + if (TokenInformationLength < sizeof(TOKEN_DEFAULT_DACL)) + { + ret = STATUS_INFO_LENGTH_MISMATCH; + break; + } + if (!TokenInformation) + { + ret = STATUS_ACCESS_VIOLATION; + break; + } + SERVER_START_REQ( set_token_default_dacl ) + { + ACL *acl = ((TOKEN_DEFAULT_DACL *)TokenInformation)->DefaultDacl; + WORD size; + + if (acl) size = acl->AclSize; + else size = 0; + + req->handle = wine_server_obj_handle( TokenHandle ); + wine_server_add_data( req, acl, size ); + ret = wine_server_call( req ); + } + SERVER_END_REQ; + break; + default: + FIXME("unimplemented class %u\n", TokenInformationClass); + break; + } + + return ret; } /******************************************************************************