Add registry permissions set utility

Fix crash on Windows XP
master
Timothy Pearson 12 years ago
parent 760c8abb53
commit 2a8d25d3bd

@ -20,6 +20,7 @@
*/ */
#include <algorithm> #include <algorithm>
#include <iterator>
#include "ldapuser.h" #include "ldapuser.h"
#include "netusergroup.h" #include "netusergroup.h"
#include "utility.h" #include "utility.h"

@ -166,6 +166,19 @@ extern "C" {
#endif // ENABLE_DEBUG #endif // ENABLE_DEBUG
#endif // ENABLE_LSA_LOG #endif // ENABLE_LSA_LOG
// Windows XP and Windows Vista/above use two different storage schemes for the user data
OSVERSIONINFO osvi;
BOOL bIsWindowsVistaorLater;
ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&osvi);
bIsWindowsVistaorLater =
( (osvi.dwMajorVersion > 6) ||
( (osvi.dwMajorVersion == 6) && (osvi.dwMinorVersion >= 0) ));
KERB_INTERACTIVE_LOGON *ptr = ((KERB_INTERACTIVE_LOGON *)AuthenticationInformation); KERB_INTERACTIVE_LOGON *ptr = ((KERB_INTERACTIVE_LOGON *)AuthenticationInformation);
#ifdef ENABLE_LSA_LOG #ifdef ENABLE_LSA_LOG
@ -195,9 +208,18 @@ extern "C" {
LPWSTR password = (LPWSTR) calloc( ptr->Password.Length + 1, sizeof(wchar_t)); LPWSTR password = (LPWSTR) calloc( ptr->Password.Length + 1, sizeof(wchar_t));
if (userName && domain) { if (userName && domain) {
memcpy( userName, (void*)((intptr_t)(ptr) + (intptr_t)(ptr->UserName.Buffer)), ptr->UserName.Length); if (bIsWindowsVistaorLater) {
memcpy( domain, (void*)((intptr_t)(ptr) + (intptr_t)(ptr->LogonDomainName.Buffer)), ptr->LogonDomainName.Length); // Windows Vista or later
memcpy( password, (void*)((intptr_t)(ptr) + (intptr_t)(ptr->Password.Buffer)), ptr->Password.Length); memcpy( userName, (void*)((intptr_t)(ptr) + (intptr_t)(ptr->UserName.Buffer)), ptr->UserName.Length);
memcpy( domain, (void*)((intptr_t)(ptr) + (intptr_t)(ptr->LogonDomainName.Buffer)), ptr->LogonDomainName.Length);
memcpy( password, (void*)((intptr_t)(ptr) + (intptr_t)(ptr->Password.Buffer)), ptr->Password.Length);
}
else {
// Windows XP or earlier
wcsncpy( userName, (wchar_t *) ((char *) ptr + ((char *)ptr->UserName.Buffer - (char *) ClientAuthenticationBase)), ptr->UserName.Length / 2);
wcsncpy( domain, (wchar_t *) ((char *) ptr + ((char *)ptr->LogonDomainName.Buffer - (char *) ClientAuthenticationBase)), ptr->LogonDomainName.Length / 2);
//wcsncpy( password, (wchar_t *) ((char *) ptr + ((char *)ptr->Password.Buffer - (char *) ClientAuthenticationBase)), ptr->Password.Length / 2);
}
userName[ptr->UserName.Length] = L'\0'; userName[ptr->UserName.Length] = L'\0';
domain[ptr->LogonDomainName.Length] = L'\0'; domain[ptr->LogonDomainName.Length] = L'\0';

@ -1,17 +1,23 @@
Microsoft Visual Studio Solution File, Format Version 12.00 Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2012 # Visual Studio 2010
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sspap3", "sspap3.vcxproj", "{EA164A0F-6361-40D6-B356-B6E16EB9FA15}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sspap3", "sspap3.vcxproj", "{EA164A0F-6361-40D6-B356-B6E16EB9FA15}"
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sspap3registrypermissions", "..\sspap3registrypermissions\sspap3registrypermissions.vcxproj", "{9BCBC2A2-62A2-4613-B61F-E7477CE0A487}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32 Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32 Release|Win32 = Release|Win32
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
{EA164A0F-6361-40D6-B356-B6E16EB9FA15}.Debug|Win32.ActiveCfg = Debug|Win32 {EA164A0F-6361-40D6-B356-B6E16EB9FA15}.Debug|Win32.ActiveCfg = Release|Win32
{EA164A0F-6361-40D6-B356-B6E16EB9FA15}.Debug|Win32.Build.0 = Debug|Win32 {EA164A0F-6361-40D6-B356-B6E16EB9FA15}.Debug|Win32.Build.0 = Release|Win32
{EA164A0F-6361-40D6-B356-B6E16EB9FA15}.Release|Win32.ActiveCfg = Release|Win32 {EA164A0F-6361-40D6-B356-B6E16EB9FA15}.Release|Win32.ActiveCfg = Release|Win32
{EA164A0F-6361-40D6-B356-B6E16EB9FA15}.Release|Win32.Build.0 = Release|Win32 {EA164A0F-6361-40D6-B356-B6E16EB9FA15}.Release|Win32.Build.0 = Release|Win32
{9BCBC2A2-62A2-4613-B61F-E7477CE0A487}.Debug|Win32.ActiveCfg = Release|Win32
{9BCBC2A2-62A2-4613-B61F-E7477CE0A487}.Debug|Win32.Build.0 = Release|Win32
{9BCBC2A2-62A2-4613-B61F-E7477CE0A487}.Release|Win32.ActiveCfg = Release|Win32
{9BCBC2A2-62A2-4613-B61F-E7477CE0A487}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

Binary file not shown.

@ -0,0 +1,295 @@
// sspap3registrypermissions.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <aclapi.h>
#define RTN_OK 0
#define RTN_ERROR 13
void
DisplayWinError(
LPSTR szAPI, // pointer to Ansi function name
DWORD dwError // DWORD WinError
);
int _tmain(int argc, _TCHAR* argv[])
{
SID_IDENTIFIER_AUTHORITY sia = SECURITY_NT_AUTHORITY;
PSID pRestrictedSid = NULL;
PSID pSystemSid = NULL;
PSID pAdministratorsSid = NULL;
PSID pEveryoneSid = NULL;
SECURITY_DESCRIPTOR sd;
PACL pDacl = NULL;
DWORD dwAclSize;
DWORD sidSize;
HKEY hKey;
LONG lRetCode;
BOOL bSuccess = FALSE; // assume this function fails
//
// open the performance key for WRITE_DAC access
//
lRetCode = RegOpenKeyEx(
HKEY_CURRENT_USER,
TEXT(""),
0,
WRITE_DAC,
&hKey
);
if(lRetCode != ERROR_SUCCESS) {
DisplayWinError("RegOpenKeyEx", lRetCode);
return RTN_ERROR;
}
//
// prepare a Sid representing the Restricted user
//
if(!AllocateAndInitializeSid(
&sia,
1,
SECURITY_RESTRICTED_CODE_RID,
0, 0, 0, 0, 0, 0, 0,
&pRestrictedSid
)) {
DisplayWinError("AllocateAndInitializeSid SECURITY_RESTRICTED_CODE_RID", GetLastError());
goto cleanup;
}
//
// prepare a Sid representing the System user
//
if(!AllocateAndInitializeSid(
&sia,
1,
SECURITY_LOCAL_SYSTEM_RID,
0, 0, 0, 0, 0, 0, 0,
&pSystemSid
)) {
DisplayWinError("AllocateAndInitializeSid SECURITY_LOCAL_SYSTEM_RID", GetLastError());
goto cleanup;
}
//
// prepare a Sid representing any administrator
//
pAdministratorsSid = (PSID)HeapAlloc(GetProcessHeap(), 0, SECURITY_MAX_SID_SIZE);
if(pAdministratorsSid == NULL) goto cleanup;
if(!CreateWellKnownSid(
WinBuiltinAdministratorsSid,
NULL,
pAdministratorsSid,
&sidSize
)) {
DisplayWinError("CreateWellKnownSid WinBuiltinAdministratorsSid", GetLastError());
goto cleanup;
}
//
// prepare a Sid representing any user
//
pEveryoneSid = (PSID)HeapAlloc(GetProcessHeap(), 0, SECURITY_MAX_SID_SIZE);
if(pEveryoneSid == NULL) goto cleanup;
if(!CreateWellKnownSid(
WinWorldSid,
NULL,
pEveryoneSid,
&sidSize
)) {
DisplayWinError("CreateWellKnownSid WinWorldSid", GetLastError());
goto cleanup;
}
//
// compute size of new acl
//
dwAclSize = sizeof(ACL) +
4 * ( sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) ) +
GetLengthSid(pRestrictedSid) +
GetLengthSid(pSystemSid) +
GetLengthSid(pAdministratorsSid) +
GetLengthSid(pEveryoneSid) ;
//
// allocate storage for Acl
//
pDacl = (PACL)HeapAlloc(GetProcessHeap(), 0, dwAclSize);
if(pDacl == NULL) goto cleanup;
if(!InitializeAcl(pDacl, dwAclSize, ACL_REVISION)) {
DisplayWinError("InitializeAcl", GetLastError());
goto cleanup;
}
//
// grant the Restricted Sid KEY_READ access to the perf key
//
if(!AddAccessAllowedAceEx(
pDacl,
ACL_REVISION,
CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE,
KEY_READ,
pRestrictedSid
)) {
DisplayWinError("AddAccessAllowedAce", GetLastError());
goto cleanup;
}
//
// grant the System Sid KEY_ALL_ACCESS access to the perf key
//
if(!AddAccessAllowedAceEx(
pDacl,
ACL_REVISION,
CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE,
KEY_ALL_ACCESS,
pSystemSid
)) {
DisplayWinError("AddAccessAllowedAce", GetLastError());
goto cleanup;
}
//
// grant the Administrators Sid KEY_ALL_ACCESS access to the perf key
//
if(!AddAccessAllowedAceEx(
pDacl,
ACL_REVISION,
CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE,
KEY_ALL_ACCESS,
pAdministratorsSid
)) {
DisplayWinError("AddAccessAllowedAce", GetLastError());
goto cleanup;
}
//
// grant the Everyone Sid KEY_ALL_ACCESS access to the perf key
//
if(!AddAccessAllowedAceEx(
pDacl,
ACL_REVISION,
CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE,
KEY_ALL_ACCESS,
pEveryoneSid
)) {
DisplayWinError("AddAccessAllowedAce", GetLastError());
goto cleanup;
}
if(!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION)) {
DisplayWinError("InitializeSecurityDescriptor", GetLastError());
goto cleanup;
}
/* if(!SetSecurityDescriptorDacl(&sd, TRUE, pDacl, FALSE)) {
DisplayWinError("SetSecurityDescriptorDacl", GetLastError());
goto cleanup;
}*/
//
// Unlike SetSecurityDescriptorDacl, SetNamedSecurityInfo propogates inheritance to subkeys
// See http://comments.gmane.org/gmane.comp.python.windows/10609
//
if(!SetNamedSecurityInfo(L"CURRENT_USER", SE_REGISTRY_KEY, DACL_SECURITY_INFORMATION, NULL, NULL, pDacl, NULL)) {
DisplayWinError("SetNamedSecurityInfo", GetLastError());
goto cleanup;
}
//
// apply the security descriptor to the registry key
//
lRetCode = RegSetKeySecurity(
hKey,
(SECURITY_INFORMATION)DACL_SECURITY_INFORMATION,
&sd
);
if(lRetCode != ERROR_SUCCESS) {
DisplayWinError("RegSetKeySecurity", lRetCode);
goto cleanup;
}
bSuccess = TRUE; // indicate success
cleanup:
RegCloseKey(hKey);
RegCloseKey(HKEY_LOCAL_MACHINE);
//
// free allocated resources
//
if(pDacl != NULL)
HeapFree(GetProcessHeap(), 0, pDacl);
if(pRestrictedSid != NULL)
FreeSid(pRestrictedSid);
if(pSystemSid != NULL)
FreeSid(pSystemSid);
if(pAdministratorsSid != NULL)
FreeSid(pAdministratorsSid);
if(pEveryoneSid != NULL)
FreeSid(pEveryoneSid);
if(bSuccess) {
printf("SUCCESS updating user hive security\n");
return RTN_OK;
} else {
printf("ERROR updating user hive security\n");
return RTN_ERROR;
}
}
void
DisplayWinError(
LPSTR szAPI, // pointer to Ansi function name
DWORD dwError // DWORD WinError
)
{
LPSTR MessageBuffer;
DWORD dwBufferLength;
//
// TODO get this fprintf out of here!
//
fprintf(stderr,"%s error!\n", szAPI);
if(dwBufferLength=FormatMessageA(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
dwError,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPSTR) &MessageBuffer,
0,
NULL
))
{
DWORD dwBytesWritten; // unused
//
// Output message string on stderr
//
WriteFile(
GetStdHandle(STD_ERROR_HANDLE),
MessageBuffer,
dwBufferLength,
&dwBytesWritten,
NULL
);
//
// free the buffer allocated by the system
//
LocalFree(MessageBuffer);
}
}

@ -0,0 +1,94 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{9BCBC2A2-62A2-4613-B61F-E7477CE0A487}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>sspap3registrypermissions</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v110</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>Use</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<Text Include="ReadMe.txt" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h" />
<ClInclude Include="targetver.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="sspap3registrypermissions.cpp" />
<ClCompile Include="stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
</ClCompile>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<Text Include="ReadMe.txt" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="targetver.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="stdafx.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="sspap3registrypermissions.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

@ -0,0 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
</Project>

@ -0,0 +1,8 @@
// stdafx.cpp : source file that includes just the standard includes
// sspap3registrypermissions.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
// TODO: reference any additional headers you need in STDAFX.H
// and not in this file

@ -0,0 +1,15 @@
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#pragma once
#include "targetver.h"
#include <stdio.h>
#include <tchar.h>
// TODO: reference additional headers your program requires here

@ -0,0 +1,8 @@
#pragma once
// Including SDKDDKVer.h defines the highest available Windows platform.
// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
#include <SDKDDKVer.h>
Loading…
Cancel
Save