[ADVAPI32_WINETEST]: Sync with Wine 1.5.19.

svn path=/trunk/; revision=57864
This commit is contained in:
Amine Khaldi 2012-12-10 14:54:40 +00:00
parent c0976cca94
commit 17eb8ef5fb
5 changed files with 1100 additions and 127 deletions

View file

@ -35,7 +35,9 @@ static BOOL (WINAPI *pCredReadA)(LPCSTR,DWORD,DWORD,PCREDENTIALA *);
static BOOL (WINAPI *pCredRenameA)(LPCSTR,LPCSTR,DWORD,DWORD);
static BOOL (WINAPI *pCredWriteA)(PCREDENTIALA,DWORD);
static BOOL (WINAPI *pCredReadDomainCredentialsA)(PCREDENTIAL_TARGET_INFORMATIONA,DWORD,DWORD*,PCREDENTIALA**);
static BOOL (WINAPI *pCredMarshalCredentialA)(CRED_MARSHAL_TYPE,PVOID,LPSTR *);
static BOOL (WINAPI *pCredUnmarshalCredentialA)(LPCSTR,PCRED_MARSHAL_TYPE,PVOID);
static BOOL (WINAPI *pCredIsMarshaledCredentialA)(LPCSTR);
#define TEST_TARGET_NAME "credtest.winehq.org"
#define TEST_TARGET_NAME2 "credtest2.winehq.org"
@ -119,6 +121,47 @@ static void test_CredWriteA(void)
ok(!ret && GetLastError() == ERROR_BAD_USERNAME,
"CredWriteA with NULL username should have failed with ERROR_BAD_USERNAME instead of %d\n",
GetLastError());
new_cred.UserName = (char *)"winetest";
new_cred.Persist = CRED_PERSIST_LOCAL_MACHINE;
SetLastError(0xdeadbeef);
ret = pCredWriteA(&new_cred, 0);
ok(ret || broken(!ret), "CredWriteA failed with error %u\n", GetLastError());
if (ret)
{
ret = pCredDeleteA(TEST_TARGET_NAME, CRED_TYPE_DOMAIN_PASSWORD, 0);
ok(ret, "CredDeleteA failed with error %u\n", GetLastError());
}
new_cred.Type = CRED_TYPE_GENERIC;
SetLastError(0xdeadbeef);
ret = pCredWriteA(&new_cred, 0);
ok(ret || broken(!ret), "CredWriteA failed with error %u\n", GetLastError());
if (ret)
{
ret = pCredDeleteA(TEST_TARGET_NAME, CRED_TYPE_GENERIC, 0);
ok(ret, "CredDeleteA failed with error %u\n", GetLastError());
}
new_cred.Persist = CRED_PERSIST_SESSION;
ret = pCredWriteA(&new_cred, 0);
ok(ret, "CredWriteA failed with error %u\n", GetLastError());
ret = pCredDeleteA(TEST_TARGET_NAME, CRED_TYPE_GENERIC, 0);
ok(ret, "CredDeleteA failed with error %u\n", GetLastError());
new_cred.Type = CRED_TYPE_DOMAIN_PASSWORD;
SetLastError(0xdeadbeef);
ret = pCredWriteA(&new_cred, 0);
ok(ret || broken(!ret), "CredWriteA failed with error %u\n", GetLastError());
if (ret)
{
ret = pCredDeleteA(TEST_TARGET_NAME, CRED_TYPE_DOMAIN_PASSWORD, 0);
ok(ret, "CredDeleteA failed with error %u\n", GetLastError());
}
new_cred.UserName = NULL;
SetLastError(0xdeadbeef);
ret = pCredWriteA(&new_cred, 0);
ok(!ret, "CredWriteA succeeded\n");
ok(GetLastError() == ERROR_BAD_USERNAME, "got %u\n", GetLastError());
}
static void test_CredDeleteA(void)
@ -336,6 +379,368 @@ static void test_domain_password(DWORD cred_type)
ok(ret, "CredDeleteA failed with error %d\n", GetLastError());
}
static void test_CredMarshalCredentialA(void)
{
static WCHAR emptyW[] = {0};
static WCHAR tW[] = {'t',0};
static WCHAR teW[] = {'t','e',0};
static WCHAR tesW[] = {'t','e','s',0};
static WCHAR testW[] = {'t','e','s','t',0};
static WCHAR test1W[] = {'t','e','s','t','1',0};
CERT_CREDENTIAL_INFO cert;
USERNAME_TARGET_CREDENTIAL_INFO username;
DWORD error;
char *str;
BOOL ret;
SetLastError( 0xdeadbeef );
ret = pCredMarshalCredentialA( 0, NULL, NULL );
error = GetLastError();
ok( !ret, "unexpected success\n" );
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
memset( cert.rgbHashOfCert, 0, sizeof(cert.rgbHashOfCert) );
cert.cbSize = sizeof(cert);
SetLastError( 0xdeadbeef );
ret = pCredMarshalCredentialA( 0, &cert, NULL );
error = GetLastError();
ok( !ret, "unexpected success\n" );
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
str = (char *)0xdeadbeef;
SetLastError( 0xdeadbeef );
ret = pCredMarshalCredentialA( 0, &cert, &str );
error = GetLastError();
ok( !ret, "unexpected success\n" );
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
ok( str == (char *)0xdeadbeef, "got %p\n", str );
SetLastError( 0xdeadbeef );
ret = pCredMarshalCredentialA( CertCredential, NULL, NULL );
error = GetLastError();
ok( !ret, "unexpected success\n" );
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
if (0) { /* crash */
SetLastError( 0xdeadbeef );
ret = pCredMarshalCredentialA( CertCredential, &cert, NULL );
error = GetLastError();
ok( !ret, "unexpected success\n" );
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
}
cert.cbSize = 0;
str = (char *)0xdeadbeef;
SetLastError( 0xdeadbeef );
ret = pCredMarshalCredentialA( CertCredential, &cert, &str );
error = GetLastError();
ok( !ret, "unexpected success\n" );
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
ok( str == (char *)0xdeadbeef, "got %p\n", str );
cert.cbSize = sizeof(cert) + 4;
str = NULL;
ret = pCredMarshalCredentialA( CertCredential, &cert, &str );
ok( ret, "unexpected failure %u\n", GetLastError() );
ok( str != NULL, "str not set\n" );
ok( !lstrcmpA( str, "@@BAAAAAAAAAAAAAAAAAAAAAAAAAAA" ), "got %s\n", str );
pCredFree( str );
cert.cbSize = sizeof(cert);
cert.rgbHashOfCert[0] = 2;
str = NULL;
ret = pCredMarshalCredentialA( CertCredential, &cert, &str );
ok( ret, "unexpected failure %u\n", GetLastError() );
ok( str != NULL, "str not set\n" );
ok( !lstrcmpA( str, "@@BCAAAAAAAAAAAAAAAAAAAAAAAAAA" ), "got %s\n", str );
pCredFree( str );
cert.rgbHashOfCert[0] = 255;
str = NULL;
ret = pCredMarshalCredentialA( CertCredential, &cert, &str );
ok( ret, "unexpected failure %u\n", GetLastError() );
ok( str != NULL, "str not set\n" );
ok( !lstrcmpA( str, "@@B-DAAAAAAAAAAAAAAAAAAAAAAAAA" ), "got %s\n", str );
pCredFree( str );
cert.rgbHashOfCert[0] = 1;
cert.rgbHashOfCert[1] = 1;
str = NULL;
ret = pCredMarshalCredentialA( CertCredential, &cert, &str );
ok( ret, "unexpected failure %u\n", GetLastError() );
ok( str != NULL, "str not set\n" );
ok( !lstrcmpA( str, "@@BBEAAAAAAAAAAAAAAAAAAAAAAAAA" ), "got %s\n", str );
pCredFree( str );
cert.rgbHashOfCert[0] = 1;
cert.rgbHashOfCert[1] = 1;
cert.rgbHashOfCert[2] = 1;
str = NULL;
ret = pCredMarshalCredentialA( CertCredential, &cert, &str );
ok( ret, "unexpected failure %u\n", GetLastError() );
ok( str != NULL, "str not set\n" );
ok( !lstrcmpA( str, "@@BBEQAAAAAAAAAAAAAAAAAAAAAAAA" ), "got %s\n", str );
pCredFree( str );
memset( cert.rgbHashOfCert, 0, sizeof(cert.rgbHashOfCert) );
cert.rgbHashOfCert[0] = 'W';
cert.rgbHashOfCert[1] = 'i';
cert.rgbHashOfCert[2] = 'n';
cert.rgbHashOfCert[3] = 'e';
str = NULL;
ret = pCredMarshalCredentialA( CertCredential, &cert, &str );
ok( ret, "unexpected failure %u\n", GetLastError() );
ok( str != NULL, "str not set\n" );
ok( !lstrcmpA( str, "@@BXlmblBAAAAAAAAAAAAAAAAAAAAA" ), "got %s\n", str );
pCredFree( str );
memset( cert.rgbHashOfCert, 0xff, sizeof(cert.rgbHashOfCert) );
str = NULL;
ret = pCredMarshalCredentialA( CertCredential, &cert, &str );
ok( ret, "unexpected failure %u\n", GetLastError() );
ok( str != NULL, "str not set\n" );
ok( !lstrcmpA( str, "@@B--------------------------P" ), "got %s\n", str );
pCredFree( str );
username.UserName = NULL;
str = (char *)0xdeadbeef;
SetLastError( 0xdeadbeef );
ret = pCredMarshalCredentialA( UsernameTargetCredential, &username, &str );
error = GetLastError();
ok( !ret, "unexpected success\n" );
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
ok( str == (char *)0xdeadbeef, "got %p\n", str );
username.UserName = emptyW;
str = (char *)0xdeadbeef;
SetLastError( 0xdeadbeef );
ret = pCredMarshalCredentialA( UsernameTargetCredential, &username, &str );
error = GetLastError();
ok( !ret, "unexpected success\n" );
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
ok( str == (char *)0xdeadbeef, "got %p\n", str );
username.UserName = tW;
str = NULL;
ret = pCredMarshalCredentialA( UsernameTargetCredential, &username, &str );
ok( ret, "unexpected failure %u\n", GetLastError() );
ok( str != NULL, "str not set\n" );
ok( !lstrcmpA( str, "@@CCAAAAA0BA" ), "got %s\n", str );
pCredFree( str );
username.UserName = teW;
str = NULL;
ret = pCredMarshalCredentialA( UsernameTargetCredential, &username, &str );
ok( ret, "unexpected failure %u\n", GetLastError() );
ok( str != NULL, "str not set\n" );
ok( !lstrcmpA( str, "@@CEAAAAA0BQZAA" ), "got %s\n", str );
pCredFree( str );
username.UserName = tesW;
str = NULL;
ret = pCredMarshalCredentialA( UsernameTargetCredential, &username, &str );
ok( ret, "unexpected failure %u\n", GetLastError() );
ok( str != NULL, "str not set\n" );
ok( !lstrcmpA( str, "@@CGAAAAA0BQZAMHA" ), "got %s\n", str );
pCredFree( str );
username.UserName = testW;
str = NULL;
ret = pCredMarshalCredentialA( UsernameTargetCredential, &username, &str );
ok( ret, "unexpected failure %u\n", GetLastError() );
ok( str != NULL, "str not set\n" );
ok( !lstrcmpA( str, "@@CIAAAAA0BQZAMHA0BA" ), "got %s\n", str );
pCredFree( str );
username.UserName = test1W;
str = NULL;
ret = pCredMarshalCredentialA( UsernameTargetCredential, &username, &str );
ok( ret, "unexpected failure %u\n", GetLastError() );
ok( str != NULL, "str not set\n" );
ok( !lstrcmpA( str, "@@CKAAAAA0BQZAMHA0BQMAA" ), "got %s\n", str );
pCredFree( str );
}
static void test_CredUnmarshalCredentialA(void)
{
static WCHAR tW[] = {'t',0};
static WCHAR testW[] = {'t','e','s','t',0};
CERT_CREDENTIAL_INFO *cert;
USERNAME_TARGET_CREDENTIAL_INFO *username;
CRED_MARSHAL_TYPE type;
unsigned int i;
DWORD error;
BOOL ret;
SetLastError( 0xdeadbeef );
ret = pCredUnmarshalCredentialA( NULL, NULL, NULL );
error = GetLastError();
ok( !ret, "unexpected success\n" );
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
cert = NULL;
SetLastError( 0xdeadbeef );
ret = pCredUnmarshalCredentialA( NULL, NULL, (void **)&cert );
error = GetLastError();
ok( !ret, "unexpected success\n" );
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
type = 0;
cert = NULL;
SetLastError( 0xdeadbeef );
ret = pCredUnmarshalCredentialA( NULL, &type, (void **)&cert );
error = GetLastError();
ok( !ret, "unexpected success\n" );
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
type = 0;
cert = NULL;
SetLastError( 0xdeadbeef );
ret = pCredUnmarshalCredentialA( "", &type, (void **)&cert );
error = GetLastError();
ok( !ret, "unexpected success\n" );
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
if (0) { /* crash */
SetLastError( 0xdeadbeef );
ret = pCredUnmarshalCredentialA( "@@BAAAAAAAAAAAAAAAAAAAAAAAAAAA", &type, NULL );
error = GetLastError();
ok( !ret, "unexpected success\n" );
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
SetLastError( 0xdeadbeef );
ret = pCredUnmarshalCredentialA( "@@BAAAAAAAAAAAAAAAAAAAAAAAAAAA", NULL, (void **)&cert );
error = GetLastError();
ok( !ret, "unexpected success\n" );
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
}
type = 0;
cert = NULL;
ret = pCredUnmarshalCredentialA( "@@BAAAAAAAAAAAAAAAAAAAAAAAAAAA", &type, (void **)&cert );
ok( ret, "unexpected failure %u\n", GetLastError() );
ok( type == CertCredential, "got %u\n", type );
ok( cert != NULL, "cert is NULL\n" );
ok( cert->cbSize == sizeof(*cert), "wrong size %u\n", cert->cbSize );
for (i = 0; i < sizeof(cert->rgbHashOfCert); i++) ok( !cert->rgbHashOfCert[i], "wrong data\n" );
pCredFree( cert );
type = 0;
cert = NULL;
ret = pCredUnmarshalCredentialA( "@@BXlmblBAAAAAAAAAAAAAAAAAAAAA", &type, (void **)&cert );
ok( ret, "unexpected failure %u\n", GetLastError() );
ok( type == CertCredential, "got %u\n", type );
ok( cert != NULL, "cert is NULL\n" );
ok( cert->cbSize == sizeof(*cert), "wrong size %u\n", cert->cbSize );
ok( cert->rgbHashOfCert[0] == 'W', "wrong data)\n" );
ok( cert->rgbHashOfCert[1] == 'i', "wrong data\n" );
ok( cert->rgbHashOfCert[2] == 'n', "wrong data\n" );
ok( cert->rgbHashOfCert[3] == 'e', "wrong data\n" );
for (i = 4; i < sizeof(cert->rgbHashOfCert); i++) ok( !cert->rgbHashOfCert[i], "wrong data\n" );
pCredFree( cert );
SetLastError( 0xdeadbeef );
ret = pCredUnmarshalCredentialA( "@@CAAAAAA", &type, (void **)&username );
error = GetLastError();
ok( !ret, "unexpected success\n" );
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
SetLastError( 0xdeadbeef );
ret = pCredUnmarshalCredentialA( "@@CAAAAAA0BA", &type, (void **)&username );
error = GetLastError();
ok( !ret, "unexpected success\n" );
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
type = 0;
username = NULL;
ret = pCredUnmarshalCredentialA( "@@CCAAAAA0BA", &type, (void **)&username );
ok( ret, "unexpected failure %u\n", GetLastError() );
ok( type == UsernameTargetCredential, "got %u\n", type );
ok( username != NULL, "username is NULL\n" );
ok( username->UserName != NULL, "UserName is NULL\n" );
ok( !lstrcmpW( username->UserName, tW ), "got %s\n", wine_dbgstr_w(username->UserName) );
pCredFree( username );
type = 0;
username = NULL;
ret = pCredUnmarshalCredentialA( "@@CIAAAAA0BQZAMHA0BA", &type, (void **)&username );
ok( ret, "unexpected failure %u\n", GetLastError() );
ok( type == UsernameTargetCredential, "got %u\n", type );
ok( username != NULL, "username is NULL\n" );
ok( username->UserName != NULL, "UserName is NULL\n" );
ok( !lstrcmpW( username->UserName, testW ), "got %s\n", wine_dbgstr_w(username->UserName) );
pCredFree( username );
type = 0;
username = NULL;
SetLastError( 0xdeadbeef );
ret = pCredUnmarshalCredentialA( "@@CA-----0BQZAMHA0BA", &type, (void **)&username );
error = GetLastError();
ok( !ret, "unexpected success\n" );
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
}
static void test_CredIsMarshaledCredentialA(void)
{
int i;
BOOL res;
BOOL expected = TRUE;
const char * ptr[] = {
/* CertCredential */
"@@BXlmblBAAAAAAAAAAAAAAAAAAAAA", /* hash for 'W','i','n','e' */
"@@BAAAAAAAAAAAAAAAAAAAAAAAAAAA", /* hash for all 0 */
/* UsernameTargetCredential */
"@@CCAAAAA0BA", /* "t" */
"@@CIAAAAA0BQZAMHA0BA", /* "test" */
/* todo: BinaryBlobCredential */
/* not marshaled names return always FALSE */
"winetest",
"",
"@@",
"@@A",
"@@AA",
"@@AAA",
"@@B",
"@@BB",
"@@BBB",
/* CertCredential */
"@@BAAAAAAAAAAAAAAAAAAAAAAAAAAAA", /* to long */
"@@BAAAAAAAAAAAAAAAAAAAAAAAAAA", /* to short */
"@@BAAAAAAAAAAAAAAAAAAAAAAAAAA+", /* bad char */
"@@BAAAAAAAAAAAAAAAAAAAAAAAAAA:",
"@@BAAAAAAAAAAAAAAAAAAAAAAAAAA>",
"@@BAAAAAAAAAAAAAAAAAAAAAAAAAA<",
"@@C",
"@@CC",
"@@CCC",
"@@D",
"@@DD",
"@@DDD",
NULL};
for (i = 0; ptr[i]; i++)
{
if (*ptr[i] != '@')
expected = FALSE;
SetLastError(0xdeadbeef);
res = pCredIsMarshaledCredentialA(ptr[i]);
if (expected)
ok(res != FALSE, "%d: got %d and %u for %s (expected TRUE)\n", i, res, GetLastError(), ptr[i]);
else
{
/* Windows returns ERROR_INVALID_PARAMETER here, but that's not documented */
ok(!res, "%d: got %d and %u for %s (expected FALSE)\n", i, res, GetLastError(), ptr[i]);
}
}
}
START_TEST(cred)
{
DWORD persists[CRED_TYPE_MAXIMUM];
@ -348,9 +753,11 @@ START_TEST(cred)
pCredReadA = (void *)GetProcAddress(GetModuleHandle("advapi32.dll"), "CredReadA");
pCredRenameA = (void *)GetProcAddress(GetModuleHandle("advapi32.dll"), "CredRenameA");
pCredReadDomainCredentialsA = (void *)GetProcAddress(GetModuleHandle("advapi32.dll"), "CredReadDomainCredentialsA");
pCredMarshalCredentialA = (void *)GetProcAddress(GetModuleHandle("advapi32.dll"), "CredMarshalCredentialA");
pCredUnmarshalCredentialA = (void *)GetProcAddress(GetModuleHandle("advapi32.dll"), "CredUnmarshalCredentialA");
pCredIsMarshaledCredentialA = (void *)GetProcAddress(GetModuleHandle("advapi32.dll"), "CredIsMarshaledCredentialA");
if (!pCredEnumerateA || !pCredFree || !pCredWriteA || !pCredDeleteA ||
!pCredReadA)
if (!pCredEnumerateA || !pCredFree || !pCredWriteA || !pCredDeleteA || !pCredReadA)
{
win_skip("credentials functions not present in advapi32.dll\n");
return;
@ -392,4 +799,8 @@ START_TEST(cred)
skip("CRED_TYPE_DOMAIN_VISIBLE_PASSWORD credentials are not supported or are disabled. Skipping\n");
else
test_domain_password(CRED_TYPE_DOMAIN_VISIBLE_PASSWORD);
test_CredMarshalCredentialA();
test_CredUnmarshalCredentialA();
test_CredIsMarshaledCredentialA();
}

View file

@ -238,6 +238,9 @@ static void test_incorrect_api_usage(void)
if (!result) return;
pCryptDestroyHash(hHash);
result = pCryptCreateHash(0, CALG_SHA, 0, 0, &hHash);
ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
result = pCryptGenKey(0, CALG_RC4, 0, &hKey);
ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
@ -448,7 +451,9 @@ static void test_verify_sig(void)
"Expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
SetLastError(0xdeadbeef);
ret = pCryptVerifySignatureW(hash, bogus, sizeof(bogus), key, NULL, 0);
ok(!ret && GetLastError() == NTE_BAD_SIGNATURE,
ok(!ret &&
(GetLastError() == NTE_BAD_SIGNATURE ||
broken(GetLastError() == NTE_BAD_HASH_STATE /* older NT4 */)),
"Expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
pCryptDestroyKey(key);
pCryptDestroyHash(hash);
@ -619,9 +624,6 @@ static BOOL FindProvTypesRegVals(DWORD *pdwIndex, DWORD *pdwProvType, LPSTR *psz
(*pdwIndex)++;
}
if (!ret)
LocalFree(*pszTypeName);
RegCloseKey(hSubKey);
LocalFree(szName);

View file

@ -346,6 +346,9 @@ static void test_set_value(void)
/* Crashes on NT4, Windows 2000 and XP SP1 */
ret = RegSetValueW(hkey_main, NULL, REG_SZ, NULL, 0);
ok(ret == ERROR_INVALID_PARAMETER, "RegSetValueW should have failed with ERROR_INVALID_PARAMETER instead of %d\n", ret);
RegSetValueExA(hkey_main, name2A, 0, REG_SZ, (const BYTE *)1, 1);
RegSetValueExA(hkey_main, name2A, 0, REG_DWORD, (const BYTE *)1, 1);
}
ret = RegSetValueW(hkey_main, NULL, REG_SZ, string1W, sizeof(string1W));
@ -353,7 +356,12 @@ static void test_set_value(void)
test_hkey_main_Value_A(NULL, string1A, sizeof(string1A));
test_hkey_main_Value_W(NULL, string1W, sizeof(string1W));
/* RegSetValueA ignores the size passed in */
ret = RegSetValueW(hkey_main, name1W, REG_SZ, string1W, sizeof(string1W));
ok(ret == ERROR_SUCCESS, "RegSetValueW failed: %d, GLE=%d\n", ret, GetLastError());
test_hkey_main_Value_A(name1A, string1A, sizeof(string1A));
test_hkey_main_Value_W(name1W, string1W, sizeof(string1W));
/* RegSetValueW ignores the size passed in */
ret = RegSetValueW(hkey_main, NULL, REG_SZ, string1W, 4 * sizeof(string1W[0]));
ok(ret == ERROR_SUCCESS, "RegSetValueW failed: %d, GLE=%d\n", ret, GetLastError());
test_hkey_main_Value_A(NULL, string1A, sizeof(string1A));
@ -390,6 +398,12 @@ static void test_set_value(void)
ok(ret == ERROR_SUCCESS, "RegSetValueExW failed: %d, GLE=%d\n", ret, GetLastError());
test_hkey_main_Value_A(name2A, string2A, sizeof(string2A));
test_hkey_main_Value_W(name2W, string2W, sizeof(string2W));
/* test RegSetValueExW with data = 1 */
ret = RegSetValueExW(hkey_main, name2W, 0, REG_SZ, (const BYTE *)1, 1);
ok(ret == ERROR_NOACCESS, "RegSetValueExW should have failed with ERROR_NOACCESS: %d, GLE=%d\n", ret, GetLastError());
ret = RegSetValueExW(hkey_main, name2W, 0, REG_DWORD, (const BYTE *)1, 1);
ok(ret == ERROR_NOACCESS, "RegSetValueExW should have failed with ERROR_NOACCESS: %d, GLE=%d\n", ret, GetLastError());
}
static void create_test_entries(void)

View file

@ -33,8 +33,17 @@
#include "ntsecapi.h"
#include "lmcons.h"
#include <winsvc.h>
#include "wine/test.h"
/* PROCESS_ALL_ACCESS in Vista+ PSDKs is incompatible with older Windows versions */
#define PROCESS_ALL_ACCESS_NT4 (PROCESS_ALL_ACCESS & ~0xf000)
#ifndef EVENT_QUERY_STATE
#define EVENT_QUERY_STATE 0x0001
#endif
/* copied from Wine winternl.h - not included in the Windows SDK */
typedef enum _OBJECT_INFORMATION_CLASS {
ObjectBasicInformation,
@ -58,7 +67,7 @@ typedef struct _OBJECT_BASIC_INFORMATION {
LARGE_INTEGER CreateTime;
} OBJECT_BASIC_INFORMATION, *POBJECT_BASIC_INFORMATION;
#define expect_eq(expr, value, type, format) { type ret = expr; ok((value) == ret, #expr " expected " format " got " format "\n", (value), (ret)); }
#define expect_eq(expr, value, type, format) { type ret_ = expr; ok((value) == ret_, #expr " expected " format " got " format "\n", (value), (ret_)); }
static BOOL (WINAPI *pAddAccessAllowedAceEx)(PACL, DWORD, DWORD, DWORD, PSID);
static BOOL (WINAPI *pAddAccessDeniedAceEx)(PACL, DWORD, DWORD, DWORD, PSID);
@ -94,6 +103,8 @@ static BOOL (WINAPI *pSetFileSecurityA)(LPCSTR, SECURITY_INFORMATION,
static DWORD (WINAPI *pGetNamedSecurityInfoA)(LPSTR, SE_OBJECT_TYPE, SECURITY_INFORMATION,
PSID*, PSID*, PACL*, PACL*,
PSECURITY_DESCRIPTOR*);
static DWORD (WINAPI *pSetNamedSecurityInfoA)(LPTSTR, SE_OBJECT_TYPE, SECURITY_INFORMATION,
PSID, PSID, PACL, PACL);
static PDWORD (WINAPI *pGetSidSubAuthority)(PSID, DWORD);
static PUCHAR (WINAPI *pGetSidSubAuthorityCount)(PSID);
static BOOL (WINAPI *pIsValidSid)(PSID);
@ -113,15 +124,27 @@ static BOOL (WINAPI *pSetSecurityDescriptorControl)(PSECURITY_DESCRIPTOR, SECURI
SECURITY_DESCRIPTOR_CONTROL);
static DWORD (WINAPI *pGetSecurityInfo)(HANDLE, SE_OBJECT_TYPE, SECURITY_INFORMATION,
PSID*, PSID*, PACL*, PACL*, PSECURITY_DESCRIPTOR*);
static DWORD (WINAPI *pSetSecurityInfo)(HANDLE, SE_OBJECT_TYPE, SECURITY_INFORMATION,
PSID, PSID, PACL, PACL);
static NTSTATUS (WINAPI *pNtAccessCheck)(PSECURITY_DESCRIPTOR, HANDLE, ACCESS_MASK, PGENERIC_MAPPING,
PPRIVILEGE_SET, PULONG, PULONG, NTSTATUS*);
static BOOL (WINAPI *pCreateRestrictedToken)(HANDLE, DWORD, DWORD, PSID_AND_ATTRIBUTES, DWORD,
PLUID_AND_ATTRIBUTES, DWORD, PSID_AND_ATTRIBUTES, PHANDLE);
static BOOL (WINAPI *pGetAclInformation)(PACL,LPVOID,DWORD,ACL_INFORMATION_CLASS);
static BOOL (WINAPI *pGetAce)(PACL,DWORD,LPVOID*);
static HMODULE hmod;
static int myARGC;
static char** myARGV;
struct strsid_entry
{
const char *str;
DWORD flags;
};
#define STRSID_OK 0
#define STRSID_OPT 1
struct sidRef
{
SID_IDENTIFIER_AUTHORITY auth;
@ -151,6 +174,7 @@ static void init(void)
pSetFileSecurityA = (void *)GetProcAddress(hmod, "SetFileSecurityA" );
pCreateWellKnownSid = (void *)GetProcAddress( hmod, "CreateWellKnownSid" );
pGetNamedSecurityInfoA = (void *)GetProcAddress(hmod, "GetNamedSecurityInfoA");
pSetNamedSecurityInfoA = (void *)GetProcAddress(hmod, "SetNamedSecurityInfoA");
pGetSidSubAuthority = (void *)GetProcAddress(hmod, "GetSidSubAuthority");
pGetSidSubAuthorityCount = (void *)GetProcAddress(hmod, "GetSidSubAuthorityCount");
pIsValidSid = (void *)GetProcAddress(hmod, "IsValidSid");
@ -159,34 +183,16 @@ static void init(void)
pSetEntriesInAclA = (void *)GetProcAddress(hmod, "SetEntriesInAclA");
pSetSecurityDescriptorControl = (void *)GetProcAddress(hmod, "SetSecurityDescriptorControl");
pGetSecurityInfo = (void *)GetProcAddress(hmod, "GetSecurityInfo");
pSetSecurityInfo = (void *)GetProcAddress(hmod, "SetSecurityInfo");
pCreateRestrictedToken = (void *)GetProcAddress(hmod, "CreateRestrictedToken");
pConvertSidToStringSidA = (void *)GetProcAddress(hmod, "ConvertSidToStringSidA");
pConvertStringSidToSidA = (void *)GetProcAddress(hmod, "ConvertStringSidToSidA");
pGetAclInformation = (void *)GetProcAddress(hmod, "GetAclInformation");
pGetAce = (void *)GetProcAddress(hmod, "GetAce");
myARGC = winetest_get_mainargs( &myARGV );
}
static void test_str_sid(const char *str_sid)
{
PSID psid;
char *temp;
if (pConvertStringSidToSidA(str_sid, &psid))
{
if (pConvertSidToStringSidA(psid, &temp))
{
trace(" %s: %s\n", str_sid, temp);
LocalFree(temp);
}
LocalFree(psid);
}
else
{
if (GetLastError() != ERROR_INVALID_SID)
trace(" %s: couldn't be converted, returned %d\n", str_sid, GetLastError());
else
trace(" %s: couldn't be converted\n", str_sid);
}
}
static void test_sid(void)
{
struct sidRef refs[] = {
@ -197,6 +203,18 @@ static void test_sid(void)
{ { {0x00,0x00,0x00,0x00,0x00,0x02} }, "S-1-2-1" },
{ { {0x00,0x00,0x00,0x00,0x00,0x0c} }, "S-1-12-1" },
};
struct strsid_entry strsid_table[] = {
{"AO", STRSID_OK}, {"RU", STRSID_OK}, {"AN", STRSID_OK}, {"AU", STRSID_OK},
{"BA", STRSID_OK}, {"BG", STRSID_OK}, {"BO", STRSID_OK}, {"BU", STRSID_OK},
{"CA", STRSID_OPT}, {"CG", STRSID_OK}, {"CO", STRSID_OK}, {"DA", STRSID_OPT},
{"DC", STRSID_OPT}, {"DD", STRSID_OPT}, {"DG", STRSID_OPT}, {"DU", STRSID_OPT},
{"EA", STRSID_OPT}, {"ED", STRSID_OK}, {"WD", STRSID_OK}, {"PA", STRSID_OPT},
{"IU", STRSID_OK}, {"LA", STRSID_OK}, {"LG", STRSID_OK}, {"LS", STRSID_OK},
{"SY", STRSID_OK}, {"NU", STRSID_OK}, {"NO", STRSID_OK}, {"NS", STRSID_OK},
{"PO", STRSID_OK}, {"PS", STRSID_OK}, {"PU", STRSID_OK}, {"RS", STRSID_OPT},
{"RD", STRSID_OK}, {"RE", STRSID_OK}, {"RC", STRSID_OK}, {"SA", STRSID_OPT},
{"SO", STRSID_OK}, {"SU", STRSID_OK}};
const char noSubAuthStr[] = "S-1-5";
unsigned int i;
PSID psid = NULL;
@ -204,12 +222,11 @@ static void test_sid(void)
BOOL r;
LPSTR str = NULL;
pConvertSidToStringSidA = (void *)GetProcAddress( hmod, "ConvertSidToStringSidA" );
if( !pConvertSidToStringSidA )
return;
pConvertStringSidToSidA = (void *)GetProcAddress( hmod, "ConvertStringSidToSidA" );
if( !pConvertStringSidToSidA )
if( !pConvertSidToStringSidA || !pConvertStringSidToSidA )
{
win_skip("ConvertSidToStringSidA or ConvertStringSidToSidA not available\n");
return;
}
r = pConvertStringSidToSidA( NULL, NULL );
ok( !r, "expected failure with NULL parameters\n" );
@ -246,8 +263,6 @@ static void test_sid(void)
for( i = 0; i < sizeof(refs) / sizeof(refs[0]); i++ )
{
PISID pisid;
r = AllocateAndInitializeSid( &refs[i].auth, 1,1,0,0,0,0,0,0,0,
&psid );
ok( r, "failed to allocate sid\n" );
@ -284,45 +299,44 @@ static void test_sid(void)
LocalFree( psid );
}
trace("String SIDs:\n");
test_str_sid("AO");
test_str_sid("RU");
test_str_sid("AN");
test_str_sid("AU");
test_str_sid("BA");
test_str_sid("BG");
test_str_sid("BO");
test_str_sid("BU");
test_str_sid("CA");
test_str_sid("CG");
test_str_sid("CO");
test_str_sid("DA");
test_str_sid("DC");
test_str_sid("DD");
test_str_sid("DG");
test_str_sid("DU");
test_str_sid("EA");
test_str_sid("ED");
test_str_sid("WD");
test_str_sid("PA");
test_str_sid("IU");
test_str_sid("LA");
test_str_sid("LG");
test_str_sid("LS");
test_str_sid("SY");
test_str_sid("NU");
test_str_sid("NO");
test_str_sid("NS");
test_str_sid("PO");
test_str_sid("PS");
test_str_sid("PU");
test_str_sid("RS");
test_str_sid("RD");
test_str_sid("RE");
test_str_sid("RC");
test_str_sid("SA");
test_str_sid("SO");
test_str_sid("SU");
/* string constant format not supported before XP */
r = pConvertStringSidToSidA(strsid_table[0].str, &psid);
if(!r)
{
win_skip("String constant format not supported\n");
return;
}
LocalFree(psid);
for(i = 0; i < sizeof(strsid_table) / sizeof(strsid_table[0]); i++)
{
char *temp;
SetLastError(0xdeadbeef);
r = pConvertStringSidToSidA(strsid_table[i].str, &psid);
if (!(strsid_table[i].flags & STRSID_OPT))
{
ok(r, "%s: got %u\n", strsid_table[i].str, GetLastError());
}
if (r)
{
if ((winetest_debug > 1) && (pConvertSidToStringSidA(psid, &temp)))
{
trace(" %s: %s\n", strsid_table[i].str, temp);
LocalFree(temp);
}
LocalFree(psid);
}
else
{
if (GetLastError() != ERROR_INVALID_SID)
trace(" %s: couldn't be converted, returned %d\n", strsid_table[i].str, GetLastError());
else
trace(" %s: couldn't be converted\n", strsid_table[i].str);
}
}
}
static void test_trustee(void)
@ -1455,9 +1469,11 @@ static void test_token_attr(void)
Size = 0;
ret = GetTokenInformation(Token, TokenGroups, Groups, Size2, &Size);
ok(Size > 1, "got %d\n", Size);
ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
ok((!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER) || broken(ret) /* wow64 */,
"%d with error %d\n", ret, GetLastError());
ok(*((BYTE*)Groups) == 0xcc, "buffer altered\n");
if(!ret)
ok(*((BYTE*)Groups) == 0xcc, "buffer altered\n");
HeapFree(GetProcessHeap(), 0, Groups);
SetLastError(0xdeadbeef);
@ -1646,7 +1662,8 @@ static const struct well_known_sid_value
/* 66 */ {TRUE, "S-1-16-4096"}, {TRUE, "S-1-16-8192"}, {TRUE, "S-1-16-12288"},
/* 69 */ {TRUE, "S-1-16-16384"}, {TRUE, "S-1-5-33"}, {TRUE, "S-1-3-4"},
/* 72 */ {FALSE, "S-1-5-21-12-23-34-45-56-571"}, {FALSE, "S-1-5-21-12-23-34-45-56-572"},
/* 74 */ {TRUE, "S-1-5-22"}, {FALSE, "S-1-5-21-12-23-34-45-56-521"}, {TRUE, "S-1-5-32-573"}
/* 74 */ {TRUE, "S-1-5-22"}, {FALSE, "S-1-5-21-12-23-34-45-56-521"}, {TRUE, "S-1-5-32-573"},
/* 77 */ {FALSE, "S-1-5-21-12-23-34-45-56-498"}, {TRUE, "S-1-5-32-574"}, {TRUE, "S-1-16-8448"}
};
static void test_CreateWellKnownSid(void)
@ -1711,7 +1728,7 @@ static void test_CreateWellKnownSid(void)
expect_eq(GetSidLengthRequired(*GetSidSubAuthorityCount(sid_buffer)), cb, DWORD, "%d");
ok(IsValidSid(sid_buffer), "The sid is not valid\n");
ok(pConvertSidToStringSidA(sid_buffer, &str), "Couldn't convert SID to string\n");
ok(strcmp(str, value->sid_string) == 0, "SID mismatch - expected %s, got %s\n",
ok(strcmp(str, value->sid_string) == 0, "%d: SID mismatch - expected %s, got %s\n", i,
value->sid_string, str);
LocalFree(str);
@ -2420,15 +2437,15 @@ static void test_granted_access(HANDLE handle, ACCESS_MASK access,
#define CHECK_SET_SECURITY(o,i,e) \
do{ \
BOOL res; \
BOOL res_; \
DWORD err; \
SetLastError( 0xdeadbeef ); \
res = SetKernelObjectSecurity( o, i, SecurityDescriptor ); \
res_ = SetKernelObjectSecurity( o, i, SecurityDescriptor ); \
err = GetLastError(); \
if (e == ERROR_SUCCESS) \
ok(res, "SetKernelObjectSecurity failed with %d\n", err); \
ok(res_, "SetKernelObjectSecurity failed with %d\n", err); \
else \
ok(!res && err == e, "SetKernelObjectSecurity should have failed " \
ok(!res_ && err == e, "SetKernelObjectSecurity should have failed " \
"with %s, instead of %d\n", #e, err); \
}while(0)
@ -2543,7 +2560,7 @@ static void test_process_security(void)
/* Doesn't matter what ACL say we should get full access for ourselves */
res = CreateProcessA( NULL, buffer, &psa, NULL, FALSE, 0, NULL, NULL, &startup, &info );
ok(res, "CreateProcess with err:%d\n", GetLastError());
TEST_GRANTED_ACCESS2( info.hProcess, PROCESS_ALL_ACCESS,
TEST_GRANTED_ACCESS2( info.hProcess, PROCESS_ALL_ACCESS_NT4,
STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL );
winetest_wait_child_process( info.hProcess );
@ -2595,7 +2612,7 @@ static void test_process_security_child(void)
ret = DuplicateHandle( GetCurrentProcess(), GetCurrentProcess(), GetCurrentProcess(),
&handle, 0, TRUE, DUPLICATE_SAME_ACCESS );
ok(ret, "duplicating handle err:%d\n", GetLastError());
TEST_GRANTED_ACCESS2( handle, PROCESS_ALL_ACCESS,
TEST_GRANTED_ACCESS2( handle, PROCESS_ALL_ACCESS_NT4,
STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL );
CloseHandle( handle );
@ -2604,7 +2621,7 @@ static void test_process_security_child(void)
ret = DuplicateHandle( GetCurrentProcess(), GetCurrentProcess(), GetCurrentProcess(),
&handle, PROCESS_ALL_ACCESS, TRUE, 0 );
ok(ret, "duplicating handle err:%d\n", GetLastError());
TEST_GRANTED_ACCESS2( handle, PROCESS_ALL_ACCESS,
TEST_GRANTED_ACCESS2( handle, PROCESS_ALL_ACCESS_NT4,
PROCESS_ALL_ACCESS | PROCESS_QUERY_LIMITED_INFORMATION );
ret = DuplicateHandle( GetCurrentProcess(), handle, GetCurrentProcess(),
&handle1, PROCESS_VM_READ, TRUE, 0 );
@ -2990,40 +3007,67 @@ static void test_SetEntriesInAclA(void)
static void test_GetNamedSecurityInfoA(void)
{
PSECURITY_DESCRIPTOR pSecDesc;
DWORD revision;
char admin_ptr[sizeof(SID)+sizeof(ULONG)*SID_MAX_SUB_AUTHORITIES], dacl[100], *user;
DWORD sid_size = sizeof(admin_ptr), user_size;
char invalid_path[] = "/an invalid file path";
PSID admin_sid = (PSID) admin_ptr, user_sid;
char sd[SECURITY_DESCRIPTOR_MIN_LENGTH];
SECURITY_DESCRIPTOR_CONTROL control;
PSID owner;
PSID group;
PACL dacl;
ACL_SIZE_INFORMATION acl_size;
CHAR windows_dir[MAX_PATH];
PSECURITY_DESCRIPTOR pSD;
ACCESS_ALLOWED_ACE *ace;
BOOL bret = TRUE, isNT4;
char tmpfile[MAX_PATH];
DWORD error, revision;
BOOL owner_defaulted;
BOOL group_defaulted;
DWORD error;
BOOL ret, isNT4;
CHAR windows_dir[MAX_PATH];
HANDLE token, hTemp;
PSID owner, group;
PACL pDacl;
if (!pGetNamedSecurityInfoA)
if (!pSetNamedSecurityInfoA || !pGetNamedSecurityInfoA || !pCreateWellKnownSid)
{
win_skip("GetNamedSecurityInfoA is not available\n");
win_skip("Required functions are not available\n");
return;
}
ret = GetWindowsDirectoryA(windows_dir, MAX_PATH);
ok(ret, "GetWindowsDirectory failed with error %d\n", GetLastError());
if (!OpenThreadToken(GetCurrentThread(), TOKEN_READ, TRUE, &token))
{
if (GetLastError() != ERROR_NO_TOKEN) bret = FALSE;
else if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token)) bret = FALSE;
}
if (!bret)
{
win_skip("Failed to get current user token\n");
return;
}
bret = GetTokenInformation(token, TokenUser, NULL, 0, &user_size);
ok(!bret && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
"GetTokenInformation(TokenUser) failed with error %d\n", GetLastError());
user = HeapAlloc(GetProcessHeap(), 0, user_size);
bret = GetTokenInformation(token, TokenUser, user, user_size, &user_size);
ok(bret, "GetTokenInformation(TokenUser) failed with error %d\n", GetLastError());
CloseHandle( token );
user_sid = ((TOKEN_USER *)user)->User.Sid;
bret = GetWindowsDirectoryA(windows_dir, MAX_PATH);
ok(bret, "GetWindowsDirectory failed with error %d\n", GetLastError());
SetLastError(0xdeadbeef);
error = pGetNamedSecurityInfoA(windows_dir, SE_FILE_OBJECT,
OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION,
NULL, NULL, NULL, NULL, &pSecDesc);
NULL, NULL, NULL, NULL, &pSD);
if (error != ERROR_SUCCESS && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
{
win_skip("GetNamedSecurityInfoA is not implemented\n");
HeapFree(GetProcessHeap(), 0, user);
return;
}
ok(!error, "GetNamedSecurityInfo failed with error %d\n", error);
ret = GetSecurityDescriptorControl(pSecDesc, &control, &revision);
ok(ret, "GetSecurityDescriptorControl failed with error %d\n", GetLastError());
bret = GetSecurityDescriptorControl(pSD, &control, &revision);
ok(bret, "GetSecurityDescriptorControl failed with error %d\n", GetLastError());
ok((control & (SE_SELF_RELATIVE|SE_DACL_PRESENT)) == (SE_SELF_RELATIVE|SE_DACL_PRESENT) ||
broken((control & (SE_SELF_RELATIVE|SE_DACL_PRESENT)) == SE_DACL_PRESENT), /* NT4 */
"control (0x%x) doesn't have (SE_SELF_RELATIVE|SE_DACL_PRESENT) flags set\n", control);
@ -3031,20 +3075,21 @@ static void test_GetNamedSecurityInfoA(void)
isNT4 = (control & (SE_SELF_RELATIVE|SE_DACL_PRESENT)) == SE_DACL_PRESENT;
ret = GetSecurityDescriptorOwner(pSecDesc, &owner, &owner_defaulted);
ok(ret, "GetSecurityDescriptorOwner failed with error %d\n", GetLastError());
bret = GetSecurityDescriptorOwner(pSD, &owner, &owner_defaulted);
ok(bret, "GetSecurityDescriptorOwner failed with error %d\n", GetLastError());
ok(owner != NULL, "owner should not be NULL\n");
ret = GetSecurityDescriptorGroup(pSecDesc, &group, &group_defaulted);
ok(ret, "GetSecurityDescriptorGroup failed with error %d\n", GetLastError());
bret = GetSecurityDescriptorGroup(pSD, &group, &group_defaulted);
ok(bret, "GetSecurityDescriptorGroup failed with error %d\n", GetLastError());
ok(group != NULL, "group should not be NULL\n");
LocalFree(pSecDesc);
LocalFree(pSD);
/* NULL descriptor tests */
if(isNT4)
{
win_skip("NT4 does not support GetNamedSecutityInfo with a NULL descriptor\n");
HeapFree(GetProcessHeap(), 0, user);
return;
}
@ -3053,13 +3098,85 @@ static void test_GetNamedSecurityInfoA(void)
ok(error==ERROR_INVALID_PARAMETER, "GetNamedSecurityInfo failed with error %d\n", error);
error = pGetNamedSecurityInfoA(windows_dir, SE_FILE_OBJECT,DACL_SECURITY_INFORMATION,
NULL, NULL, &dacl, NULL, NULL);
NULL, NULL, &pDacl, NULL, NULL);
ok(!error, "GetNamedSecurityInfo failed with error %d\n", error);
ok(dacl != NULL, "dacl should not be NULL\n");
ok(pDacl != NULL, "DACL should not be NULL\n");
error = pGetNamedSecurityInfoA(windows_dir, SE_FILE_OBJECT,OWNER_SECURITY_INFORMATION,
NULL, NULL, &dacl, NULL, NULL);
NULL, NULL, &pDacl, NULL, NULL);
ok(error==ERROR_INVALID_PARAMETER, "GetNamedSecurityInfo failed with error %d\n", error);
/* Test behavior of SetNamedSecurityInfo with an invalid path */
SetLastError(0xdeadbeef);
error = pSetNamedSecurityInfoA(invalid_path, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL,
NULL, NULL, NULL);
ok(error == ERROR_FILE_NOT_FOUND, "Unexpected error returned: 0x%x\n", error);
ok(GetLastError() == 0xdeadbeef, "Expected last error to remain unchanged.\n");
/* Create security descriptor information and test that it comes back the same */
pSD = &sd;
pDacl = (PACL)&dacl;
InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
pCreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, admin_sid, &sid_size);
bret = InitializeAcl(pDacl, sizeof(dacl), ACL_REVISION);
ok(bret, "Failed to initialize ACL.\n");
bret = pAddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid);
HeapFree(GetProcessHeap(), 0, user);
ok(bret, "Failed to add Current User to ACL.\n");
bret = pAddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, admin_sid);
ok(bret, "Failed to add Administrator Group to ACL.\n");
bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE);
ok(bret, "Failed to add ACL to security desciptor.\n");
GetTempFileNameA(".", "foo", 0, tmpfile);
hTemp = CreateFileA(tmpfile, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING,
FILE_FLAG_DELETE_ON_CLOSE, NULL);
SetLastError(0xdeadbeef);
error = pSetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL,
NULL, pDacl, NULL);
if (error != ERROR_SUCCESS && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
{
win_skip("SetNamedSecurityInfoA is not implemented\n");
CloseHandle(hTemp);
return;
}
ok(!error, "SetNamedSecurityInfoA failed with error %d\n", error);
SetLastError(0xdeadbeef);
error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
NULL, NULL, &pDacl, NULL, &pSD);
if (error != ERROR_SUCCESS && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
{
win_skip("GetNamedSecurityInfoA is not implemented\n");
return;
}
ok(!error, "GetNamedSecurityInfo failed with error %d\n", error);
bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
ok(bret, "GetAclInformation failed\n");
if (acl_size.AceCount > 0)
{
bret = pGetAce(pDacl, 0, (VOID **)&ace);
ok(bret, "Failed to get Current User ACE.\n");
bret = EqualSid(&ace->SidStart, user_sid);
todo_wine ok(bret, "Current User ACE != Current User SID.\n");
ok(((ACE_HEADER *)ace)->AceFlags == 0,
"Current User ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags);
ok(ace->Mask == 0x1f01ff, "Current User ACE has unexpected mask (0x%x != 0x1f01ff)\n",
ace->Mask);
}
if (acl_size.AceCount > 1)
{
bret = pGetAce(pDacl, 1, (VOID **)&ace);
ok(bret, "Failed to get Administators Group ACE.\n");
bret = EqualSid(&ace->SidStart, admin_sid);
todo_wine ok(bret || broken(!bret) /* win2k */,
"Administators Group ACE != Administators Group SID.\n");
ok(((ACE_HEADER *)ace)->AceFlags == 0,
"Administators Group ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags);
ok(ace->Mask == 0x1f01ff || broken(ace->Mask == GENERIC_ALL) /* win2k */,
"Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n", ace->Mask);
}
LocalFree(pSD);
CloseHandle(hTemp);
}
static void test_ConvertStringSecurityDescriptor(void)
@ -3523,20 +3640,42 @@ static void test_acls(void)
static void test_GetSecurityInfo(void)
{
HANDLE obj;
PSECURITY_DESCRIPTOR sd;
char b[sizeof(TOKEN_USER) + sizeof(SID) + sizeof(DWORD)*SID_MAX_SUB_AUTHORITIES];
char admin_ptr[sizeof(SID)+sizeof(ULONG)*SID_MAX_SUB_AUTHORITIES], dacl[100];
DWORD sid_size = sizeof(admin_ptr), l = sizeof(b);
PSID admin_sid = (PSID) admin_ptr, user_sid;
char sd[SECURITY_DESCRIPTOR_MIN_LENGTH];
ACL_SIZE_INFORMATION acl_size;
PSECURITY_DESCRIPTOR pSD;
ACCESS_ALLOWED_ACE *ace;
HANDLE token, obj;
PSID owner, group;
PACL dacl;
BOOL bret = TRUE;
PACL pDacl;
DWORD ret;
if (!pGetSecurityInfo)
if (!pGetSecurityInfo || !pSetSecurityInfo)
{
win_skip("GetSecurityInfo is not available\n");
win_skip("[Get|Set]SecurityInfo is not available\n");
return;
}
if (!OpenThreadToken(GetCurrentThread(), TOKEN_READ, TRUE, &token))
{
if (GetLastError() != ERROR_NO_TOKEN) bret = FALSE;
else if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token)) bret = FALSE;
}
if (!bret)
{
win_skip("Failed to get current user token\n");
return;
}
GetTokenInformation(token, TokenUser, b, l, &l);
CloseHandle( token );
user_sid = ((TOKEN_USER *)b)->User.Sid;
/* Create something. Files have lots of associated security info. */
obj = CreateFile(myARGV[0], GENERIC_READ, FILE_SHARE_READ, NULL,
obj = CreateFile(myARGV[0], GENERIC_READ|WRITE_DAC, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (obj == INVALID_HANDLE_VALUE)
{
@ -3546,7 +3685,7 @@ static void test_GetSecurityInfo(void)
ret = pGetSecurityInfo(obj, SE_FILE_OBJECT,
OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
&owner, &group, &dacl, NULL, &sd);
&owner, &group, &pDacl, NULL, &pSD);
if (ret == ERROR_CALL_NOT_IMPLEMENTED)
{
win_skip("GetSecurityInfo is not implemented\n");
@ -3554,15 +3693,15 @@ static void test_GetSecurityInfo(void)
return;
}
ok(ret == ERROR_SUCCESS, "GetSecurityInfo returned %d\n", ret);
ok(sd != NULL, "GetSecurityInfo\n");
ok(pSD != NULL, "GetSecurityInfo\n");
ok(owner != NULL, "GetSecurityInfo\n");
ok(group != NULL, "GetSecurityInfo\n");
if (dacl != NULL)
ok(IsValidAcl(dacl), "GetSecurityInfo\n");
if (pDacl != NULL)
ok(IsValidAcl(pDacl), "GetSecurityInfo\n");
else
win_skip("No ACL information returned\n");
LocalFree(sd);
LocalFree(pSD);
if (!pCreateWellKnownSid)
{
@ -3575,15 +3714,59 @@ static void test_GetSecurityInfo(void)
the other stuff, leaving us no way to free it. */
ret = pGetSecurityInfo(obj, SE_FILE_OBJECT,
OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
&owner, &group, &dacl, NULL, NULL);
&owner, &group, &pDacl, NULL, NULL);
ok(ret == ERROR_SUCCESS, "GetSecurityInfo returned %d\n", ret);
ok(owner != NULL, "GetSecurityInfo\n");
ok(group != NULL, "GetSecurityInfo\n");
if (dacl != NULL)
ok(IsValidAcl(dacl), "GetSecurityInfo\n");
if (pDacl != NULL)
ok(IsValidAcl(pDacl), "GetSecurityInfo\n");
else
win_skip("No ACL information returned\n");
/* Create security descriptor information and test that it comes back the same */
pSD = &sd;
pDacl = (PACL)&dacl;
InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
pCreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, admin_sid, &sid_size);
bret = InitializeAcl(pDacl, sizeof(dacl), ACL_REVISION);
ok(bret, "Failed to initialize ACL.\n");
bret = pAddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid);
ok(bret, "Failed to add Current User to ACL.\n");
bret = pAddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, admin_sid);
ok(bret, "Failed to add Administrator Group to ACL.\n");
bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE);
ok(bret, "Failed to add ACL to security desciptor.\n");
ret = pSetSecurityInfo(obj, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
NULL, NULL, pDacl, NULL);
ok(ret == ERROR_SUCCESS, "SetSecurityInfo returned %d\n", ret);
ret = pGetSecurityInfo(obj, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
NULL, NULL, &pDacl, NULL, NULL);
ok(ret == ERROR_SUCCESS, "GetSecurityInfo returned %d\n", ret);
ok(pDacl && IsValidAcl(pDacl), "GetSecurityInfo returned invalid DACL.\n");
bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
ok(bret, "GetAclInformation failed\n");
if (acl_size.AceCount > 0)
{
bret = pGetAce(pDacl, 0, (VOID **)&ace);
ok(bret, "Failed to get Current User ACE.\n");
bret = EqualSid(&ace->SidStart, user_sid);
todo_wine ok(bret, "Current User ACE != Current User SID.\n");
ok(((ACE_HEADER *)ace)->AceFlags == 0,
"Current User ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags);
ok(ace->Mask == 0x1f01ff, "Current User ACE has unexpected mask (0x%x != 0x1f01ff)\n",
ace->Mask);
}
if (acl_size.AceCount > 1)
{
bret = pGetAce(pDacl, 1, (VOID **)&ace);
ok(bret, "Failed to get Administators Group ACE.\n");
bret = EqualSid(&ace->SidStart, admin_sid);
todo_wine ok(bret, "Administators Group ACE != Administators Group SID.\n");
ok(((ACE_HEADER *)ace)->AceFlags == 0,
"Administators Group ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags);
ok(ace->Mask == 0x1f01ff, "Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n",
ace->Mask);
}
CloseHandle(obj);
}
@ -3981,6 +4164,339 @@ static void test_CreateRestrictedToken(void)
CloseHandle(process_token);
}
static void validate_default_security_descriptor(SECURITY_DESCRIPTOR *sd)
{
BOOL ret, present, defaulted;
ACL *acl;
void *sid;
ret = IsValidSecurityDescriptor(sd);
ok(ret, "security descriptor is not valid\n");
present = -1;
defaulted = -1;
acl = (void *)0xdeadbeef;
SetLastError(0xdeadbeef);
ret = GetSecurityDescriptorDacl(sd, &present, &acl, &defaulted);
ok(ret, "GetSecurityDescriptorDacl error %d\n", GetLastError());
todo_wine
ok(present == 1, "acl is not present\n");
todo_wine
ok(acl != (void *)0xdeadbeef && acl != NULL, "acl pointer is not set\n");
ok(defaulted == 0, "defaulted is set to TRUE\n");
defaulted = -1;
sid = (void *)0xdeadbeef;
SetLastError(0xdeadbeef);
ret = GetSecurityDescriptorOwner(sd, &sid, &defaulted);
ok(ret, "GetSecurityDescriptorOwner error %d\n", GetLastError());
todo_wine
ok(sid != (void *)0xdeadbeef && sid != NULL, "sid pointer is not set\n");
ok(defaulted == 0, "defaulted is set to TRUE\n");
defaulted = -1;
sid = (void *)0xdeadbeef;
SetLastError(0xdeadbeef);
ret = GetSecurityDescriptorGroup(sd, &sid, &defaulted);
ok(ret, "GetSecurityDescriptorGroup error %d\n", GetLastError());
todo_wine
ok(sid != (void *)0xdeadbeef && sid != NULL, "sid pointer is not set\n");
ok(defaulted == 0, "defaulted is set to TRUE\n");
}
static void test_default_handle_security(HANDLE token, HANDLE handle, GENERIC_MAPPING *mapping)
{
DWORD ret, length, needed, granted, priv_set_len;
BOOL status;
PRIVILEGE_SET priv_set;
SECURITY_DESCRIPTOR *sd;
needed = 0xdeadbeef;
SetLastError(0xdeadbeef);
ret = GetKernelObjectSecurity(handle, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
NULL, 0, &needed);
ok(!ret, "GetKernelObjectSecurity should fail\n");
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
ok(needed != 0xdeadbeef, "GetKernelObjectSecurity should return required buffer length\n");
length = needed;
sd = HeapAlloc(GetProcessHeap(), 0, length);
needed = 0xdeadbeef;
SetLastError(0xdeadbeef);
ret = GetKernelObjectSecurity(handle, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
sd, length, &needed);
ok(ret, "GetKernelObjectSecurity error %d\n", GetLastError());
ok(needed == length || needed == 0 /* file, pipe */, "GetKernelObjectSecurity should return %u instead of %u\n", length, needed);
validate_default_security_descriptor(sd);
priv_set_len = sizeof(priv_set);
granted = 0xdeadbeef;
status = 0xdeadbeef;
SetLastError(0xdeadbeef);
ret = AccessCheck(sd, token, MAXIMUM_ALLOWED, mapping, &priv_set, &priv_set_len, &granted, &status);
todo_wine {
ok(ret, "AccessCheck error %d\n", GetLastError());
ok(status == 1, "expected 1, got %d\n", status);
ok(granted == mapping->GenericAll, "expected all access %#x, got %#x\n", mapping->GenericAll, granted);
}
priv_set_len = sizeof(priv_set);
granted = 0xdeadbeef;
status = 0xdeadbeef;
SetLastError(0xdeadbeef);
ret = AccessCheck(sd, token, 0, mapping, &priv_set, &priv_set_len, &granted, &status);
todo_wine {
ok(ret, "AccessCheck error %d\n", GetLastError());
ok(status == 0 || broken(status == 1) /* NT4 */, "expected 0, got %d\n", status);
ok(granted == 0 || broken(granted == mapping->GenericRead) /* NT4 */, "expected 0, got %#x\n", granted);
}
priv_set_len = sizeof(priv_set);
granted = 0xdeadbeef;
status = 0xdeadbeef;
SetLastError(0xdeadbeef);
ret = AccessCheck(sd, token, ACCESS_SYSTEM_SECURITY, mapping, &priv_set, &priv_set_len, &granted, &status);
todo_wine {
ok(ret, "AccessCheck error %d\n", GetLastError());
ok(status == 0, "expected 0, got %d\n", status);
ok(granted == 0, "expected 0, got %#x\n", granted);
}
priv_set_len = sizeof(priv_set);
granted = 0xdeadbeef;
status = 0xdeadbeef;
SetLastError(0xdeadbeef);
ret = AccessCheck(sd, token, mapping->GenericRead, mapping, &priv_set, &priv_set_len, &granted, &status);
todo_wine {
ok(ret, "AccessCheck error %d\n", GetLastError());
ok(status == 1, "expected 1, got %d\n", status);
ok(granted == mapping->GenericRead, "expected read access %#x, got %#x\n", mapping->GenericRead, granted);
}
priv_set_len = sizeof(priv_set);
granted = 0xdeadbeef;
status = 0xdeadbeef;
SetLastError(0xdeadbeef);
ret = AccessCheck(sd, token, mapping->GenericWrite, mapping, &priv_set, &priv_set_len, &granted, &status);
todo_wine {
ok(ret, "AccessCheck error %d\n", GetLastError());
ok(status == 1, "expected 1, got %d\n", status);
ok(granted == mapping->GenericWrite, "expected write access %#x, got %#x\n", mapping->GenericWrite, granted);
}
priv_set_len = sizeof(priv_set);
granted = 0xdeadbeef;
status = 0xdeadbeef;
SetLastError(0xdeadbeef);
ret = AccessCheck(sd, token, mapping->GenericExecute, mapping, &priv_set, &priv_set_len, &granted, &status);
todo_wine {
ok(ret, "AccessCheck error %d\n", GetLastError());
ok(status == 1, "expected 1, got %d\n", status);
ok(granted == mapping->GenericExecute, "expected execute access %#x, got %#x\n", mapping->GenericExecute, granted);
}
HeapFree(GetProcessHeap(), 0, sd);
}
static void test_mutex_security(HANDLE token)
{
HANDLE mutex;
GENERIC_MAPPING mapping = { STANDARD_RIGHTS_READ | MUTANT_QUERY_STATE | SYNCHRONIZE,
STANDARD_RIGHTS_WRITE | MUTEX_MODIFY_STATE | SYNCHRONIZE,
STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE,
STANDARD_RIGHTS_ALL | MUTEX_ALL_ACCESS };
SetLastError(0xdeadbeef);
mutex = OpenMutex(0, FALSE, "WineTestMutex");
ok(!mutex, "mutex should not exist\n");
ok(GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError());
SetLastError(0xdeadbeef);
mutex = CreateMutex(NULL, FALSE, "WineTestMutex");
ok(mutex != 0, "CreateMutex error %d\n", GetLastError());
test_default_handle_security(token, mutex, &mapping);
CloseHandle (mutex);
}
static void test_event_security(HANDLE token)
{
HANDLE event;
GENERIC_MAPPING mapping = { STANDARD_RIGHTS_READ | EVENT_QUERY_STATE | SYNCHRONIZE,
STANDARD_RIGHTS_WRITE | EVENT_MODIFY_STATE | SYNCHRONIZE,
STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE,
STANDARD_RIGHTS_ALL | EVENT_ALL_ACCESS };
SetLastError(0xdeadbeef);
event = OpenEvent(0, FALSE, "WineTestEvent");
ok(!event, "event should not exist\n");
ok(GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError());
SetLastError(0xdeadbeef);
event = CreateEvent(NULL, FALSE, FALSE, "WineTestEvent");
ok(event != 0, "CreateEvent error %d\n", GetLastError());
test_default_handle_security(token, event, &mapping);
CloseHandle(event);
}
#define WINE_TEST_PIPE "\\\\.\\pipe\\WineTestPipe"
static void test_named_pipe_security(HANDLE token)
{
HANDLE pipe, file;
GENERIC_MAPPING mapping = { FILE_GENERIC_READ,
FILE_GENERIC_WRITE,
FILE_GENERIC_EXECUTE,
STANDARD_RIGHTS_ALL | FILE_ALL_ACCESS };
SetLastError(0xdeadbeef);
pipe = CreateNamedPipe(WINE_TEST_PIPE, PIPE_ACCESS_DUPLEX | FILE_FLAG_FIRST_PIPE_INSTANCE,
PIPE_TYPE_BYTE | PIPE_NOWAIT, PIPE_UNLIMITED_INSTANCES,
0, 0, NMPWAIT_USE_DEFAULT_WAIT, NULL);
ok(pipe != INVALID_HANDLE_VALUE, "CreateNamedPipe error %d\n", GetLastError());
test_default_handle_security(token, pipe, &mapping);
SetLastError(0xdeadbeef);
file = CreateFile(WINE_TEST_PIPE, FILE_ALL_ACCESS, 0, NULL, OPEN_EXISTING, 0, 0);
ok(file != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError());
CloseHandle(file);
CloseHandle(pipe);
SetLastError(0xdeadbeef);
file = CreateFile("\\\\.\\pipe\\", FILE_ALL_ACCESS, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
ok(file != INVALID_HANDLE_VALUE || broken(file == INVALID_HANDLE_VALUE) /* before Vista */, "CreateFile error %d\n", GetLastError());
CloseHandle(file);
}
static BOOL validate_impersonation_token(HANDLE token, DWORD *token_type)
{
DWORD ret, needed;
TOKEN_TYPE type;
SECURITY_IMPERSONATION_LEVEL sil;
type = 0xdeadbeef;
needed = 0;
SetLastError(0xdeadbeef);
ret = GetTokenInformation(token, TokenType, &type, sizeof(type), &needed);
ok(ret, "GetTokenInformation error %d\n", GetLastError());
ok(needed == sizeof(type), "GetTokenInformation should return required buffer length\n");
ok(type == TokenPrimary || type == TokenImpersonation, "expected TokenPrimary or TokenImpersonation, got %d\n", type);
*token_type = type;
if (type != TokenImpersonation) return FALSE;
needed = 0;
SetLastError(0xdeadbeef);
ret = GetTokenInformation(token, TokenImpersonationLevel, &sil, sizeof(sil), &needed);
ok(ret, "GetTokenInformation error %d\n", GetLastError());
ok(needed == sizeof(sil), "GetTokenInformation should return required buffer length\n");
ok(sil == SecurityImpersonation, "expected SecurityImpersonation, got %d\n", sil);
needed = 0xdeadbeef;
SetLastError(0xdeadbeef);
ret = GetTokenInformation(token, TokenDefaultDacl, NULL, 0, &needed);
ok(!ret, "GetTokenInformation should fail\n");
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
ok(needed != 0xdeadbeef, "GetTokenInformation should return required buffer length\n");
ok(needed > sizeof(TOKEN_DEFAULT_DACL), "GetTokenInformation returned empty default DACL\n");
needed = 0xdeadbeef;
SetLastError(0xdeadbeef);
ret = GetTokenInformation(token, TokenOwner, NULL, 0, &needed);
ok(!ret, "GetTokenInformation should fail\n");
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
ok(needed != 0xdeadbeef, "GetTokenInformation should return required buffer length\n");
ok(needed > sizeof(TOKEN_OWNER), "GetTokenInformation returned empty token owner\n");
needed = 0xdeadbeef;
SetLastError(0xdeadbeef);
ret = GetTokenInformation(token, TokenPrimaryGroup, NULL, 0, &needed);
ok(!ret, "GetTokenInformation should fail\n");
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
ok(needed != 0xdeadbeef, "GetTokenInformation should return required buffer length\n");
ok(needed > sizeof(TOKEN_PRIMARY_GROUP), "GetTokenInformation returned empty token primary group\n");
return TRUE;
}
static void test_kernel_objects_security(void)
{
HANDLE token, process_token;
DWORD ret, token_type;
ret = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE | TOKEN_QUERY, &process_token);
ok(ret, "OpenProcessToken error %d\n", GetLastError());
ret = validate_impersonation_token(process_token, &token_type);
ok(token_type == TokenPrimary, "expected TokenPrimary, got %d\n", token_type);
ok(!ret, "access token should not be an impersonation token\n");
ret = DuplicateToken(process_token, SecurityImpersonation, &token);
ok(ret, "DuplicateToken error %d\n", GetLastError());
ret = validate_impersonation_token(token, &token_type);
ok(ret, "access token should be a valid impersonation token\n");
ok(token_type == TokenImpersonation, "expected TokenImpersonation, got %d\n", token_type);
test_mutex_security(token);
test_event_security(token);
test_named_pipe_security(token);
/* FIXME: test other kernel object types */
CloseHandle(process_token);
CloseHandle(token);
}
static void test_TokenIntegrityLevel(void)
{
TOKEN_MANDATORY_LABEL *tml;
BYTE buffer[64]; /* using max. 28 byte in win7 x64 */
HANDLE token;
DWORD size;
DWORD res;
char *sidname = NULL;
static SID medium_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY},
{SECURITY_MANDATORY_HIGH_RID}};
static SID high_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY},
{SECURITY_MANDATORY_MEDIUM_RID}};
SetLastError(0xdeadbeef);
res = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
ok(res, "got %d with %d (expected TRUE)\n", res, GetLastError());
SetLastError(0xdeadbeef);
res = GetTokenInformation(token, TokenIntegrityLevel, buffer, sizeof(buffer), &size);
/* not supported before Vista */
if (!res && ((GetLastError() == ERROR_INVALID_PARAMETER) || GetLastError() == ERROR_INVALID_FUNCTION))
{
win_skip("TokenIntegrityLevel not supported\n");
CloseHandle(token);
return;
}
ok(res, "got %u with %u (expected TRUE)\n", res, GetLastError());
if (!res)
{
CloseHandle(token);
return;
}
tml = (TOKEN_MANDATORY_LABEL*) buffer;
ok(tml->Label.Attributes == (SE_GROUP_INTEGRITY | SE_GROUP_INTEGRITY_ENABLED),
"got 0x%x (expected 0x%x)\n", tml->Label.Attributes, (SE_GROUP_INTEGRITY | SE_GROUP_INTEGRITY_ENABLED));
SetLastError(0xdeadbeef);
res = pConvertSidToStringSidA(tml->Label.Sid, &sidname);
ok(res, "got %u and %u\n", res, GetLastError());
ok(EqualSid(tml->Label.Sid, &medium_level) || EqualSid(tml->Label.Sid, &high_level),
"got %s (expected 'S-1-16-8192' or 'S-1-16-12288')\n", sidname);
LocalFree(sidname);
CloseHandle(token);
}
START_TEST(security)
{
init();
@ -3991,6 +4507,7 @@ START_TEST(security)
test_process_security_child();
return;
}
test_kernel_objects_security();
test_sid();
test_trustee();
test_luid();
@ -4017,4 +4534,5 @@ START_TEST(security)
test_GetUserNameA();
test_GetUserNameW();
test_CreateRestrictedToken();
test_TokenIntegrityLevel();
}

View file

@ -1896,6 +1896,7 @@ static void test_queryconfig2(void)
DWORD expected, needed;
BYTE buffer[MAX_PATH];
LPSERVICE_DESCRIPTIONA pConfig = (LPSERVICE_DESCRIPTIONA)buffer;
SERVICE_PRESHUTDOWN_INFO preshutdown_info;
static const CHAR servicename [] = "Winetest";
static const CHAR displayname [] = "Winetest dummy service";
static const CHAR pathname [] = "we_dont_care.exe";
@ -2062,6 +2063,33 @@ static void test_queryconfig2(void)
ret = pQueryServiceConfig2W(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer, needed,&needed);
ok(ret, "expected QueryServiceConfig2W to succeed\n");
SetLastError(0xdeadbeef);
ret = pQueryServiceConfig2W(svc_handle, SERVICE_CONFIG_PRESHUTDOWN_INFO,
(LPBYTE)&preshutdown_info, sizeof(preshutdown_info), &needed);
if(!ret && GetLastError()==ERROR_INVALID_LEVEL)
{
/* Win2k3 and older */
win_skip("SERVICE_CONFIG_PRESHUTDOWN_INFO not supported\n");
goto cleanup;
}
ok(ret, "expected QueryServiceConfig2W to succeed (%d)\n", GetLastError());
ok(needed == sizeof(preshutdown_info), "needed = %d\n", needed);
ok(preshutdown_info.dwPreshutdownTimeout == 180000, "Default PreshutdownTimeout = %d\n",
preshutdown_info.dwPreshutdownTimeout);
SetLastError(0xdeadbeef);
preshutdown_info.dwPreshutdownTimeout = -1;
ret = pChangeServiceConfig2A(svc_handle, SERVICE_CONFIG_PRESHUTDOWN_INFO,
(LPVOID)&preshutdown_info);
ok(ret, "expected ChangeServiceConfig2A to succeed (%d)\n", GetLastError());
ret = pQueryServiceConfig2W(svc_handle, SERVICE_CONFIG_PRESHUTDOWN_INFO,
(LPBYTE)&preshutdown_info, sizeof(preshutdown_info), &needed);
ok(ret, "expected QueryServiceConfig2W to succeed (%d)\n", GetLastError());
ok(needed == sizeof(preshutdown_info), "needed = %d\n", needed);
ok(preshutdown_info.dwPreshutdownTimeout == -1, "New PreshutdownTimeout = %d\n",
preshutdown_info.dwPreshutdownTimeout);
cleanup:
DeleteService(svc_handle);
@ -2178,7 +2206,7 @@ static void test_start_stop(void)
if (!winetest_interactive)
{
skip("reactos bug 6646: Skipping service start timeout tests!\n");
skip("ROSTESTS-56: Skipping service start timeout tests!\n");
goto cleanup;
}