From 3bea619a9a0c1b847da8348ef7548becb51a2267 Mon Sep 17 00:00:00 2001 From: Steven Edwards Date: Tue, 16 Aug 2005 05:17:06 +0000 Subject: [PATCH] Changes to get msi based installers mostly working ConvertStringSecurityDescriptorToSecurityDescriptor[W/A] - implement based on Winehq code InitiateSystemShutdownExW - add stub from Wine Convert registry source file to use Wine debugging Macros svn path=/trunk/; revision=17410 --- reactos/lib/advapi32/advapi32.def | 6 +- reactos/lib/advapi32/advapi32.h | 1 + reactos/lib/advapi32/advapi32.xml | 1 + reactos/lib/advapi32/misc/shutdown.c | 16 + reactos/lib/advapi32/reg/reg.c | 102 ++-- reactos/lib/advapi32/sec/sid.c | 691 ++++++++++++++++++++++++++- 6 files changed, 759 insertions(+), 58 deletions(-) diff --git a/reactos/lib/advapi32/advapi32.def b/reactos/lib/advapi32/advapi32.def index fbaf991d14e..37c045c4ae3 100644 --- a/reactos/lib/advapi32/advapi32.def +++ b/reactos/lib/advapi32/advapi32.def @@ -91,8 +91,8 @@ ConvertSidToStringSidW@8 ;ConvertStringSDToSDDomainW@24 ;ConvertStringSDToSDRootDomainA@20 ;ConvertStringSDToSDRootDomainW@20 -;ConvertStringSecurityDescriptorToSecurityDescriptorA@20 -;ConvertStringSecurityDescriptorToSecurityDescriptorW@20 +ConvertStringSecurityDescriptorToSecurityDescriptorA@16 +ConvertStringSecurityDescriptorToSecurityDescriptorW@16 ;ConvertStringSidToSidA@8 ;ConvertStringSidToSidW@8 ConvertToAutoInheritPrivateObjectSecurity@24 @@ -315,7 +315,7 @@ InitializeSecurityDescriptor@8 InitializeSid@12 InitiateSystemShutdownA@20 ;InitiateSystemShutdownExA@24 -;InitiateSystemShutdownExW@24 +InitiateSystemShutdownExW@24 InitiateSystemShutdownW@20 ;InstallApplication IsTextUnicode@12=NTDLL.RtlIsTextUnicode diff --git a/reactos/lib/advapi32/advapi32.h b/reactos/lib/advapi32/advapi32.h index 9d7f3324d43..978d6f5626f 100644 --- a/reactos/lib/advapi32/advapi32.h +++ b/reactos/lib/advapi32/advapi32.h @@ -14,6 +14,7 @@ /* PSDK/NDK Headers */ #include #include +#include #define NTOS_MODE_USER #include diff --git a/reactos/lib/advapi32/advapi32.xml b/reactos/lib/advapi32/advapi32.xml index 68142a02c12..65f38ca005d 100644 --- a/reactos/lib/advapi32/advapi32.xml +++ b/reactos/lib/advapi32/advapi32.xml @@ -10,6 +10,7 @@ ntdll kernel32 rpcrt4 + wine advapi32.h crypt.c diff --git a/reactos/lib/advapi32/misc/shutdown.c b/reactos/lib/advapi32/misc/shutdown.c index b2c324c0bf8..7b5121461dd 100644 --- a/reactos/lib/advapi32/misc/shutdown.c +++ b/reactos/lib/advapi32/misc/shutdown.c @@ -11,6 +11,7 @@ */ #include +#include #define USZ {0,0,0} @@ -146,4 +147,19 @@ InitiateSystemShutdownA( return rv; } +/****************************************************************************** + * InitiateSystemShutdownExW [ADVAPI32.@] + * + * see InitiateSystemShutdownExA + */ +BOOL WINAPI InitiateSystemShutdownExW( LPWSTR lpMachineName, LPWSTR lpMessage, + DWORD dwTimeout, BOOL bForceAppsClosed, BOOL bRebootAfterShutdown, + DWORD dwReason) +{ + FIXME("%s %s %ld %d %d %ld\n", debugstr_w(lpMachineName), + debugstr_w(lpMessage), dwTimeout, bForceAppsClosed, + bRebootAfterShutdown, dwReason); + return TRUE; +} + /* EOF */ diff --git a/reactos/lib/advapi32/reg/reg.c b/reactos/lib/advapi32/reg/reg.c index 2073dd7f106..7aa9dbb8d42 100644 --- a/reactos/lib/advapi32/reg/reg.c +++ b/reactos/lib/advapi32/reg/reg.c @@ -15,7 +15,7 @@ #include #define NDEBUG -#include +#include /* DEFINES ******************************************************************/ @@ -56,7 +56,7 @@ inline static int is_string( DWORD type ) BOOL RegInitialize (VOID) { - DPRINT("RegInitialize()\n"); + TRACE("RegInitialize()\n"); ProcessHeap = RtlGetProcessHeap(); RtlZeroMemory (DefaultHandleTable, @@ -73,7 +73,7 @@ RegInitialize (VOID) BOOL RegCleanup (VOID) { - DPRINT("RegCleanup()\n"); + TRACE("RegCleanup()\n"); CloseDefaultKeys (); RtlDeleteCriticalSection (&HandleTableCS); @@ -90,7 +90,7 @@ MapDefaultKey (PHANDLE RealKey, ULONG Index; NTSTATUS Status = STATUS_SUCCESS; - DPRINT("MapDefaultKey (Key %x)\n", Key); + TRACE("MapDefaultKey (Key %x)\n", Key); if (((ULONG)Key & 0xF0000000) != 0x80000000) { @@ -142,7 +142,7 @@ MapDefaultKey (PHANDLE RealKey, break; default: - DPRINT("MapDefaultHandle() no handle creator\n"); + WARN("MapDefaultHandle() no handle creator\n"); Status = STATUS_INVALID_PARAMETER; } } @@ -181,7 +181,7 @@ OpenClassesRootKey (PHANDLE KeyHandle) OBJECT_ATTRIBUTES Attributes; UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\Software\\CLASSES"); - DPRINT("OpenClassesRootKey()\n"); + TRACE("OpenClassesRootKey()\n"); InitializeObjectAttributes (&Attributes, &KeyName, @@ -201,7 +201,7 @@ OpenLocalMachineKey (PHANDLE KeyHandle) UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine"); NTSTATUS Status; - DPRINT("OpenLocalMachineKey()\n"); + TRACE("OpenLocalMachineKey()\n"); InitializeObjectAttributes (&Attributes, &KeyName, @@ -212,7 +212,7 @@ OpenLocalMachineKey (PHANDLE KeyHandle) MAXIMUM_ALLOWED, &Attributes); - DPRINT("NtOpenKey(%wZ) => %08x\n", &KeyName, Status); + TRACE("NtOpenKey(%wZ) => %08x\n", &KeyName, Status); return Status; } @@ -223,7 +223,7 @@ OpenUsersKey (PHANDLE KeyHandle) OBJECT_ATTRIBUTES Attributes; UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\User"); - DPRINT("OpenUsersKey()\n"); + TRACE("OpenUsersKey()\n"); InitializeObjectAttributes (&Attributes, &KeyName, @@ -243,7 +243,7 @@ OpenCurrentConfigKey (PHANDLE KeyHandle) UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Hardware Profiles\\Current"); - DPRINT("OpenCurrentConfigKey()\n"); + TRACE("OpenCurrentConfigKey()\n"); InitializeObjectAttributes (&Attributes, &KeyName, @@ -341,7 +341,7 @@ CreateNestedKey(PHKEY KeyHandle, ClassString, dwOptions, (PULONG)lpdwDisposition); - DPRINT("NtCreateKey(%wZ) called (Status %lx)\n", ObjectAttributes->ObjectName, Status); + TRACE("NtCreateKey(%wZ) called (Status %lx)\n", ObjectAttributes->ObjectName, Status); if (Status != STATUS_OBJECT_NAME_NOT_FOUND) return Status; @@ -373,7 +373,7 @@ CreateNestedKey(PHKEY KeyHandle, NULL, 0, &Disposition); - DPRINT("NtCreateKey(%wZ) called (Status %lx)\n", &LocalKeyName, Status); + TRACE("NtCreateKey(%wZ) called (Status %lx)\n", &LocalKeyName, Status); } if (!NT_SUCCESS(Status)) @@ -410,7 +410,7 @@ CreateNestedKey(PHKEY KeyHandle, NULL, 0, &Disposition); - DPRINT("NtCreateKey(%wZ) called (Status %lx)\n", &LocalKeyName, Status); + TRACE("NtCreateKey(%wZ) called (Status %lx)\n", &LocalKeyName, Status); if (!NT_SUCCESS(Status)) break; } @@ -443,7 +443,7 @@ RegCreateKeyExA (HKEY hKey, HANDLE ParentKey; NTSTATUS Status; - DPRINT("RegCreateKeyExA() called\n"); + TRACE("RegCreateKeyExA() called\n"); /* get the real parent key */ Status = MapDefaultKey (&ParentKey, @@ -452,7 +452,7 @@ RegCreateKeyExA (HKEY hKey, { return RtlNtStatusToDosError (Status); } - DPRINT("ParentKey %x\n", (ULONG)ParentKey); + TRACE("ParentKey %x\n", (ULONG)ParentKey); if (lpClass != NULL) { @@ -479,7 +479,7 @@ RegCreateKeyExA (HKEY hKey, RtlFreeUnicodeString (&ClassString); } - DPRINT("Status %x\n", Status); + TRACE("Status %x\n", Status); if (!NT_SUCCESS(Status)) { return RtlNtStatusToDosError (Status); @@ -511,7 +511,7 @@ RegCreateKeyExW (HKEY hKey, HANDLE ParentKey; NTSTATUS Status; - DPRINT("RegCreateKeyExW() called\n"); + TRACE("RegCreateKeyExW() called\n"); /* get the real parent key */ Status = MapDefaultKey (&ParentKey, @@ -520,7 +520,7 @@ RegCreateKeyExW (HKEY hKey, { return RtlNtStatusToDosError(Status); } - DPRINT("ParentKey %x\n", (ULONG)ParentKey); + TRACE("ParentKey %x\n", (ULONG)ParentKey); RtlInitUnicodeString (&ClassString, lpClass); @@ -537,7 +537,7 @@ RegCreateKeyExW (HKEY hKey, dwOptions, samDesired, lpdwDisposition); - DPRINT("Status %x\n", Status); + TRACE("Status %x\n", Status); if (!NT_SUCCESS(Status)) { return RtlNtStatusToDosError (Status); @@ -838,7 +838,7 @@ RegEnumKeyExA (HKEY hKey, HANDLE KeyHandle; NTSTATUS Status; - DPRINT("RegEnumKeyExA(hKey 0x%x, dwIndex %d, lpName 0x%x, *lpcbName %d, lpClass 0x%x, lpcbClass %d)\n", + TRACE("RegEnumKeyExA(hKey 0x%x, dwIndex %d, lpName 0x%x, *lpcbName %d, lpClass 0x%x, lpcbClass %d)\n", hKey, dwIndex, lpName, *lpcbName, lpClass, lpcbClass ? *lpcbClass : 0); if ((lpClass) && (!lpcbClass)) @@ -892,7 +892,7 @@ RegEnumKeyExA (HKEY hKey, KeyInfo, BufferSize, &ResultSize); - DPRINT("NtEnumerateKey() returned status 0x%X\n", Status); + TRACE("NtEnumerateKey() returned status 0x%X\n", Status); if (!NT_SUCCESS(Status)) { ErrorCode = RtlNtStatusToDosError (Status); @@ -960,10 +960,10 @@ RegEnumKeyExA (HKEY hKey, } } - DPRINT("Key Namea0 Length %d\n", StringU.Length); - DPRINT("Key Namea1 Length %d\n", NameLength); - DPRINT("Key Namea Length %d\n", *lpcbName); - DPRINT("Key Namea %s\n", lpName); + TRACE("Key Namea0 Length %d\n", StringU.Length); + TRACE("Key Namea1 Length %d\n", NameLength); + TRACE("Key Namea Length %d\n", *lpcbName); + TRACE("Key Namea %s\n", lpName); RtlFreeHeap (ProcessHeap, 0, @@ -1050,7 +1050,7 @@ RegEnumKeyExW (HKEY hKey, KeyInfo, BufferSize, &ResultSize); - DPRINT("NtEnumerateKey() returned status 0x%X\n", Status); + TRACE("NtEnumerateKey() returned status 0x%X\n", Status); if (!NT_SUCCESS(Status)) { ErrorCode = RtlNtStatusToDosError (Status); @@ -1386,7 +1386,7 @@ RegGetKeySecurity(HKEY hKey, hKey); if (!NT_SUCCESS(Status)) { - DPRINT("MapDefaultKey() failed (Status %lx)\n", Status); + TRACE("MapDefaultKey() failed (Status %lx)\n", Status); return RtlNtStatusToDosError (Status); } @@ -1397,7 +1397,7 @@ RegGetKeySecurity(HKEY hKey, lpcbSecurityDescriptor); if (!NT_SUCCESS(Status)) { - DPRINT("NtQuerySecurityObject() failed (Status %lx)\n", Status); + WARN("NtQuerySecurityObject() failed (Status %lx)\n", Status); return RtlNtStatusToDosError (Status); } @@ -1590,7 +1590,7 @@ RegOpenKeyA (HKEY hKey, LPCSTR lpSubKey, PHKEY phkResult) { - DPRINT("RegOpenKeyA hKey 0x%x lpSubKey %s phkResult %p\n", hKey, lpSubKey, phkResult); + TRACE("RegOpenKeyA hKey 0x%x lpSubKey %s phkResult %p\n", hKey, lpSubKey, phkResult); if (!lpSubKey || !*lpSubKey) { @@ -1616,7 +1616,7 @@ RegOpenKeyW (HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult) { - DPRINT("RegOpenKeyW hKey 0x%x lpSubKey %S phkResult %p\n", hKey, lpSubKey, phkResult); + TRACE("RegOpenKeyW hKey 0x%x lpSubKey %S phkResult %p\n", hKey, lpSubKey, phkResult); if (!lpSubKey || !*lpSubKey) { @@ -1644,7 +1644,7 @@ RegOpenKeyExA (HKEY hKey, HANDLE KeyHandle; NTSTATUS Status; - DPRINT("RegOpenKeyExA hKey 0x%x lpSubKey %s ulOptions 0x%x samDesired 0x%x phkResult %p\n", + TRACE("RegOpenKeyExA hKey 0x%x lpSubKey %s ulOptions 0x%x samDesired 0x%x phkResult %p\n", hKey, lpSubKey, ulOptions, samDesired, phkResult); Status = MapDefaultKey (&KeyHandle, hKey); @@ -1688,7 +1688,7 @@ RegOpenKeyExW (HKEY hKey, HANDLE KeyHandle; NTSTATUS Status; - DPRINT("RegOpenKeyExW hKey 0x%x lpSubKey %S ulOptions 0x%x samDesired 0x%x phkResult %p\n", + TRACE("RegOpenKeyExW hKey 0x%x lpSubKey %S ulOptions 0x%x samDesired 0x%x phkResult %p\n", hKey, lpSubKey, ulOptions, samDesired, phkResult); Status = MapDefaultKey (&KeyHandle, hKey); @@ -1837,7 +1837,7 @@ ReadTokenSid: RtlAppendUnicodeToString(&UserClassesKeyRoot, UserClassesKeySuffix); - DPRINT("RegOpenUserClassesRoot: Absolute path: %wZ\n", &UserClassesKeyRoot); + TRACE("RegOpenUserClassesRoot: Absolute path: %wZ\n", &UserClassesKeyRoot); /* * Open the key @@ -2001,7 +2001,7 @@ RegQueryInfoKeyW (HKEY hKey, FullInfo, FullInfoSize, &Length); - DPRINT("NtQueryKey() returned status 0x%X\n", Status); + TRACE("NtQueryKey() returned status 0x%X\n", Status); if (!NT_SUCCESS(Status)) { if (lpClass != NULL) @@ -2014,37 +2014,37 @@ RegQueryInfoKeyW (HKEY hKey, return RtlNtStatusToDosError (Status); } - DPRINT("SubKeys %d\n", FullInfo->SubKeys); + TRACE("SubKeys %d\n", FullInfo->SubKeys); if (lpcSubKeys != NULL) { *lpcSubKeys = FullInfo->SubKeys; } - DPRINT("MaxNameLen %lu\n", FullInfo->MaxNameLen); + TRACE("MaxNameLen %lu\n", FullInfo->MaxNameLen); if (lpcbMaxSubKeyLen != NULL) { *lpcbMaxSubKeyLen = FullInfo->MaxNameLen / sizeof(WCHAR) + 1; } - DPRINT("MaxClassLen %lu\n", FullInfo->MaxClassLen); + TRACE("MaxClassLen %lu\n", FullInfo->MaxClassLen); if (lpcbMaxClassLen != NULL) { *lpcbMaxClassLen = FullInfo->MaxClassLen / sizeof(WCHAR) + 1; } - DPRINT("Values %lu\n", FullInfo->Values); + TRACE("Values %lu\n", FullInfo->Values); if (lpcValues != NULL) { *lpcValues = FullInfo->Values; } - DPRINT("MaxValueNameLen %lu\n", FullInfo->MaxValueNameLen); + TRACE("MaxValueNameLen %lu\n", FullInfo->MaxValueNameLen); if (lpcbMaxValueNameLen != NULL) { *lpcbMaxValueNameLen = FullInfo->MaxValueNameLen / sizeof(WCHAR) + 1; } - DPRINT("MaxValueDataLen %lu\n", FullInfo->MaxValueDataLen); + TRACE("MaxValueDataLen %lu\n", FullInfo->MaxValueDataLen); if (lpcbMaxValueLen != NULL) { *lpcbMaxValueLen = FullInfo->MaxValueDataLen; @@ -2124,7 +2124,7 @@ RegQueryMultipleValuesA (HKEY hKey, *ldwTotsize = 0; - DPRINT ("RegQueryMultipleValuesA(%p,%p,%ld,%p,%p=%ld)\n", + TRACE("RegQueryMultipleValuesA(%p,%p,%ld,%p,%p=%ld)\n", hKey, val_list, num_vals, lpValueBuf, ldwTotsize, *ldwTotsize); for (i = 0; i < num_vals; i++) @@ -2188,7 +2188,7 @@ RegQueryMultipleValuesW (HKEY hKey, *ldwTotsize = 0; - DPRINT ("RegQueryMultipleValuesW(%p,%p,%ld,%p,%p=%ld)\n", + TRACE ("RegQueryMultipleValuesW(%p,%p,%ld,%p,%p=%ld)\n", hKey, val_list, num_vals, lpValueBuf, ldwTotsize, *ldwTotsize); for (i = 0; i < num_vals; i++) @@ -2252,7 +2252,7 @@ RegQueryValueExW (HKEY hKey, LONG ErrorCode = ERROR_SUCCESS; ULONG MaxCopy = lpcbData != NULL && lpData != NULL ? *lpcbData : 0; - DPRINT("hKey 0x%X lpValueName %S lpData 0x%X lpcbData %d\n", + TRACE("hKey 0x%X lpValueName %S lpData 0x%X lpcbData %d\n", hKey, lpValueName, lpData, lpcbData ? *lpcbData : 0); Status = MapDefaultKey (&KeyHandle, @@ -2284,7 +2284,7 @@ RegQueryValueExW (HKEY hKey, ValueInfo, BufferSize, &ResultSize); - DPRINT("Status 0x%X\n", Status); + TRACE("Status 0x%X\n", Status); if (Status == STATUS_BUFFER_OVERFLOW) { /* Return ERROR_SUCCESS and the buffer space needed for a successful call */ @@ -2325,7 +2325,7 @@ RegQueryValueExW (HKEY hKey, if (lpcbData != NULL) { *lpcbData = (ResultSize - FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data[0])); - DPRINT("(string) Returning Size: %lu\n", *lpcbData); + TRACE("(string) Returning Size: %lu\n", *lpcbData); } } else @@ -2333,11 +2333,11 @@ RegQueryValueExW (HKEY hKey, if (lpcbData != NULL) { *lpcbData = ResultSize - FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data[0]); - DPRINT("(other) Returning Size: %lu\n", *lpcbData); + TRACE("(other) Returning Size: %lu\n", *lpcbData); } } - DPRINT("Type %d Size %d\n", ValueInfo->Type, ValueInfo->DataLength); + TRACE("Type %d Size %d\n", ValueInfo->Type, ValueInfo->DataLength); RtlFreeHeap (ProcessHeap, 0, @@ -2367,7 +2367,7 @@ RegQueryValueExA (HKEY hKey, DWORD Length; DWORD Type; - DPRINT("hKey 0x%X lpValueName %s lpData 0x%X lpcbData %d\n", + TRACE("hKey 0x%X lpValueName %s lpData 0x%X lpcbData %d\n", hKey, lpValueName, lpData, lpcbData ? *lpcbData : 0); if (lpData != NULL && lpcbData == NULL) @@ -2404,7 +2404,7 @@ RegQueryValueExA (HKEY hKey, &Type, (lpData == NULL) ? NULL : (LPBYTE)ValueData.Buffer, &Length); - DPRINT("ErrorCode %lu\n", ErrorCode); + TRACE("ErrorCode %lu\n", ErrorCode); RtlFreeUnicodeString(&ValueName); if (ErrorCode == ERROR_SUCCESS || @@ -2473,7 +2473,7 @@ RegQueryValueA (HKEY hKey, LONG ValueSize; LONG ErrorCode; - DPRINT("hKey 0x%X lpSubKey %s lpValue %p lpcbValue %d\n", + TRACE("hKey 0x%X lpSubKey %s lpValue %p lpcbValue %d\n", hKey, lpSubKey, lpValue, lpcbValue ? *lpcbValue : 0); if (lpValue != NULL && @@ -2562,7 +2562,7 @@ RegQueryValueW (HKEY hKey, BOOL CloseRealKey; NTSTATUS Status; - DPRINT("hKey 0x%X lpSubKey %S lpValue %p lpcbValue %d\n", + TRACE("hKey 0x%X lpSubKey %S lpValue %p lpcbValue %d\n", hKey, lpSubKey, lpValue, lpcbValue ? *lpcbValue : 0); Status = MapDefaultKey (&KeyHandle, diff --git a/reactos/lib/advapi32/sec/sid.c b/reactos/lib/advapi32/sec/sid.c index 774d8302d1c..93b0b6dc53a 100644 --- a/reactos/lib/advapi32/sec/sid.c +++ b/reactos/lib/advapi32/sec/sid.c @@ -1,14 +1,612 @@ /* $Id$ * * COPYRIGHT: See COPYING in the top level directory + * WINE COPYRIGHT: + * Copyright 1999, 2000 Juergen Schmied + * Copyright 2003 CodeWeavers Inc. (Ulrich Czekalla) + * * PROJECT: ReactOS system libraries * FILE: lib/advapi32/sec/sid.c * PURPOSE: Security ID functions */ #include -#include +#include +#include +WINE_DEFAULT_DEBUG_CHANNEL(advapi); + + +static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes); +static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags, + PACL pAcl, LPDWORD cBytes); +static BYTE ParseAceStringFlags(LPCWSTR* StringAcl); +static BYTE ParseAceStringType(LPCWSTR* StringAcl); +static DWORD ParseAceStringRights(LPCWSTR* StringAcl); +static DWORD ParseAclStringFlags(LPCWSTR* StringAcl); + +typedef struct _ACEFLAG +{ + LPCWSTR wstr; + DWORD value; +} ACEFLAG, *LPACEFLAG; + +static SID const sidWorld = { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY} , { SECURITY_WORLD_RID } }; + +/* + * ACE access rights + */ +static const WCHAR SDDL_READ_CONTROL[] = {'R','C',0}; +static const WCHAR SDDL_WRITE_DAC[] = {'W','D',0}; +static const WCHAR SDDL_WRITE_OWNER[] = {'W','O',0}; +static const WCHAR SDDL_STANDARD_DELETE[] = {'S','D',0}; +static const WCHAR SDDL_GENERIC_ALL[] = {'G','A',0}; +static const WCHAR SDDL_GENERIC_READ[] = {'G','R',0}; +static const WCHAR SDDL_GENERIC_WRITE[] = {'G','W',0}; +static const WCHAR SDDL_GENERIC_EXECUTE[] = {'G','X',0}; + +/* + * ACE types + */ +static const WCHAR SDDL_ACCESS_ALLOWED[] = {'A',0}; +static const WCHAR SDDL_ACCESS_DENIED[] = {'D',0}; +static const WCHAR SDDL_OBJECT_ACCESS_ALLOWED[] = {'O','A',0}; +static const WCHAR SDDL_OBJECT_ACCESS_DENIED[] = {'O','D',0}; +static const WCHAR SDDL_AUDIT[] = {'A','U',0}; +static const WCHAR SDDL_ALARM[] = {'A','L',0}; +static const WCHAR SDDL_OBJECT_AUDIT[] = {'O','U',0}; +static const WCHAR SDDL_OBJECT_ALARMp[] = {'O','L',0}; + +/* + * ACE flags + */ +static const WCHAR SDDL_CONTAINER_INHERIT[] = {'C','I',0}; +static const WCHAR SDDL_OBJECT_INHERIT[] = {'O','I',0}; +static const WCHAR SDDL_NO_PROPAGATE[] = {'N','P',0}; +static const WCHAR SDDL_INHERIT_ONLY[] = {'I','O',0}; +static const WCHAR SDDL_INHERITED[] = {'I','D',0}; +static const WCHAR SDDL_AUDIT_SUCCESS[] = {'S','A',0}; +static const WCHAR SDDL_AUDIT_FAILURE[] = {'F','A',0}; + +/* set last error code from NT status and get the proper boolean return value */ +/* used for functions that are a simple wrapper around the corresponding ntdll API */ +static inline BOOL set_ntstatus( NTSTATUS status ) +{ + if (status) SetLastError( RtlNtStatusToDosError( status )); + return !status; +} + +#define WINE_SIZE_OF_WORLD_ACCESS_ACL (sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD)) + + +/* some helper functions - taken from winehq cvs 20050916 */ +/****************************************************************************** + * ComputeStringSidSize + */ +static DWORD ComputeStringSidSize(LPCWSTR StringSid) +{ + int ctok = 0; + DWORD size = sizeof(SID); + + while (*StringSid) + { + if (*StringSid == '-') + ctok++; + StringSid++; + } + + if (ctok > 3) + size += (ctok - 3) * sizeof(DWORD); + + return size; +} + +/****************************************************************************** + * ParseAceStringType + */ +ACEFLAG AceType[] = +{ + { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE }, + { SDDL_ALARM, SYSTEM_ALARM_ACE_TYPE }, + { SDDL_AUDIT, SYSTEM_AUDIT_ACE_TYPE }, + { SDDL_ACCESS_DENIED, ACCESS_DENIED_ACE_TYPE }, + /* + { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE }, + { SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE }, + { SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE }, + { SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE }, + */ + { NULL, 0 }, +}; + +static BYTE ParseAceStringType(LPCWSTR* StringAcl) +{ + UINT len = 0; + LPCWSTR szAcl = *StringAcl; + LPACEFLAG lpaf = AceType; + + while (lpaf->wstr && + (len = strlenW(lpaf->wstr)) && + strncmpW(lpaf->wstr, szAcl, len)) + lpaf++; + + if (!lpaf->wstr) + return 0; + + *StringAcl += len; + return lpaf->value; +} + + +/****************************************************************************** + * ParseAceStringFlags + */ +ACEFLAG AceFlags[] = +{ + { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE }, + { SDDL_AUDIT_FAILURE, FAILED_ACCESS_ACE_FLAG }, + { SDDL_INHERITED, INHERITED_ACE }, + { SDDL_INHERIT_ONLY, INHERIT_ONLY_ACE }, + { SDDL_NO_PROPAGATE, NO_PROPAGATE_INHERIT_ACE }, + { SDDL_OBJECT_INHERIT, OBJECT_INHERIT_ACE }, + { SDDL_AUDIT_SUCCESS, SUCCESSFUL_ACCESS_ACE_FLAG }, + { NULL, 0 }, +}; + +static BYTE ParseAceStringFlags(LPCWSTR* StringAcl) +{ + UINT len = 0; + BYTE flags = 0; + LPCWSTR szAcl = *StringAcl; + + while (*szAcl != ';') + { + LPACEFLAG lpaf = AceFlags; + + while (lpaf->wstr && + (len = strlenW(lpaf->wstr)) && + strncmpW(lpaf->wstr, szAcl, len)) + lpaf++; + + if (!lpaf->wstr) + return 0; + + flags |= lpaf->value; + szAcl += len; + } + + *StringAcl = szAcl; + return flags; +} + + +/****************************************************************************** + * ParseAceStringRights + */ +ACEFLAG AceRights[] = +{ + { SDDL_GENERIC_ALL, GENERIC_ALL }, + { SDDL_GENERIC_READ, GENERIC_READ }, + { SDDL_GENERIC_WRITE, GENERIC_WRITE }, + { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE }, + { SDDL_READ_CONTROL, READ_CONTROL }, + { SDDL_STANDARD_DELETE, DELETE }, + { SDDL_WRITE_DAC, WRITE_DAC }, + { SDDL_WRITE_OWNER, WRITE_OWNER }, + { NULL, 0 }, +}; + +static DWORD ParseAceStringRights(LPCWSTR* StringAcl) +{ + UINT len = 0; + DWORD rights = 0; + LPCWSTR szAcl = *StringAcl; + + if ((*szAcl == '0') && (*(szAcl + 1) == 'x')) + { + LPCWSTR p = szAcl; + + while (*p && *p != ';') + p++; + + if (p - szAcl <= 8) + { + rights = strtoulW(szAcl, NULL, 16); + *StringAcl = p; + } + else + WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl)); + } + else + { + while (*szAcl != ';') + { + LPACEFLAG lpaf = AceRights; + + while (lpaf->wstr && + (len = strlenW(lpaf->wstr)) && + strncmpW(lpaf->wstr, szAcl, len)) + { + lpaf++; + } + + if (!lpaf->wstr) + return 0; + + rights |= lpaf->value; + szAcl += len; + } + } + + *StringAcl = szAcl; + return rights; +} + +/****************************************************************************** + * ParseStringAclToAcl + * + * dacl_flags(string_ace1)(string_ace2)... (string_acen) + */ +static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags, + PACL pAcl, LPDWORD cBytes) +{ + DWORD val; + DWORD sidlen; + DWORD length = sizeof(ACL); + PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */ + + TRACE("%s\n", debugstr_w(StringAcl)); + + if (!StringAcl) + return FALSE; + + if (pAcl) /* pAce is only useful if we're setting values */ + pAce = (PACCESS_ALLOWED_ACE) ((LPBYTE)pAcl + sizeof(PACL)); + + /* Parse ACL flags */ + *lpdwFlags = ParseAclStringFlags(&StringAcl); + + /* Parse ACE */ + while (*StringAcl == '(') + { + StringAcl++; + + /* Parse ACE type */ + val = ParseAceStringType(&StringAcl); + if (pAce) + pAce->Header.AceType = (BYTE) val; + if (*StringAcl != ';') + goto lerr; + StringAcl++; + + /* Parse ACE flags */ + val = ParseAceStringFlags(&StringAcl); + if (pAce) + pAce->Header.AceFlags = (BYTE) val; + if (*StringAcl != ';') + goto lerr; + StringAcl++; + + /* Parse ACE rights */ + val = ParseAceStringRights(&StringAcl); + if (pAce) + pAce->Mask = val; + if (*StringAcl != ';') + goto lerr; + StringAcl++; + + /* Parse ACE object guid */ + if (*StringAcl != ';') + { + FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n"); + goto lerr; + } + StringAcl++; + + /* Parse ACE inherit object guid */ + if (*StringAcl != ';') + { + FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n"); + goto lerr; + } + StringAcl++; + + /* Parse ACE account sid */ + if (ParseStringSidToSid(StringAcl, pAce ? (PSID)&pAce->SidStart : NULL, &sidlen)) + { + while (*StringAcl && *StringAcl != ')') + StringAcl++; + } + + if (*StringAcl != ')') + goto lerr; + StringAcl++; + + length += sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen; + } + + *cBytes = length; + return TRUE; + +lerr: + WARN("Invalid ACE string format\n"); + return FALSE; +} + +/****************************************************************************** + * ParseStringSecurityDescriptorToSecurityDescriptor + */ +static BOOL ParseStringSecurityDescriptorToSecurityDescriptor( + LPCWSTR StringSecurityDescriptor, + SECURITY_DESCRIPTOR* SecurityDescriptor, + LPDWORD cBytes) +{ + BOOL bret = FALSE; + WCHAR toktype; + WCHAR tok[MAX_PATH]; + LPCWSTR lptoken; + LPBYTE lpNext = NULL; + DWORD len; + + *cBytes = 0; + + if (SecurityDescriptor) + lpNext = ((LPBYTE) SecurityDescriptor) + sizeof(SECURITY_DESCRIPTOR); + + while (*StringSecurityDescriptor) + { + toktype = *StringSecurityDescriptor; + + /* Expect char identifier followed by ':' */ + StringSecurityDescriptor++; + if (*StringSecurityDescriptor != ':') + { + SetLastError(ERROR_INVALID_PARAMETER); + goto lend; + } + StringSecurityDescriptor++; + + /* Extract token */ + lptoken = StringSecurityDescriptor; + while (*lptoken && *lptoken != ':') + lptoken++; + + if (*lptoken) + lptoken--; + + len = lptoken - StringSecurityDescriptor; + memcpy( tok, StringSecurityDescriptor, len * sizeof(WCHAR) ); + tok[len] = 0; + + switch (toktype) + { + case 'O': + { + DWORD bytes; + + if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes)) + goto lend; + + if (SecurityDescriptor) + { + SecurityDescriptor->Owner = (PSID) ((DWORD) lpNext - + (DWORD) SecurityDescriptor); + lpNext += bytes; /* Advance to next token */ + } + + *cBytes += bytes; + + break; + } + + case 'G': + { + DWORD bytes; + + if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes)) + goto lend; + + if (SecurityDescriptor) + { + SecurityDescriptor->Group = (PSID) ((DWORD) lpNext - + (DWORD) SecurityDescriptor); + lpNext += bytes; /* Advance to next token */ + } + + *cBytes += bytes; + + break; + } + + case 'D': + { + DWORD flags; + DWORD bytes; + + if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes)) + goto lend; + + if (SecurityDescriptor) + { + SecurityDescriptor->Control |= SE_DACL_PRESENT | flags; + SecurityDescriptor->Dacl = (PACL) ((DWORD) lpNext - + (DWORD) SecurityDescriptor); + lpNext += bytes; /* Advance to next token */ + } + + *cBytes += bytes; + + break; + } + + case 'S': + { + DWORD flags; + DWORD bytes; + + if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes)) + goto lend; + + if (SecurityDescriptor) + { + SecurityDescriptor->Control |= SE_SACL_PRESENT | flags; + SecurityDescriptor->Sacl = (PACL) ((DWORD) lpNext - + (DWORD) SecurityDescriptor); + lpNext += bytes; /* Advance to next token */ + } + + *cBytes += bytes; + + break; + } + + default: + FIXME("Unknown token\n"); + SetLastError(ERROR_INVALID_PARAMETER); + goto lend; + } + + StringSecurityDescriptor = lptoken; + } + + bret = TRUE; + +lend: + return bret; +} + +/****************************************************************************** + * ParseAclStringFlags + */ +static DWORD ParseAclStringFlags(LPCWSTR* StringAcl) +{ + DWORD flags = 0; + LPCWSTR szAcl = *StringAcl; + + while (*szAcl != '(') + { + if (*szAcl == 'P') + { + flags |= SE_DACL_PROTECTED; + } + else if (*szAcl == 'A') + { + szAcl++; + if (*szAcl == 'R') + flags |= SE_DACL_AUTO_INHERIT_REQ; + else if (*szAcl == 'I') + flags |= SE_DACL_AUTO_INHERITED; + } + szAcl++; + } + + *StringAcl = szAcl; + return flags; +} + +/****************************************************************************** + * ParseStringSidToSid + */ +static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes) +{ + BOOL bret = FALSE; + SID* pisid=pSid; + + TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes); + if (!StringSid) + { + SetLastError(ERROR_INVALID_PARAMETER); + TRACE("StringSid is NULL, returning FALSE\n"); + return FALSE; + } + + *cBytes = ComputeStringSidSize(StringSid); + if (!pisid) /* Simply compute the size */ + { + TRACE("only size requested, returning TRUE\n"); + return TRUE; + } + + if (*StringSid != 'S' || *StringSid != '-') /* S-R-I-S-S */ + { + DWORD i = 0, identAuth; + DWORD csubauth = ((*cBytes - sizeof(SID)) / sizeof(DWORD)) + 1; + + StringSid += 2; /* Advance to Revision */ + pisid->Revision = atoiW(StringSid); + + if (pisid->Revision != SDDL_REVISION) + { + TRACE("Revision %d is unknown\n", pisid->Revision); + goto lend; /* ERROR_INVALID_SID */ + } + if (csubauth == 0) + { + TRACE("SubAuthorityCount is 0\n"); + goto lend; /* ERROR_INVALID_SID */ + } + + pisid->SubAuthorityCount = csubauth; + + /* Advance to identifier authority */ + while (*StringSid && *StringSid != '-') + StringSid++; + if (*StringSid == '-') + StringSid++; + + /* MS' implementation can't handle values greater than 2^32 - 1, so + * we don't either; assume most significant bytes are always 0 + */ + pisid->IdentifierAuthority.Value[0] = 0; + pisid->IdentifierAuthority.Value[1] = 0; + identAuth = atoiW(StringSid); + pisid->IdentifierAuthority.Value[5] = identAuth & 0xff; + pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8; + pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16; + pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24; + + /* Advance to first sub authority */ + while (*StringSid && *StringSid != '-') + StringSid++; + if (*StringSid == '-') + StringSid++; + + while (*StringSid) + { + while (*StringSid && *StringSid != '-') + StringSid++; + + pisid->SubAuthority[i++] = atoiW(StringSid); + } + + if (i != pisid->SubAuthorityCount) + goto lend; /* ERROR_INVALID_SID */ + + bret = TRUE; + } + else /* String constant format - Only available in winxp and above */ + { + pisid->Revision = SDDL_REVISION; + pisid->SubAuthorityCount = 1; + + FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2)); + + /* TODO: Lookup string of well-known SIDs in table */ + pisid->IdentifierAuthority.Value[5] = 0; + pisid->SubAuthority[0] = 0; + + bret = TRUE; + } + +lend: + if (!bret) + SetLastError(ERROR_INVALID_SID); + + TRACE("returning %s\n", bret ? "TRUE" : "FALSE"); + return bret; +} + +/* Exported functions */ /* * @implemented @@ -89,7 +687,92 @@ CopySid (DWORD nDestinationSidLength, return TRUE; } +/* Winehq cvs 20050916 */ +/****************************************************************************** + * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@] + * @implemented + */ +BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW( + LPCWSTR StringSecurityDescriptor, + DWORD StringSDRevision, + PSECURITY_DESCRIPTOR* SecurityDescriptor, + PULONG SecurityDescriptorSize) +{ + DWORD cBytes; + SECURITY_DESCRIPTOR* psd; + BOOL bret = FALSE; + TRACE("%s\n", debugstr_w(StringSecurityDescriptor)); + + if (GetVersion() & 0x80000000) + { + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + goto lend; + } + else if (StringSDRevision != SID_REVISION) + { + SetLastError(ERROR_UNKNOWN_REVISION); + goto lend; + } + + /* Compute security descriptor length */ + if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor, + NULL, &cBytes)) + goto lend; + + psd = *SecurityDescriptor = (SECURITY_DESCRIPTOR*) LocalAlloc( + GMEM_ZEROINIT, cBytes); + + psd->Revision = SID_REVISION; + psd->Control |= SE_SELF_RELATIVE; + + if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor, + psd, &cBytes)) + { + LocalFree(psd); + goto lend; + } + + if (SecurityDescriptorSize) + *SecurityDescriptorSize = cBytes; + + bret = TRUE; + +lend: + TRACE(" ret=%d\n", bret); + return bret; +} + +/* Winehq cvs 20050916 */ +/****************************************************************************** + * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@] + * @implemented + */ +BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA( + LPCSTR StringSecurityDescriptor, + DWORD StringSDRevision, + PSECURITY_DESCRIPTOR* SecurityDescriptor, + PULONG SecurityDescriptorSize) +{ + UINT len; + BOOL ret = FALSE; + LPWSTR StringSecurityDescriptorW; + + len = MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, NULL, 0); + StringSecurityDescriptorW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); + + if (StringSecurityDescriptorW) + { + MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, StringSecurityDescriptorW, len); + + ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW, + StringSDRevision, SecurityDescriptor, + SecurityDescriptorSize); + HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW); + } + + return ret; +} /* * @implemented @@ -312,7 +995,7 @@ EqualDomainSid(IN PSID pSid1, IN PSID pSid2, OUT BOOL* pfEqual) { - DPRINT1("%s() not implemented!\n", __FUNCTION__); + FIXME("%s() not implemented!\n", __FUNCTION__); return FALSE; } @@ -325,7 +1008,7 @@ GetWindowsAccountDomainSid(IN PSID pSid, OUT PSID ppDomainSid, IN OUT DWORD* cbSid) { - DPRINT1("%s() not implemented!\n", __FUNCTION__); + FIXME("%s() not implemented!\n", __FUNCTION__); return FALSE; } @@ -339,7 +1022,7 @@ CreateWellKnownSid(IN WELL_KNOWN_SID_TYPE WellKnownSidType, OUT PSID pSid, IN OUT DWORD* cbSid) { - DPRINT1("%s() not implemented!\n", __FUNCTION__); + FIXME("unimplemented!\n", __FUNCTION__); return FALSE; }