I'm trying to write a backup and recovery tool. I'm running my code on a WinPE CD (http://en.wikipedia.org/wiki/Windows_Preinstallation_Environment). I'm trying to read the entire C: partition and write it to the network. Just like the tar command, but windows specific. I have everything working except for setting the file owner. Windows seems to be really intolerant to files being owned by unknown SIDs. Since I'm running in WinPE, most of the users defined on C: aren't in the local user database.
Here are some of the functions I've tried:
- SetFileSecurity (returns 1307)
- SetSecurityInfo (returns 1307)
- SetNamedSecurityInfo (returns 1307)
- BackupWrite (returns 1307)
- NtSetSecurityObject (returns 0xC000005A)
I know this can be done. SetACL (http://helgeklein.com/setacl/) is able to do it.
So, the question. How do I set the owner of a file to a non-existing user/SID? Any help is greatly appreciated!
Here's a sample of the code I've tried:
#define _WIN32_WINNT 0x0500
#include <windows.h>
#include <sddl.h>
#include <aclapi.h>
#include <tchar.h>
INT _tmain(){
PSECURITY_DESCRIPTOR psdOwner = LocalAlloc(LPTR,SECURITY_DESCRIPTOR_MIN_LENGTH);
if (InitializeSecurityDescriptor(psdOwner,SECURITY_DESCRIPTOR_REVISION)){
PSID psOwner = (PSID)0;
if (ConvertStringSidToSid(TEXT("S-1-5-21-3626571138-2175758104-1447827851-1013"),&psOwner)){
if (SetSecurityDescriptorOwner(psdOwner,psOwner,FALSE)){
DWORD dwError = SetNamedSecurityInfo(TEXT("test.txt"),SE_FILE_OBJECT,OWNER_SECURITY_INFORMATION,psdOwner,NULL,NULL,NULL);
if (dwError == ERROR_SUCCESS){
_tprintf(TEXT("Success!\n"));
}else{
_tprintf(TEXT("Failed to set owner: %u\n"),dwError);
}
}else{
_tprintf(TEXT("Failed to set owner into SD: %u\n"),GetLastError());
}
}else{
_tprintf(TEXT("Failed to covnert Sid string to Sid: %u\n"),GetLastError());
}
if (psOwner) LocalFree(psOwner);
}else{
_tprintf(TEXT("Failed to initialize SD: %u\n"),GetLastError());
}
if (psdOwner) LocalFree(psdOwner);
return 0;
}