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.
 
 
 
 
 
 

629 lines
16 KiB

/*++
Copyright (c) 2001 Microsoft Corporation
Module Name :
common.cxx
Abstract:
Class that are used to do a number of commonly needed things
Author:
Christopher Achille (cachille)
Project:
Internet Services Setup
Revision History:
August 2001: Created
--*/
#include "stdafx.h"
#include "common.hxx"
#include "dcomperm.h"
// function: VerifyParameters
//
// Verify the parameters are correct
//
// Parameters of ciParams
// 0 params - The caller want to know if this is an upgrade, period
// 2 params - The caller wants to know if this is an upgrade in the range from param(0) to param(1) (inclusive)
//
BOOL
CIsUpgrade::VerifyParameters(CItemList &ciParams)
{
if ( ( ciParams.GetNumberOfItems() == 0 ) ||
( ( ciParams.GetNumberOfItems() == 2 ) &&
( ciParams.IsNumber(0) ) &&
( ciParams.IsNumber(1) )
)
)
{
return TRUE;
}
return FALSE;
}
// function: GetMethodName
//
// Returns the name of the CIsMetabase call
//
LPTSTR
CIsUpgrade::GetMethodName()
{
return _T("IsUpgrade");
}
// function: DoInternalWork
//
// Do the Verification of the upgrade
//
BOOL
CIsUpgrade::DoInternalWork(CItemList &ciParams)
{
BOOL fRet = TRUE;
DWORD dwUpgradeType = g_pTheApp->m_eUpgradeType;
// Init return to installmode==upgrade
fRet = g_pTheApp->m_eInstallMode == IM_UPGRADE;
if (ciParams.GetNumberOfItems() == 0)
{
// We only wanted to know if it was an upgrade, so return
return fRet;
}
// Check lower bound
if (fRet)
{
DWORD dwMin = ciParams.GetNumber(0);
switch ( dwUpgradeType )
{
case UT_10:
case UT_10_W95:
fRet = dwMin <= 1;
break;
case UT_20:
fRet = dwMin <= 2;
break;
case UT_30:
case UT_351:
fRet = dwMin <= 3;
break;
case UT_40:
fRet = dwMin <= 4;
break;
case UT_50:
case UT_51:
fRet = dwMin <= 5;
break;
case UT_60:
fRet = dwMin <= 6;
break;
default:
fRet = FALSE;
}
}
// Check upper bound
if (fRet)
{
DWORD dwMax = ciParams.GetNumber(1);
switch ( dwUpgradeType )
{
case UT_10:
case UT_10_W95:
fRet = dwMax >= 1;
break;
case UT_20:
fRet = dwMax >= 2;
break;
case UT_30:
case UT_351:
fRet = dwMax >= 3;
break;
case UT_40:
fRet = dwMax >= 4;
break;
case UT_50:
case UT_51:
fRet = dwMax >= 5;
break;
case UT_60:
fRet = dwMax >= 6;
break;
default:
fRet = FALSE;
} // switch
}
return fRet;
}
// function: AddAceToSD
//
// Add an ACE (Access Control List) to a Source Descriptor.
//
// Parameters:
// hObject - Handle to the object
// ObjectType - The type of object
// pszTustee - The trustee for new ACE
// TrusteeForm - The format of the trustee structure
// dwAccessRights - Access Mask for the New ACE
// AccessMode - Type of ACE
// dwInderitance - Inheritance Flags for ACE
// bAddToExisting - TRUE==add ace to existing ACL, FALSE==ignore existing ACL
//
// Return
// TRUE - It was successful
// FALSE - It failed
BOOL
CFileSys_Acl::AddAcetoSD( HANDLE hObject, // handle to object
SE_OBJECT_TYPE ObjectType, // type of object
LPTSTR pszTrustee, // trustee for new ACE
TRUSTEE_FORM TrusteeForm, // format of TRUSTEE structure
DWORD dwAccessRights, // access mask for new ACE
ACCESS_MODE AccessMode, // type of ACE
DWORD dwInheritance, // inheritance flags for new ACE
BOOL bAddToExisting // add the new ace to the old SD, if not create a new SD
)
{
DWORD dwErr = ERROR_SUCCESS;
PACL pNewDacl = NULL;
PACL pOldDacl = NULL;
EXPLICIT_ACCESS ea;
PSECURITY_DESCRIPTOR pSD = NULL;
if ( bAddToExisting )
{
// If we are adding, then lets retrieve the old SD
dwErr = GetSecurityInfo( hObject,
ObjectType,
DACL_SECURITY_INFORMATION,
NULL,
NULL,
&pOldDacl,
NULL,
&pSD);
if ( dwErr == ERROR_SUCCESS )
{
// It is possible that we did not retrieve any acl's for this file,
// so don't try to remove a user from them
if ( pOldDacl )
{
RemoveUserFromAcl( pOldDacl, pszTrustee);
}
}
}
// Create new SD with the new ACE
if ( dwErr == ERROR_SUCCESS )
{
ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
ea.grfAccessPermissions = dwAccessRights;
ea.grfAccessMode = AccessMode;
ea.grfInheritance = dwInheritance;
ea.Trustee.TrusteeForm = TrusteeForm;
ea.Trustee.ptstrName = pszTrustee;
dwErr = SetEntriesInAcl(1, &ea, pOldDacl, &pNewDacl);
}
if ( ( dwErr == ERROR_SUCCESS ) &&
( pNewDacl )
)
{
dwErr = SetSecurityInfo( hObject,
ObjectType,
DACL_SECURITY_INFORMATION |
( bAddToExisting ?
UNPROTECTED_DACL_SECURITY_INFORMATION :
PROTECTED_DACL_SECURITY_INFORMATION ),
NULL,
NULL,
pNewDacl,
NULL);
}
if ( pSD )
{
LocalFree( pSD );
}
if ( pNewDacl )
{
LocalFree( pNewDacl );
}
return dwErr == ERROR_SUCCESS;
}
// function: RemoveUserFromAcl
//
// Remove a User from the Acl
//
// Parameters
// pAcl - A pointer to the Acl
// szUserName - The user to remove
BOOL
CFileSys_Acl::RemoveUserFromAcl(PACL pAcl, LPTSTR szUserName)
{
BOOL bUserExisted;
do {
bUserExisted = FALSE;
// Keep removing until all instances of that user are gone.
} while ( ( RemovePrincipalFromACL(pAcl,szUserName,&bUserExisted) == ERROR_SUCCESS) && bUserExisted );
return TRUE;
}
// function: VerifyParameters
//
// Verify the parameters are correct
//
BOOL
CFileSys_AddAcl::VerifyParameters(CItemList &ciParams)
{
if ( ( ciParams.GetNumberOfItems() == 6 ) &&
ciParams.IsNumber(3) &&
ciParams.IsNumber(4) &&
ciParams.IsNumber(5)
)
{
return TRUE;
}
return FALSE;
}
// function: GetMethodName
//
// Return the Method Name for this Class
//
LPTSTR
CFileSys_AddAcl::GetMethodName()
{
return _T("FilSys_AddAcl");
}
// function: CreateFullFileName
//
// Create the Full FileName from the Path with wildcards, and the filename
//
// Parameters:
// buffFullFileName [out] - The FileName including the path
// szFullPathwithWildCard [in] - The search path (ie. c:\winnt\system32\inetsrv\*.*)
// szFileName [in] - The filename to append to the seach path (ie. asp.dll)
//
BOOL
CFileSys_Acl::CreateFullFileName(BUFFER &buffFullFileName, LPTSTR szFullPathwithWildCard, LPTSTR szFileName)
{
LPTSTR szLastSlash;
if ( !buffFullFileName.Resize( ( _tcslen(szFullPathwithWildCard) + _tcslen(szFileName) + 1 ) * sizeof(TCHAR) ) )
{
// Could not allocate memory needed
return FALSE;
}
// Copy the full path to the buffer
_tcscpy( (LPTSTR) buffFullFileName.QueryPtr(), szFullPathwithWildCard);
// Look for last part of path
szLastSlash = _tcsrchr( (LPTSTR) buffFullFileName.QueryPtr(), L'\\' );
if (!szLastSlash)
{
return FALSE;
}
// Copy the filename on top of the end of the path
_tcscpy( szLastSlash + 1, szFileName);
return TRUE;
}
// function: SetFileAcl
//
// Add the file/directory acl
//
BOOL
CFileSys_Acl::SetFileAcl(LPTSTR szFileName, LPTSTR szUserName, SE_OBJECT_TYPE ObjectType,
DWORD dwAccessMask, BOOL bAllowAccess, DWORD dwInheritable, BOOL bAddAcetoOriginal)
{
HANDLE hFile;
BOOL bRet;
hFile = CreateFile( szFileName,
WRITE_DAC|READ_CONTROL,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
NULL);
if ( hFile == INVALID_HANDLE_VALUE )
{
return FALSE;
}
bRet = AddAcetoSD( hFile, ObjectType, szUserName, TRUSTEE_IS_NAME, dwAccessMask,
bAllowAccess ? SET_ACCESS: DENY_ACCESS, dwInheritable,
bAddAcetoOriginal );
// bAllowAccess ? GRANT_ACCESS: DENY_ACCESS, dwInheritable);
CloseHandle( hFile );
return bRet;
}
// function: RemoveUserAcl
//
// Remove a User's ACL from a file
//
BOOL
CFileSys_Acl::RemoveUserAcl(LPTSTR szFile, LPTSTR szUserName)
{
HANDLE hFile;
DWORD dwErr;
PACL pDacl;
PSECURITY_DESCRIPTOR pSD = NULL;
hFile = CreateFile( szFile,
WRITE_DAC|READ_CONTROL,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
NULL);
if ( hFile == INVALID_HANDLE_VALUE )
{
return FALSE;
}
dwErr = GetSecurityInfo( hFile,
SE_FILE_OBJECT,
DACL_SECURITY_INFORMATION,
NULL,
NULL,
&pDacl,
NULL,
&pSD);
if ( ( dwErr == ERROR_SUCCESS ) &&
( pDacl )
)
{
RemoveUserFromAcl( pDacl, szUserName);
dwErr = SetSecurityInfo(hFile,
SE_FILE_OBJECT,
DACL_SECURITY_INFORMATION,
NULL,
NULL,
pDacl,
NULL);
}
CloseHandle( hFile );
if ( pSD )
{
LocalFree( pSD );
}
return dwErr == ERROR_SUCCESS;
}
// function: DoSetAcl
//
// Set or remove an ACL on a file.
// If it is Set, then we will either add or just set based on bIgnorePreviousAcls
//
// Parameters
// bAdd - Add the ace. FALSE==remove the ace from the acl
// bAddAcltoOrignial - TRUE==add ace, FALSE==do not add to old ace, just replace
//
// ciList - The list of the parameters from the inf file
// 0 - A list of files (full paths)
// 1 - The exclusion list, list of files to not be inclused (file names only)
// 2 - The user(s) to have access for
// the following are needed it bAdd is true...
// 3 - Access Mask
// 4 - bAllowAccess (FALSE==Denuy Access)
// 5 - Inheritance Flags
//
BOOL
CFileSys_Acl::DoAcling(CItemList &ciList, BOOL bAdd, BOOL bAddAcltoOriginal)
{
HANDLE hFileList;
WIN32_FIND_DATA sFD;
BUFFER BuffFullFileName;
CItemList ciExclusionList;
CItemList ciUserList;
// Load exclusion list, and userlist
if ( (!ciExclusionList.LoadSubList(ciList.GetItem(1))) ||
(!ciUserList.LoadSubList(ciList.GetItem(2)))
)
{
return FALSE;
}
if ( !_tcsstr( ciList.GetItem(0), _T("*")) )
{
for (DWORD i = 0; i < ciUserList.GetNumberOfItems(); i++)
{
if ( bAdd )
{
// It is only a single file, so only call it once
SetFileAcl( (LPTSTR) ciList.GetItem(0), // FileName
ciUserList.GetItem(i), // UserName
SE_FILE_OBJECT, // The type of object
ciList.GetNumber(3), // dwAccess Mask
ciList.GetNumber(4), // bAllow access
ciList.GetNumber(5), // bInhertance Flags
bAddAcltoOriginal );
}
else
{
RemoveUserAcl(ciList.GetItem(0),ciUserList.GetItem(i));
}
}
return TRUE;
}
hFileList = FindFirstFile( ciList.GetItem(0), &sFD );
if (hFileList == INVALID_HANDLE_VALUE)
{
return FALSE;
}
do {
if ( ( !ciExclusionList.FindItem( sFD.cFileName, FALSE ) ) &&
( _tcscmp( sFD.cFileName, _T(".") ) ) &&
( _tcscmp( sFD.cFileName, _T("..") ) ) &&
( CreateFullFileName( BuffFullFileName, ciList.GetItem(0), sFD.cFileName ) )
)
{
for (DWORD i = 0; i < ciUserList.GetNumberOfItems(); i++)
{
if ( bAdd )
{
SetFileAcl( (LPTSTR) BuffFullFileName.QueryPtr(), // FileName
ciUserList.GetItem(i), // UserName
SE_FILE_OBJECT, // The type of object
ciList.GetNumber(3), // dwAccess Mask
ciList.GetNumber(4), // bAllow access
ciList.GetNumber(5), // bInhertance Flags
bAddAcltoOriginal );
}
else
{
RemoveUserAcl((LPTSTR) BuffFullFileName.QueryPtr(),ciUserList.GetItem(i));
}
}
}
} while ( FindNextFile( hFileList, &sFD ) );
FindClose( hFileList );
return TRUE;
}
// function: DoInternalWork
//
// Add the Acl for the files specified
//
// Parameters
// ciList - The list of the parameters from the inf file
// 0 - A list of files (full paths)
// 1 - The exclusion list, list of files to not be inclused (file names only)
// 2 - The user(s) to have access for
// 3 - Access Mask
// 4 - bAllowAccess (FALSE==Denuy Access)
// 5 - Inheritance Flags
BOOL
CFileSys_AddAcl::DoInternalWork(CItemList &ciList)
{
return DoAcling( ciList, TRUE, TRUE );
}
// function: VerifyParameters
//
// Verify the parameters are correct
//
BOOL
CFileSys_RemoveAcl::VerifyParameters(CItemList &ciParams)
{
return ciParams.GetNumberOfItems() == 3;
}
// function: GetMethodName
//
// Return the Method Name for this Class
//
LPTSTR
CFileSys_RemoveAcl::GetMethodName()
{
return _T("FilSys_RemoveAcl");
}
// function: DoInternalWork
//
// Remove an Acl for a specific user
//
// Parameters
// ciList - The list of the parameters from the inf file
// 0 - A list of files (full paths)
// 1 - The exclusion list, list of files to not be inclused (file names only)
// 2 - The user(s) to remove access for
BOOL
CFileSys_RemoveAcl::DoInternalWork(CItemList &ciList)
{
return DoAcling( ciList, FALSE );
}
// function: VerifyParameters
//
// Verify the parameters are correct
//
BOOL
CFileSys_SetAcl::VerifyParameters(CItemList &ciParams)
{
if ( ( ciParams.GetNumberOfItems() == 6 ) &&
ciParams.IsNumber(3) &&
ciParams.IsNumber(4) &&
ciParams.IsNumber(5)
)
{
return TRUE;
}
return FALSE;
}
// function: GetMethodName
//
// Return the Method Name for this Class
//
LPTSTR
CFileSys_SetAcl::GetMethodName()
{
return _T("FilSys_SetAcl");
}
// function: DoInternalWork
//
// Set the Acl for the files specified (ignoring previous acl's)
//
// Parameters
// ciList - The list of the parameters from the inf file
// 0 - A list of files (full paths)
// 1 - The exclusion list, list of files to not be inclused (file names only)
// 2 - The user(s) to have access for
// 3 - Access Mask
// 4 - bAllowAccess (FALSE==Denuy Access)
// 5 - Inheritance Flags
BOOL
CFileSys_SetAcl::DoInternalWork(CItemList &ciList)
{
return DoAcling( ciList, TRUE, FALSE );
}