Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

481 lines
11 KiB

#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0500
#endif
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include "webcaum.h"
#include "..\..\shared\common.h"
#include "..\..\shared\apppool.h"
bool AddAccessRights( TCHAR *lpszFileName, TCHAR *szUserName, DWORD dwAccessMask )
{
//
// SID variables.
//
SID_NAME_USE snuType;
TCHAR * szDomain = NULL;
DWORD cbDomain = 0;
//
// User name variables.
//
LPVOID pUserSID = NULL;
DWORD cbUserSID = 0;
DWORD cbUserName = 0;
//
// File SD variables.
//
PSECURITY_DESCRIPTOR pFileSD = NULL;
DWORD cbFileSD = 0;
//
// New SD variables.
//
PSECURITY_DESCRIPTOR pNewSD = NULL;
//
// ACL variables.
//
PACL pACL = NULL;
BOOL fDaclPresent;
BOOL fDaclDefaulted;
ACL_SIZE_INFORMATION AclInfo;
//
// New ACL variables.
//
PACL pNewACL = NULL;
DWORD cbNewACL = 0;
//
// Temporary ACE.
//
LPVOID pTempAce = NULL;
UINT CurrentAceIndex;
bool fResult = false;
BOOL fAPISuccess;
// error code
DWORD lastErr = 0;
try
{
//
// Call this API once to get the buffer sizes ( it will return ERROR_INSUFFICIENT_BUFFER )
//
fAPISuccess = LookupAccountName( NULL, szUserName, pUserSID, &cbUserSID, szDomain, &cbDomain, &snuType );
if( fAPISuccess )
{
throw E_FAIL; // we throw some fake error to skip through to the exit door
}
else if( GetLastError() != ERROR_INSUFFICIENT_BUFFER )
{
lastErr = GetLastError();
LogError( TEXT( "LookupAccountName() failed" ), lastErr );
throw lastErr;
}
//
// allocate the buffers
//
pUserSID = calloc( cbUserSID, 1 );
if( !pUserSID )
{
lastErr = GetLastError();
LogError( TEXT( "Alloc() for UserSID failed" ), lastErr );
throw lastErr;
}
szDomain = ( TCHAR * ) calloc( cbDomain + sizeof TCHAR, sizeof TCHAR );
if( !szDomain )
{
lastErr = GetLastError();
LogError( TEXT( "Alloc() for szDomain failed" ), lastErr );
throw lastErr;
}
//
// The LookupAccountName function accepts the name of a system and an account as input.
// It retrieves a security identifier ( SID ) for the account and
// the name of the domain on which the account was found
//
fAPISuccess = LookupAccountName( NULL /* = local computer */, szUserName, pUserSID, &cbUserSID, szDomain, &cbDomain, &snuType );
if( !fAPISuccess )
{
lastErr = GetLastError();
LogError( TEXT( "LookupAccountName() failed" ), lastErr );
throw lastErr;
}
//
// call this API once to get the buffer sizes
// API should have failed with insufficient buffer.
//
fAPISuccess = GetFileSecurity( lpszFileName, DACL_SECURITY_INFORMATION, pFileSD, 0, &cbFileSD );
if( fAPISuccess )
{
throw E_FAIL;
}
else if( GetLastError() != ERROR_INSUFFICIENT_BUFFER )
{
lastErr = GetLastError();
LogError( TEXT( "GetFileSecurity() failed" ), lastErr );
throw lastErr;
}
//
// allocate the buffers
//
pFileSD = calloc( cbFileSD, 1 );
if( !pFileSD )
{
lastErr = GetLastError();
LogError( TEXT( "Alloc() for pFileSD failed" ), lastErr );
throw lastErr;
}
//
// call the api to get the actual data
//
fAPISuccess = GetFileSecurity( lpszFileName, DACL_SECURITY_INFORMATION, pFileSD, cbFileSD, &cbFileSD );
if( !fAPISuccess )
{
lastErr = GetLastError();
LogError( TEXT( "GetFileSecurity() failed" ), lastErr );
throw lastErr;
}
//
// Initialize new SD.
//
pNewSD = calloc( cbFileSD, 1 ); // Should be same size as FileSD.
if( !pNewSD )
{
lastErr = GetLastError();
LogError( TEXT( "Alloc() for pNewDS failed" ), GetLastError() );
throw lastErr;
}
if( !InitializeSecurityDescriptor( pNewSD, SECURITY_DESCRIPTOR_REVISION ) )
{
lastErr = GetLastError();
LogError( TEXT( "InitializeSecurityDescriptor() failed" ), lastErr );
throw lastErr;
}
//
// Get DACL from SD.
//
if( !GetSecurityDescriptorDacl( pFileSD, &fDaclPresent, &pACL, &fDaclDefaulted ) )
{
lastErr = GetLastError();
LogError( TEXT( "GetSecurityDescriptorDacl() failed" ), lastErr );
throw lastErr;
}
//
// Get size information for DACL.
//
AclInfo.AceCount = 0; // Assume NULL DACL.
AclInfo.AclBytesFree = 0;
AclInfo.AclBytesInUse = sizeof( ACL ); // If not NULL DACL, gather size information from DACL.
if( fDaclPresent && pACL )
{
if( !GetAclInformation( pACL, &AclInfo, sizeof( ACL_SIZE_INFORMATION ), AclSizeInformation ) )
{
lastErr = GetLastError();
LogError( TEXT( "GetAclInformation() failed" ), lastErr );
throw lastErr;
}
}
//
// Compute size needed for the new ACL.
//
cbNewACL = AclInfo.AclBytesInUse + sizeof( ACCESS_ALLOWED_ACE ) + GetLengthSid( pUserSID );
//
// Allocate memory for new ACL.
//
pNewACL = ( PACL ) calloc( cbNewACL, 1 );
if( !pNewACL )
{
lastErr = GetLastError();
LogError( TEXT( "HeapAlloc() failed" ), lastErr );
throw lastErr;
}
//
// Initialize the new ACL.
//
if( !InitializeAcl( pNewACL, cbNewACL, ACL_REVISION2 ) )
{
lastErr = GetLastError();
LogError( TEXT( "InitializeAcl() failed" ), lastErr );
throw lastErr;
}
//
// Add the access-allowed ACE to the new DACL.
//
ACE_HEADER aceheader = {0};
aceheader.AceFlags = CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE;
aceheader.AceSize = sizeof( ACE_HEADER );
aceheader.AceType = ACCESS_ALLOWED_OBJECT_ACE_TYPE;
if( !AddAccessAllowedAceEx( pNewACL, ACL_REVISION2, aceheader.AceFlags, dwAccessMask, pUserSID ) )
{
lastErr = GetLastError();
LogError( TEXT( "AddAccessAllowedAce() failed" ), lastErr );
throw lastErr;
}
//
// If DACL is present, copy it to a new DACL.
//
if( fDaclPresent )
{
//
// Copy the file's ACEs to the new ACL
//
if( AclInfo.AceCount )
{
for( CurrentAceIndex = 0; CurrentAceIndex < AclInfo.AceCount; CurrentAceIndex++ )
{
//
// Get an ACE.
//
if( !GetAce( pACL, CurrentAceIndex, &pTempAce ) )
{
lastErr = GetLastError();
LogError( TEXT( "GetAce() failed" ), lastErr );
throw lastErr;
}
//
// Add the ACE to the new ACL.
//
if( !AddAce( pNewACL, ACL_REVISION, MAXDWORD, pTempAce, ( ( PACE_HEADER ) pTempAce )->AceSize ) )
{
lastErr = GetLastError();
LogError( TEXT( "AddAce() failed" ), lastErr );
throw lastErr;
}
}
}
}
//
// Set the new DACL to the file SD.
//
if( !SetSecurityDescriptorDacl( pNewSD, TRUE, pNewACL, FALSE ) )
{
lastErr = GetLastError();
LogError( TEXT( "SetSecurityDescriptorDacl() failed" ), lastErr );
lastErr;
}
//
// Set the SD to the File.
//
if( !SetFileSecurity( lpszFileName, DACL_SECURITY_INFORMATION, pNewSD ) )
{
lastErr = GetLastError();
LogError( TEXT( "SetFileSecurity() failed" ), lastErr );
throw lastErr;
}
fResult = TRUE;
}
catch (...)
{
fResult = FALSE;
}
//
// Free allocated memory
//
if( pUserSID )
free( pUserSID );
if( szDomain )
free( szDomain );
if( pFileSD )
free( pFileSD );
if( pNewSD )
free( pNewSD );
if( pNewACL )
free( pNewACL );
return fResult;
}
//----------------------------------------------------------------------------
// give the domain account read access to the webroot folder and subfolders
//
bool SetUDDIFolderDacls( TCHAR *szUserName )
{
ENTER();
TCHAR szUDDIInstallPath[ MAX_PATH + 1 ];
TCHAR szSubfolderPath[ MAX_PATH + 1 ];
//
// get UDDI install location ( it already has a backslash )
//
if( !GetUDDIInstallPath( szUDDIInstallPath, MAX_PATH ) )
return false;
//
// give read access to the webroot folder
//
_sntprintf( szSubfolderPath, MAX_PATH, TEXT( "%s%s" ), szUDDIInstallPath, TEXT( "webroot\\" ) );
SetFolderAclRecurse( szSubfolderPath, szUserName );
return true;
}
//-------------------------------------------------------------------*
bool SetFolderAclRecurse( PTCHAR szDirName, PTCHAR szUserName, DWORD dwAccessMask )
{
//
// add the ACE for this folder
//
Log( TEXT( "Giving %s access to folder %s" ), szUserName, szDirName );
if( !AddAccessRights( szDirName, szUserName, dwAccessMask ) )
{
LogError( TEXT( "Error:" ), GetLastError() );
return false;
}
//
// search any subdirectories:
//
TCHAR tmpFileName[MAX_PATH];
_tcscpy( tmpFileName, szDirName );
_tcscat( tmpFileName, TEXT( "*" ) );
WIN32_FIND_DATA FindData;
HANDLE hFindFile = FindFirstFileEx( tmpFileName, FindExInfoStandard, &FindData,
FindExSearchLimitToDirectories, NULL, 0 );
if( hFindFile == INVALID_HANDLE_VALUE )
{
return true;
}
do
{
// make sure it's really a directory
if( FILE_ATTRIBUTE_DIRECTORY & FindData.dwFileAttributes &&
0 != _tcscmp( FindData.cFileName, TEXT( "." ) ) &&
0 != _tcscmp( FindData.cFileName, TEXT( ".." ) ) )
{
_tcscpy( tmpFileName, szDirName );
_tcscat( tmpFileName, FindData.cFileName );
_tcscat( tmpFileName, TEXT( "\\" ) );
// recursively call this routine
if( !SetFolderAclRecurse( tmpFileName, szUserName ) )
{
FindClose( hFindFile );
return false;
}
}
}
while( FindNextFile( hFindFile, &FindData ) );
// clean up
FindClose( hFindFile );
return true;
}
//-------------------------------------------------------------------*
bool SetWindowsTempDacls( TCHAR *szUserName )
{
//
// Get the windows temp directory.
//
TCHAR *systemTemp = GetSystemTemp();
if( NULL == systemTemp )
{
return false;
}
//
// Add the rights
//
bool rightsAdded = AddAccessRights( systemTemp, szUserName, GENERIC_READ );
//
// Clean up
//
delete[] systemTemp;
systemTemp = NULL;
return rightsAdded;
}
TCHAR * GetSystemTemp()
{
TCHAR *TEMP = _T( "\\TEMP\\" );
//
// Get the WINDIR environment variable
//
DWORD valueSize = GetEnvironmentVariable( L"WINDIR", NULL, NULL );
if( 0 == valueSize )
{
return NULL;
}
//
// Keep in mind that we need to append \\TEMP to our string as well.
//
valueSize += ( DWORD) _tcslen( TEMP );
TCHAR *valueBuffer = NULL;
valueBuffer = new TCHAR[ valueSize ];
ZeroMemory( valueBuffer, valueSize );
if( NULL == valueBuffer )
{
return NULL;
}
DWORD realSize = GetEnvironmentVariable( L"WINDIR", valueBuffer, valueSize );
if( 0 == realSize || realSize > valueSize )
{
delete[] valueBuffer;
valueBuffer = NULL;
return NULL;
}
//
// Append a \\TEMP to it
//
_tcsncat( valueBuffer, TEMP, _tcslen( TEMP ) );
//
// Make sure we have null terminated.
//
valueBuffer[ valueSize - 1] = 0;
//
// Return the value
//
return valueBuffer;
}