우리는 많은 시스템 관련 작업을 수행하는 DLL을 유지 관리합니다. 파일 시스템, 레지스트리 등을 순회하는 것입니다.이 DLL의 호출자는 가장을 사용하거나 사용하지 않을 수 있습니다. 가능한 모든 시나리오를보다 잘 지원하기 위해 나는 더 똑똑 해 지도록 수정하려고합니다. 파일을 삭제하는 예제를 사용하겠습니다. 현재 우리는 단지 DeleteFile()을 호출하고 이것이 실패하면 그 것이 끝납니다. 나는 다음을 생각해 냈다 :일시적으로 권한을 가장하여 권한을 부여 하시겠습니까?
BOOL TryReallyHardToDeleteFile(LPCTSTR lpFileName)
{
// 1. caller without privilege
BOOL bSuccess = DeleteFile(lpFileName);
DWORD dwError = GetLastError();
if(!bSuccess && dwError == ERROR_ACCESS_DENIED)
{
// failed with access denied; try with privilege
DWORD dwOldRestorePrivilege = 0;
BOOL bHasRestorePrivilege = SetPrivilege(SE_RESTORE_NAME, SE_PRIVILEGE_ENABLED, &dwOldRestorePrivilege);
if(bHasRestorePrivilege)
{
// 2. caller with privilege
bSuccess = DeleteFile(lpFileName);
dwError = GetLastError();
SetPrivilege(SE_RESTORE_NAME, dwOldRestorePrivilege, NULL);
}
if(!bSuccess && dwError == ERROR_ACCESS_DENIED)
{
// failed with access denied; if caller is impersonating then try as process
HANDLE hToken = NULL;
if(OpenThreadToken(GetCurrentThread(), TOKEN_QUERY | TOKEN_IMPERSONATE, TRUE, &hToken))
{
if(RevertToSelf())
{
// 3. process without privilege
bSuccess = DeleteFile(lpFileName);
dwError = GetLastError();
if(!bSuccess && dwError == ERROR_ACCESS_DENIED)
{
// failed with access denied; try with privilege
bHasRestorePrivilege = SetPrivilege(SE_RESTORE_NAME, SE_PRIVILEGE_ENABLED, &dwOldRestorePrivilege);
if(bHasRestorePrivilege)
{
// 4. process with privilege
bSuccess = DeleteFile(lpFileName);
dwError = GetLastError();
SetPrivilege(SE_RESTORE_NAME, dwOldRestorePrivilege, NULL);
}
}
SetThreadToken(NULL, hToken);
}
CloseHandle(hToken);
hToken = NULL;
}
}
}
if(!bSuccess)
{
SetLastError(dwError);
}
return bSuccess;
}
그래서 먼저 호출자로 시도한다. 액세스가 거부되어 실패하면 일시적으로 호출자의 토큰에서 권한을 활성화하고 다시 시도합니다. 액세스가 거부되어 호출자가 가장하는 경우 실패하고 일시적으로 거부하고 다시 시도합니다. 액세스가 거부되어 실패하면 일시적으로 프로세스 토큰에서 특권을 사용 가능하게하고 다시 시도합니다. 이것은 거의 모든 상황을 처리해야한다고 생각하지만, 이것을 달성하기위한 더 좋은 방법이 있는지 궁금합니다. 이 메소드를 사용할 가능성이있는 작업이 많이 있습니다 (예 : 보안 개체에 액세스하는 모든 작업).
바로 마지막 옵션으로 이동하지 않겠습니까? 예외 처리가 필요하지 않습니다. 올바르게 설명을 읽으면 제대로 작동합니다. – ChrisF
프로세스가 LocalSystem (즉 서비스)으로 실행되고 네트워크 위치의 파일을 읽어야하는 경우 (즉, 가장 된 사용자 계정 만 파일에 액세스 할 수 있음) 처리하지 못합니다. – Luke
@Chris : 그것은 또한 최소한 특권의 사고 방식에 반대합니다. 그 행동을 위해 필요한만큼의 권한 만 있으면됩니다. 그것은 일을하는 것이 더 힘든 방법이지만,보다 이상적인 방법입니다. – Ioan