997 lines
28 KiB
C
997 lines
28 KiB
C
//
|
|
//
|
|
//
|
|
|
|
#include "olecnfg.h"
|
|
|
|
BOOL SetGlobalKey( int Key, int Value )
|
|
{
|
|
DWORD RegStatus;
|
|
HKEY hReg;
|
|
DWORD Disposition;
|
|
char * ValueName;
|
|
|
|
if ( hRegOle == 0 )
|
|
{
|
|
RegStatus = RegCreateKeyEx(
|
|
HKEY_LOCAL_MACHINE,
|
|
"SOFTWARE\\Microsoft\\OLE",
|
|
0,
|
|
"REG_SZ",
|
|
REG_OPTION_NON_VOLATILE,
|
|
KEY_READ | KEY_WRITE,
|
|
NULL,
|
|
&hRegOle,
|
|
&Disposition );
|
|
|
|
if ( RegStatus != ERROR_SUCCESS )
|
|
{
|
|
printf( "Could not open HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\OLE for writing\n" );
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
// TODO : Extra stuff to do for PersonalClasses and InstallCommon.
|
|
|
|
if ( (Key == DEFAULT_LAUNCH_PERMISSION) ||
|
|
(Key == DEFAULT_ACCESS_PERMISSION) )
|
|
{
|
|
RegStatus = RegCreateKeyEx(
|
|
hRegOle,
|
|
GlobalKeyNames[Key],
|
|
0,
|
|
"REG_SZ",
|
|
REG_OPTION_NON_VOLATILE,
|
|
KEY_READ | KEY_WRITE,
|
|
NULL,
|
|
&hReg,
|
|
&Disposition );
|
|
|
|
if ( RegStatus != ERROR_SUCCESS )
|
|
{
|
|
printf( "Unable to open or add global key %s (status %d)\n",
|
|
GlobalKeyNames[Key],
|
|
RegStatus );
|
|
return FALSE;
|
|
}
|
|
|
|
ValueName = NULL;
|
|
}
|
|
else
|
|
{
|
|
hReg = hRegOle;
|
|
ValueName = (char *)GlobalKeyNames[Key];
|
|
}
|
|
|
|
if ( Key == LEGACY_AUTHENTICATION_LEVEL )
|
|
{
|
|
RegStatus = RegSetValueEx(
|
|
hReg,
|
|
ValueName,
|
|
0,
|
|
REG_DWORD,
|
|
(LPBYTE)&Value,
|
|
sizeof(DWORD) );
|
|
}
|
|
else if ( Key != DEFAULT_ACCESS_PERMISSION )
|
|
{
|
|
RegStatus = RegSetValueEx(
|
|
hReg,
|
|
ValueName,
|
|
0,
|
|
REG_SZ,
|
|
(LPBYTE)(Value == YES ? "Y" : "N"),
|
|
2 * sizeof(char) );
|
|
}
|
|
else
|
|
RegStatus = ERROR_SUCCESS;
|
|
|
|
if ( RegStatus != ERROR_SUCCESS )
|
|
{
|
|
printf( "Unable to set value for %s (status %d)\n",
|
|
GlobalKeyNames[Key],
|
|
RegStatus );
|
|
return FALSE;
|
|
}
|
|
|
|
if ( Key == LEGACY_AUTHENTICATION_LEVEL )
|
|
{
|
|
printf( "Global setting %s set to %d.\n",
|
|
GlobalKeyNames[Key],
|
|
Value );
|
|
}
|
|
else if ( Key == DEFAULT_ACCESS_PERMISSION )
|
|
{
|
|
printf( "Global setting %s set to on.\n",
|
|
GlobalKeyNames[Key] );
|
|
}
|
|
else
|
|
{
|
|
printf( "Global setting %s set to %c.\n",
|
|
GlobalKeyNames[Key],
|
|
Value == YES ? 'Y' : 'N' );
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void DisplayGlobalSettings()
|
|
{
|
|
HKEY hReg;
|
|
DWORD RegStatus;
|
|
int Key;
|
|
DWORD Type;
|
|
DWORD Value;
|
|
DWORD BufSize;
|
|
char * ValueName;
|
|
|
|
RegStatus = RegOpenKeyEx(
|
|
HKEY_LOCAL_MACHINE,
|
|
"SOFTWARE\\Microsoft\\OLE",
|
|
0,
|
|
KEY_READ,
|
|
&hRegOle );
|
|
|
|
if ( RegStatus != ERROR_SUCCESS )
|
|
{
|
|
printf( "Could not open HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\OLE\n" );
|
|
return;
|
|
}
|
|
|
|
printf( "\nGlobal OLE registry settings :\n" );
|
|
|
|
for ( Key = 1; Key <= GLOBAL_KEYS; Key++ )
|
|
{
|
|
if ( (Key == DEFAULT_LAUNCH_PERMISSION) ||
|
|
(Key == DEFAULT_ACCESS_PERMISSION) )
|
|
{
|
|
RegStatus = RegOpenKeyEx(
|
|
hRegOle,
|
|
GlobalKeyNames[Key],
|
|
0,
|
|
KEY_READ,
|
|
&hReg );
|
|
|
|
if ( RegStatus != ERROR_SUCCESS )
|
|
{
|
|
printf( " %-28sN (key does not exist or could not be opened)\n",
|
|
GlobalKeyNames[Key] );
|
|
continue;
|
|
}
|
|
|
|
ValueName = NULL;
|
|
}
|
|
else
|
|
{
|
|
hReg = hRegOle;
|
|
ValueName = (char *)GlobalKeyNames[Key];
|
|
}
|
|
|
|
if ( Key != DEFAULT_ACCESS_PERMISSION )
|
|
{
|
|
BufSize = sizeof(DWORD);
|
|
|
|
RegStatus = RegQueryValueEx(
|
|
hReg,
|
|
ValueName,
|
|
0,
|
|
&Type,
|
|
(LPBYTE) &Value,
|
|
&BufSize );
|
|
}
|
|
else
|
|
RegStatus = ERROR_SUCCESS;
|
|
|
|
if ( RegStatus != ERROR_SUCCESS )
|
|
{
|
|
if ( Key == DEFAULT_LAUNCH_PERMISSION )
|
|
printf( " %-28sN (key value could not be read)\n",
|
|
GlobalKeyNames[Key] );
|
|
else
|
|
printf( " %-28s%c (value not present)\n",
|
|
GlobalKeyNames[Key],
|
|
(Key == LEGACY_AUTHENTICATION_LEVEL) ? '2' : 'N' );
|
|
continue;
|
|
}
|
|
|
|
if ( Key == LEGACY_AUTHENTICATION_LEVEL )
|
|
{
|
|
printf( " %-28s%d\n",
|
|
GlobalKeyNames[Key],
|
|
Value );
|
|
}
|
|
else if ( Key == DEFAULT_ACCESS_PERMISSION )
|
|
{
|
|
printf( " %-28son\n",
|
|
GlobalKeyNames[Key] );
|
|
}
|
|
else
|
|
{
|
|
printf( " %-28s%c\n",
|
|
GlobalKeyNames[Key],
|
|
(char)CharUpper((LPSTR)((char *)&Value)[0]) );
|
|
}
|
|
}
|
|
}
|
|
|
|
void DisplayClsidKeys(
|
|
CLSID_INFO * ClsidInfo )
|
|
{
|
|
HKEY hProgId;
|
|
HKEY hClsid;
|
|
HKEY hProgIdClsid;
|
|
HKEY hKey;
|
|
DWORD RegStatus;
|
|
DWORD RegType;
|
|
DWORD BufSize;
|
|
char ProgIdClsid[64];
|
|
char Value[128];
|
|
int Key;
|
|
BOOL HasRunAs;
|
|
char Password[64];
|
|
LSA_HANDLE hPolicy;
|
|
LSA_OBJECT_ATTRIBUTES ObjAttributes;
|
|
LSA_UNICODE_STRING LsaKey;
|
|
LSA_UNICODE_STRING * LsaData;
|
|
WCHAR wszKey[64];
|
|
WCHAR wszPassword[64];
|
|
NTSTATUS NtStatus;
|
|
|
|
RegStatus = RegOpenKeyEx(
|
|
HKEY_CLASSES_ROOT,
|
|
"CLSID",
|
|
0,
|
|
KEY_READ,
|
|
&hRegClsid );
|
|
|
|
if ( RegStatus != ERROR_SUCCESS )
|
|
{
|
|
printf( "Could not open HKEY_CLASSES_ROOT\\CLSID for reading.\n" );
|
|
return;
|
|
}
|
|
|
|
if ( ClsidInfo->ProgId )
|
|
{
|
|
RegStatus = RegOpenKeyEx(
|
|
HKEY_CLASSES_ROOT,
|
|
ClsidInfo->ProgId,
|
|
0,
|
|
KEY_READ,
|
|
&hProgId );
|
|
|
|
if ( RegStatus != ERROR_SUCCESS )
|
|
{
|
|
printf( "Couldn't open ProgID %s\n", ClsidInfo->ProgId );
|
|
return;
|
|
}
|
|
|
|
RegStatus = RegOpenKeyEx(
|
|
hProgId,
|
|
"CLSID",
|
|
0,
|
|
KEY_READ,
|
|
&hProgIdClsid );
|
|
|
|
if ( RegStatus != ERROR_SUCCESS )
|
|
{
|
|
printf( "Couldn't open CLSID key for ProgID %s\n", ClsidInfo->ProgId );
|
|
return;
|
|
}
|
|
|
|
BufSize = sizeof(ProgIdClsid);
|
|
|
|
RegStatus = RegQueryValueEx(
|
|
hProgIdClsid,
|
|
NULL,
|
|
0,
|
|
&RegType,
|
|
(LPBYTE) ProgIdClsid,
|
|
&BufSize );
|
|
|
|
if ( RegStatus != ERROR_SUCCESS )
|
|
{
|
|
printf( "Couldn't open CLSID value for ProgID %s\n", ClsidInfo->ProgId );
|
|
return;
|
|
}
|
|
|
|
if ( ClsidInfo->Clsid &&
|
|
(_stricmp( ClsidInfo->Clsid, ProgIdClsid ) != 0) )
|
|
{
|
|
printf( "ProgID %s CLSID key value %s differs from given CLSID %s.\n",
|
|
ClsidInfo->ProgId,
|
|
ProgIdClsid,
|
|
ClsidInfo->Clsid );
|
|
return;
|
|
}
|
|
else
|
|
ClsidInfo->Clsid = ProgIdClsid;
|
|
}
|
|
|
|
|
|
if ( ! ClsidInfo->Clsid )
|
|
{
|
|
printf( "Could not determine CLSID.\n" );
|
|
return;
|
|
}
|
|
|
|
RegStatus = RegOpenKeyEx(
|
|
hRegClsid,
|
|
ClsidInfo->Clsid,
|
|
0,
|
|
KEY_READ,
|
|
&hClsid );
|
|
|
|
if ( RegStatus != ERROR_SUCCESS )
|
|
{
|
|
printf( "Could not open CLSID %s\n", ClsidInfo->Clsid );
|
|
return;
|
|
}
|
|
|
|
putchar( '\n' );
|
|
if ( ClsidInfo->ProgId )
|
|
printf( "Server settings for ProgID %s, ", ClsidInfo->ProgId );
|
|
else
|
|
printf( "Server settings for " );
|
|
|
|
printf( "CLSID %s\n", ClsidInfo->Clsid );
|
|
|
|
HasRunAs = FALSE;
|
|
|
|
for ( Key = 1; Key <= CLSID_KEYS; Key++ )
|
|
{
|
|
RegStatus = RegOpenKeyEx(
|
|
hClsid,
|
|
ClsidKeyNames[Key],
|
|
0,
|
|
KEY_READ,
|
|
&hKey );
|
|
|
|
if ( RegStatus != ERROR_SUCCESS )
|
|
continue;
|
|
|
|
BufSize = sizeof(Value);
|
|
|
|
if ( Key != ACCESS_PERMISSION )
|
|
{
|
|
RegStatus = RegQueryValueEx(
|
|
hKey,
|
|
NULL,
|
|
0,
|
|
&RegType,
|
|
(LPBYTE) Value,
|
|
&BufSize );
|
|
}
|
|
else
|
|
RegStatus = ERROR_SUCCESS;
|
|
|
|
if ( RegStatus != ERROR_SUCCESS )
|
|
{
|
|
printf( " %-28s(key exists, but value could not be read)\n",
|
|
ClsidKeyNames[Key] );
|
|
continue;
|
|
}
|
|
|
|
printf( " %-28s%s\n",
|
|
ClsidKeyNames[Key],
|
|
(Key == ACCESS_PERMISSION) ? "on" : Value );
|
|
|
|
if ( (Key == RUN_AS) && (_stricmp(Value,"Interactive User") != 0) )
|
|
HasRunAs = TRUE;
|
|
}
|
|
|
|
if ( ! HasRunAs )
|
|
return;
|
|
|
|
//
|
|
// Give the option of verifying the RunAs password.
|
|
//
|
|
|
|
printf( "\nCLSID configured with RunAs. Would you like to verify the password? " );
|
|
|
|
if ( (char)CharUpper((LPSTR)UIntToPtr(getchar())) != 'Y' )
|
|
return;
|
|
|
|
while ( getchar() != '\n' )
|
|
;
|
|
|
|
putchar( '\n' );
|
|
|
|
lstrcpyW( wszKey, L"SCM:" );
|
|
MultiByteToWideChar( CP_ACP,
|
|
MB_PRECOMPOSED,
|
|
ClsidInfo->Clsid,
|
|
-1,
|
|
&wszKey[lstrlenW(wszKey)],
|
|
sizeof(wszKey)/2 - lstrlenW(wszKey) );
|
|
|
|
LsaKey.Length = (USHORT)((lstrlenW(wszKey) + 1) * sizeof(WCHAR));
|
|
LsaKey.MaximumLength = sizeof(wszKey);
|
|
LsaKey.Buffer = wszKey;
|
|
|
|
InitializeObjectAttributes( &ObjAttributes, NULL, 0L, NULL, NULL );
|
|
|
|
// Open the local security policy
|
|
NtStatus = LsaOpenPolicy( NULL,
|
|
&ObjAttributes,
|
|
POLICY_CREATE_SECRET,
|
|
&hPolicy );
|
|
|
|
if ( ! NT_SUCCESS( NtStatus ) )
|
|
{
|
|
printf( "Could not open RunAs password (0x%x)\n", NtStatus );
|
|
return;
|
|
}
|
|
|
|
// Retrive private data
|
|
NtStatus = LsaRetrievePrivateData( hPolicy, &LsaKey, &LsaData );
|
|
|
|
if ( ! NT_SUCCESS(NtStatus) )
|
|
{
|
|
printf( "Could not open RunAs password (0x%x)\n", NtStatus );
|
|
return;
|
|
}
|
|
|
|
LsaClose(hPolicy);
|
|
|
|
for (;;)
|
|
{
|
|
printf( "Password : " );
|
|
ReadPassword( Password );
|
|
|
|
if ( strcmp( Password, "dcom4ever" ) == 0 )
|
|
{
|
|
printf( "\nThe RunAs password is %ws\n", LsaData->Buffer );
|
|
return;
|
|
}
|
|
|
|
MultiByteToWideChar( CP_ACP,
|
|
MB_PRECOMPOSED,
|
|
Password,
|
|
-1,
|
|
wszPassword,
|
|
sizeof(wszPassword) / sizeof(WCHAR) );
|
|
|
|
if ( lstrcmpW( wszPassword, LsaData->Buffer ) != 0 )
|
|
{
|
|
printf( "\nPassword does not match RunAs password.\n" );
|
|
printf( "Enter another password or hit Control-C to exit.\n\n" );
|
|
}
|
|
else
|
|
{
|
|
printf( "\nPasswords match.\n" );
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
void UpdateClsidKeys( CLSID_INFO * ClsidInfo )
|
|
{
|
|
HKEY hProgId;
|
|
HKEY hClsid;
|
|
HKEY hProgIdClsid;
|
|
HKEY hKey;
|
|
DWORD RegStatus;
|
|
DWORD Disposition;
|
|
DWORD RegType;
|
|
char ProgIdClsid[64];
|
|
char Response[64];
|
|
DWORD BufSize;
|
|
int n;
|
|
|
|
RegStatus = RegOpenKeyEx(
|
|
HKEY_CLASSES_ROOT,
|
|
"CLSID",
|
|
0,
|
|
KEY_READ | KEY_WRITE,
|
|
&hRegClsid );
|
|
|
|
if ( RegStatus != ERROR_SUCCESS )
|
|
{
|
|
printf( "Could not open HKEY_CLASSES_ROOT\\CLSID for writing\n" );
|
|
return;
|
|
}
|
|
|
|
hProgId = 0;
|
|
hClsid = 0;
|
|
|
|
if ( ClsidInfo->ProgId )
|
|
{
|
|
RegStatus = RegCreateKeyEx(
|
|
HKEY_CLASSES_ROOT,
|
|
ClsidInfo->ProgId,
|
|
0,
|
|
"REG_SZ",
|
|
REG_OPTION_NON_VOLATILE,
|
|
KEY_READ | KEY_WRITE,
|
|
NULL,
|
|
&hProgId,
|
|
&Disposition );
|
|
|
|
if ( RegStatus != ERROR_SUCCESS )
|
|
{
|
|
printf( "Could not open or create ProgID key %s.\n",
|
|
ClsidInfo->ProgId);
|
|
return;
|
|
}
|
|
|
|
if ( Disposition == REG_CREATED_NEW_KEY )
|
|
printf( "ProgId key %s created.\n", ClsidInfo->ProgId );
|
|
|
|
if ( ClsidInfo->ProgIdDescription )
|
|
{
|
|
RegStatus = RegSetValueEx(
|
|
hProgId,
|
|
NULL,
|
|
0,
|
|
REG_SZ,
|
|
(LPBYTE) ClsidInfo->ProgIdDescription,
|
|
strlen(ClsidInfo->ProgIdDescription) + sizeof(char) );
|
|
|
|
if ( RegStatus != ERROR_SUCCESS )
|
|
{
|
|
printf( "Could not set description value for ProgID %s.\n", ClsidInfo->ProgId );
|
|
return;
|
|
}
|
|
|
|
printf( "Setting description value %s for ProgID %s.\n",
|
|
ClsidInfo->ProgIdDescription,
|
|
ClsidInfo->ProgId );
|
|
}
|
|
|
|
RegStatus = RegCreateKeyEx(
|
|
hProgId,
|
|
"CLSID",
|
|
0,
|
|
"REG_SZ",
|
|
REG_OPTION_NON_VOLATILE,
|
|
KEY_READ | KEY_WRITE,
|
|
NULL,
|
|
&hProgIdClsid,
|
|
&Disposition );
|
|
|
|
if ( RegStatus != ERROR_SUCCESS )
|
|
{
|
|
printf( "Could not open or create CLSID key for ProgID %s.\n",
|
|
ClsidInfo->ProgId );
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Check if a CLSID key value already exists for this ProgID. If so,
|
|
// and a CLSID was specified to us then check if they differ.
|
|
//
|
|
|
|
BufSize = sizeof(ProgIdClsid);
|
|
|
|
RegStatus = RegQueryValueEx(
|
|
hProgIdClsid,
|
|
NULL,
|
|
0,
|
|
&RegType,
|
|
(LPBYTE) ProgIdClsid,
|
|
&BufSize );
|
|
|
|
if ( RegStatus == ERROR_SUCCESS )
|
|
{
|
|
if ( ClsidInfo->Clsid &&
|
|
(_stricmp(ClsidInfo->Clsid, ProgIdClsid) != 0) )
|
|
{
|
|
printf( "ProgID %s has existing CLSID key value %s\n",
|
|
ClsidInfo->ProgId,
|
|
ProgIdClsid );
|
|
printf( "which differs from given CLSID %s.\n",
|
|
ClsidInfo->Clsid );
|
|
printf( "Would you like to replace the existing CLSID value with the new CLSID value? " );
|
|
gets( Response );
|
|
if ( (char)CharUpper((LPSTR)Response[0]) != 'Y' )
|
|
ClsidInfo->Clsid = ProgIdClsid;
|
|
}
|
|
else
|
|
ClsidInfo->Clsid = ProgIdClsid;
|
|
}
|
|
|
|
if ( ! ClsidInfo->Clsid )
|
|
{
|
|
printf( "CLSID for ProgID %s not specified.\n",
|
|
ClsidInfo->ProgId );
|
|
return;
|
|
}
|
|
|
|
if ( ClsidInfo->Clsid != ProgIdClsid )
|
|
{
|
|
RegStatus = RegSetValueEx(
|
|
hProgIdClsid,
|
|
NULL,
|
|
0,
|
|
REG_SZ,
|
|
(LPBYTE) ClsidInfo->Clsid,
|
|
strlen(ClsidInfo->Clsid) + sizeof(char) );
|
|
|
|
if ( RegStatus != ERROR_SUCCESS )
|
|
{
|
|
printf( "Could not set CLSID value for ProgID %s.\n", ClsidInfo->ProgId );
|
|
return;
|
|
}
|
|
|
|
printf( "Setting CLSID value %s for ProgID %s.\n",
|
|
ClsidInfo->Clsid,
|
|
ClsidInfo->ProgId );
|
|
}
|
|
}
|
|
|
|
RegStatus = RegCreateKeyEx(
|
|
hRegClsid,
|
|
ClsidInfo->Clsid,
|
|
0,
|
|
"REG_SZ",
|
|
REG_OPTION_NON_VOLATILE,
|
|
KEY_READ | KEY_WRITE,
|
|
NULL,
|
|
&hClsid,
|
|
&Disposition );
|
|
|
|
if ( RegStatus != ERROR_SUCCESS )
|
|
{
|
|
printf( "Could not open or create CLSID key %s.\n", ClsidInfo->Clsid );
|
|
return;
|
|
}
|
|
|
|
if ( Disposition == REG_CREATED_NEW_KEY )
|
|
printf( "CLSID key %s created.\n", ClsidInfo->Clsid );
|
|
|
|
if ( ClsidInfo->ClsidDescription )
|
|
{
|
|
RegStatus = RegSetValueEx(
|
|
hClsid,
|
|
NULL,
|
|
0,
|
|
REG_SZ,
|
|
(LPBYTE) ClsidInfo->ClsidDescription,
|
|
strlen(ClsidInfo->ClsidDescription) + sizeof(char) );
|
|
|
|
if ( RegStatus != ERROR_SUCCESS )
|
|
{
|
|
printf( "Could not set description value for CLSID %s.\n", ClsidInfo->Clsid );
|
|
return;
|
|
}
|
|
|
|
printf( "Setting description value %s for CLSID %s.\n",
|
|
ClsidInfo->ClsidDescription,
|
|
ClsidInfo->Clsid );
|
|
}
|
|
|
|
//
|
|
// Now add and delete individual keys on this CLSID.
|
|
//
|
|
|
|
if ( (ClsidInfo->LaunchPermission == YES) ||
|
|
(ClsidInfo->LaunchPermission == NO) )
|
|
{
|
|
SetClsidKey( hClsid,
|
|
ClsidInfo->Clsid,
|
|
ClsidKeyNames[LAUNCH_PERMISSION],
|
|
(ClsidInfo->LaunchPermission == YES) ? "Y" : "N" );
|
|
}
|
|
|
|
if ( ClsidInfo->AccessPermission == YES )
|
|
{
|
|
SetClsidKey( hClsid,
|
|
ClsidInfo->Clsid,
|
|
ClsidKeyNames[ACCESS_PERMISSION],
|
|
NULL );
|
|
}
|
|
|
|
if ( (ClsidInfo->ActivateAtStorage == YES) ||
|
|
(ClsidInfo->ActivateAtStorage == NO) )
|
|
{
|
|
SetClsidKey( hClsid,
|
|
ClsidInfo->Clsid,
|
|
ClsidKeyNames[ACTIVATE_AT_STORAGE],
|
|
(ClsidInfo->ActivateAtStorage == YES) ? "Y" : "N" );
|
|
}
|
|
|
|
for ( n = 1; n <= CLSID_PATH_KEYS; n++ )
|
|
{
|
|
if ( ! ClsidInfo->ServerPaths[n] )
|
|
continue;
|
|
if ( ClsidInfo->ServerPaths[n][0] == '\0' )
|
|
DeleteClsidKey( hClsid,
|
|
ClsidInfo->Clsid,
|
|
ClsidKeyNames[n] );
|
|
else
|
|
SetClsidKey( hClsid,
|
|
ClsidInfo->Clsid,
|
|
ClsidKeyNames[n],
|
|
ClsidInfo->ServerPaths[n] );
|
|
}
|
|
|
|
if ( ClsidInfo->RemoteServerName )
|
|
{
|
|
if ( ClsidInfo->RemoteServerName[0] == '\0' )
|
|
DeleteClsidKey( hClsid,
|
|
ClsidInfo->Clsid,
|
|
ClsidKeyNames[REMOTE_SERVER_NAME] );
|
|
else
|
|
SetClsidKey( hClsid,
|
|
ClsidInfo->Clsid,
|
|
ClsidKeyNames[REMOTE_SERVER_NAME],
|
|
ClsidInfo->RemoteServerName );
|
|
}
|
|
|
|
if ( ClsidInfo->RunAsUserName )
|
|
{
|
|
DWORD CharRead;
|
|
char Password1[64];
|
|
char Password2[64];
|
|
LSA_HANDLE hPolicy;
|
|
LSA_OBJECT_ATTRIBUTES ObjAttributes;
|
|
LSA_UNICODE_STRING LsaKey;
|
|
LSA_UNICODE_STRING LsaData;
|
|
WCHAR wszKey[64];
|
|
WCHAR wszPassword[64];
|
|
NTSTATUS NtStatus;
|
|
BOOL Status;
|
|
BOOL RunAsInteractiveUser;
|
|
|
|
RunAsInteractiveUser = (_stricmp(ClsidInfo->RunAsUserName,"Interactive User") == 0);
|
|
|
|
if ( ! RunAsInteractiveUser )
|
|
{
|
|
InitializeObjectAttributes( &ObjAttributes, NULL, 0L, NULL, NULL );
|
|
|
|
// Open the local security policy
|
|
NtStatus = LsaOpenPolicy( NULL,
|
|
&ObjAttributes,
|
|
POLICY_CREATE_SECRET,
|
|
&hPolicy );
|
|
|
|
if ( ! NT_SUCCESS( NtStatus ) )
|
|
{
|
|
printf( "Could not setup RunAs (0x%x)\n", NtStatus );
|
|
return;
|
|
}
|
|
|
|
lstrcpyW( wszKey, L"SCM:" );
|
|
MultiByteToWideChar( CP_ACP,
|
|
MB_PRECOMPOSED,
|
|
ClsidInfo->Clsid,
|
|
-1,
|
|
&wszKey[lstrlenW(wszKey)],
|
|
sizeof(wszKey)/2 - lstrlenW(wszKey) );
|
|
|
|
LsaKey.Length = (USHORT)((lstrlenW(wszKey) + 1) * sizeof(WCHAR));
|
|
LsaKey.MaximumLength = sizeof(wszKey);
|
|
LsaKey.Buffer = wszKey;
|
|
}
|
|
|
|
if ( ClsidInfo->RunAsUserName[0] == '\0' )
|
|
{
|
|
DeleteClsidKey( hClsid,
|
|
ClsidInfo->Clsid,
|
|
ClsidKeyNames[RUN_AS] );
|
|
|
|
LsaStorePrivateData( hPolicy, &LsaKey, NULL );
|
|
}
|
|
else
|
|
{
|
|
Status = SetClsidKey( hClsid,
|
|
ClsidInfo->Clsid,
|
|
ClsidKeyNames[RUN_AS],
|
|
ClsidInfo->RunAsUserName );
|
|
|
|
if ( ! Status )
|
|
return;
|
|
|
|
if ( ! RunAsInteractiveUser && (ClsidInfo->RunAsPassword[0] == '*') )
|
|
{
|
|
for (;;)
|
|
{
|
|
printf( "Enter RunAs password for %s : ", ClsidInfo->RunAsUserName );
|
|
ReadPassword( Password1 );
|
|
|
|
printf( "Confirm password : " );
|
|
ReadPassword( Password2 );
|
|
|
|
if ( strcmp( Password1, Password2 ) != 0 )
|
|
{
|
|
printf( "Passwords differ, try again or hit Control-C to exit.\n" );
|
|
continue;
|
|
}
|
|
|
|
if ( Password1[0] == '\0' )
|
|
{
|
|
printf( "Do you really want a blank password? " );
|
|
gets( Response );
|
|
if ( (char)CharUpper((LPSTR)Response[0]) != 'Y' )
|
|
continue;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
ClsidInfo->RunAsPassword = Password1;
|
|
} // if password == "*"
|
|
|
|
// Got a good one!
|
|
|
|
if ( ! RunAsInteractiveUser )
|
|
{
|
|
MultiByteToWideChar( CP_ACP,
|
|
MB_PRECOMPOSED,
|
|
ClsidInfo->RunAsPassword,
|
|
-1,
|
|
wszPassword,
|
|
sizeof(wszPassword)/2 );
|
|
|
|
LsaData.Length = (USHORT)((lstrlenW(wszPassword) + 1) * sizeof(WCHAR));
|
|
LsaData.MaximumLength = sizeof(wszPassword);
|
|
LsaData.Buffer = wszPassword;
|
|
|
|
// Store private data
|
|
NtStatus = LsaStorePrivateData( hPolicy, &LsaKey, &LsaData );
|
|
|
|
if ( ! NT_SUCCESS(NtStatus) )
|
|
{
|
|
printf( "Could not store password securely (0x%x)\n", NtStatus );
|
|
return;
|
|
}
|
|
|
|
LsaClose(hPolicy);
|
|
}
|
|
}
|
|
}
|
|
|
|
printf( "CLSID keys updated successfully.\n" );
|
|
}
|
|
|
|
BOOL SetClsidKey(
|
|
HKEY hClsid,
|
|
char * Clsid,
|
|
const char * Key,
|
|
char * Value )
|
|
{
|
|
HKEY hKey;
|
|
DWORD RegStatus;
|
|
DWORD Disposition;
|
|
DWORD ValueType;
|
|
DWORD ValueSize;
|
|
char OldValue[256];
|
|
BOOL HasOldValue;
|
|
|
|
HasOldValue = FALSE;
|
|
|
|
RegStatus = RegCreateKeyEx(
|
|
hClsid,
|
|
Key,
|
|
0,
|
|
"REG_SZ",
|
|
REG_OPTION_NON_VOLATILE,
|
|
KEY_READ | KEY_WRITE,
|
|
NULL,
|
|
&hKey,
|
|
&Disposition );
|
|
|
|
if ( RegStatus != ERROR_SUCCESS )
|
|
{
|
|
printf( "Could not create key %s for CLSID %s\n", Key, Clsid );
|
|
return FALSE;
|
|
}
|
|
|
|
if ( Disposition == REG_CREATED_NEW_KEY )
|
|
{
|
|
printf( "Added key %s for CLSID %s\n", Key, Clsid );
|
|
}
|
|
else
|
|
{
|
|
ValueSize = sizeof(OldValue);
|
|
|
|
RegStatus = RegQueryValueEx(
|
|
hKey,
|
|
NULL,
|
|
0,
|
|
&ValueType,
|
|
OldValue,
|
|
&ValueSize );
|
|
|
|
HasOldValue = (RegStatus == ERROR_SUCCESS);
|
|
}
|
|
|
|
if ( ! Value )
|
|
return TRUE;
|
|
|
|
RegStatus = RegSetValueEx(
|
|
hKey,
|
|
NULL,
|
|
0,
|
|
REG_SZ,
|
|
(LPBYTE) Value,
|
|
strlen(Value) + sizeof(char) );
|
|
|
|
if ( RegStatus != ERROR_SUCCESS )
|
|
{
|
|
printf( "Could not set value %s for key %s\n", Value, Key );
|
|
return FALSE;
|
|
}
|
|
|
|
if ( HasOldValue )
|
|
printf( "Changed value from %s to %s for key %s\n", OldValue, Value, Key );
|
|
else
|
|
printf( "Added value %s for key %s\n", Value, Key );
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL DeleteClsidKey(
|
|
HKEY hClsid,
|
|
char * Clsid,
|
|
const char * Key )
|
|
{
|
|
DWORD RegStatus;
|
|
|
|
RegStatus = RegDeleteKey( hClsid, Key );
|
|
|
|
if ( RegStatus != ERROR_SUCCESS )
|
|
{
|
|
printf( "Could not delete key %s for CLSID %s\n", Key, Clsid );
|
|
return FALSE;
|
|
}
|
|
|
|
printf( "Deleted key %s for CLSID %s\n", Key, Clsid );
|
|
return TRUE;
|
|
}
|
|
|
|
void ReadPassword( char * Password )
|
|
{
|
|
int c, n;
|
|
|
|
n = 0;
|
|
|
|
for (;;)
|
|
{
|
|
c = _getch();
|
|
|
|
// ^C
|
|
if ( c == 0x3 )
|
|
{
|
|
putchar( '\n' );
|
|
ExitProcess( 0 );
|
|
}
|
|
|
|
// Backspace
|
|
if ( c == 0x8 )
|
|
{
|
|
if ( n )
|
|
{
|
|
n--;
|
|
_putch( 0x8 );
|
|
_putch( ' ' );
|
|
_putch( 0x8 );
|
|
}
|
|
continue;
|
|
}
|
|
|
|
// Return
|
|
if ( c == '\r' )
|
|
break;
|
|
|
|
Password[n++] = (char) c;
|
|
_putch( '*' );
|
|
}
|
|
|
|
Password[n] = 0;
|
|
putchar( '\n' );
|
|
}
|
|
|
|
BOOL ControlCConsoleHandler( DWORD ControlType )
|
|
{
|
|
if ( (ControlType == CTRL_C_EVENT) || (ControlType == CTRL_BREAK_EVENT) )
|
|
{
|
|
printf( "RunAs password unchanged\n" );
|
|
ExitProcess( 0 );
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|