Hi I'm making icacls command(It is windows file security utility) with C and Win32API.
So, when I try to implement the owner change, it fails with SetFileSecurity and GetLastError returns 1307.
What's wrong with this following code:
#include "Icacls.h"
BOOL SetFileOwner(LPWSTR lpFileName, LPWSTR lpUserName) {
DWORD dwSecurityDescriptorSize = 0;
// Get file security information size needed
if (!GetFileSecurityW(lpFileName, OWNER_SECURITY_INFORMATION, NULL, 0, &dwSecurityDescriptorSize)) {
// Buffer shortage
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
// Allocate memory
PSECURITY_DESCRIPTOR pSecDesc = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR, dwSecurityDescriptorSize + 1000);
if (NULL == pSecDesc) {
wprintf(L"LocalAlloc (pSecDesc) error: %d\n", GetLastError());
return ERROR_NOT_ENOUGH_MEMORY;
}
// Start protected statement
__try {
// Get file security information with size needed
if (!GetFileSecurityW(lpFileName, OWNER_SECURITY_INFORMATION, pSecDesc, dwSecurityDescriptorSize, &dwSecurityDescriptorSize)) {
wprintf(L"GetFileSecurityW error: %d\n", GetLastError());
__leave;
}
// Initialize security descriptor
if (!InitializeSecurityDescriptor(pSecDesc, SECURITY_DESCRIPTOR_REVISION)) {
wprintf(L"InitializeSecurityDescriptor error: %d\n", GetLastError());
__leave;
}
BOOL bOwnerDefaulted = FALSE; PSID pNewSid = NULL;
// Get account sid from username
if (!GetAccountSid(lpUserName, &pNewSid, NULL)) {
wprintf(L"InitializeSecurityDescriptor error: %d\n", GetLastError());
__leave;
}
wprintf(L"lpUserName: %s\nlpFileName: %s\n\n", lpUserName, lpFileName);
// Set file owner to local security descriptor
if (!SetSecurityDescriptorOwner(pSecDesc, pNewSid, bOwnerDefaulted)) {
wprintf(L"SetSecurityDescriptorOwner error: %d\n", GetLastError());
__leave;
}
HANDLE hToken;
GetTokenHandle(&hToken);
AssertTakeOwnership(hToken);
// Set security descriptor to file security
if (!SetFileSecurityW(lpFileName, OWNER_SECURITY_INFORMATION, pSecDesc)) {
wprintf(L"SetFileSecurityW error: %d\n", GetLastError());
__leave;
}
}
// Cleanup
__finally {
if (pSecDesc) LocalFree(pSecDesc);
return GetLastError();
}
}
}
}
BOOL GetTokenHandle(PHANDLE TokenHandle) {
HANDLE ProcessHandle;
BOOL Result;
ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, GetCurrentProcessId());
if (ProcessHandle == NULL) {
return(FALSE);
}
Result = OpenProcessToken(ProcessHandle, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, TokenHandle);
if (!Result) {
CloseHandle(ProcessHandle);
return FALSE;
}
CloseHandle(ProcessHandle);
return(TRUE);
}
BOOL AssertTakeOwnership(HANDLE TokenHandle) {
LUID TakeOwnershipValue;
BOOL Result;
TOKEN_PRIVILEGES TokenPrivileges;
Result = LookupPrivilegeValueW(NULL, L"SeTakeOwnershipPrivilege", &TakeOwnershipValue);
if (!Result) {
return FALSE;
}
TokenPrivileges.PrivilegeCount = 1;
TokenPrivileges.Privileges[0].Luid = TakeOwnershipValue;
TokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
(VOID)AdjustTokenPrivileges(TokenHandle, FALSE, &TokenPrivileges, sizeof(TOKEN_PRIVILEGES), NULL, NULL);
if (GetLastError() != NO_ERROR) {
return FALSE;
}
return(TRUE);
}