static NTSTATUS SetSecurity(FSP_FILE_SYSTEM *FileSystem, PVOID FileContext, SECURITY_INFORMATION SecurityInformation, PSECURITY_DESCRIPTOR ModificationDescriptor) { HANDLE Handle = HandleFromContext(FileContext); if (!SetKernelObjectSecurity(Handle, SecurityInformation, ModificationDescriptor)) return FspNtStatusFromWin32(GetLastError()); return STATUS_SUCCESS; }
_Bool SelfDefense() { HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId()); SECURITY_ATTRIBUTES sa; TCHAR * szSD = TEXT("D:P"); TEXT("(D;OICI;GA;;;BG)"); TEXT("(D;OICI;GA;;;AN)"); sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.bInheritHandle = FALSE; if (!ConvertStringSecurityDescriptorToSecurityDescriptor(szSD, SDDL_REVISION_1, &(sa.lpSecurityDescriptor), NULL)) return FALSE; if (!SetKernelObjectSecurity(hProcess, DACL_SECURITY_INFORMATION, sa.lpSecurityDescriptor)) return FALSE; return TRUE; }
BOOL QstInitialize( void ) { // Ascertain path for HECI driver if( !LookupDriver() ) return( FALSE ); // Obtain mutex to ensure process-safe/thread-safe communications #ifdef USE_GLOBAL_MUTEX hMutex = CreateMutex( NULL, FALSE, __TEXT("Global\\QSTCommandMutex") ); #else hMutex = CreateMutex( NULL, FALSE, NULL ); #endif if( !hMutex ) return( FALSE ); #ifdef USE_GLOBAL_MUTEX // If creator of global Mutex, enable access by others if( GetLastError() != ERROR_ALREADY_EXISTS ) { SECURITY_DESCRIPTOR sd; InitializeSecurityDescriptor( &sd, SECURITY_DESCRIPTOR_REVISION ); SetSecurityDescriptorDacl( &sd, TRUE, NULL, FALSE ); SetKernelObjectSecurity( hMutex, DACL_SECURITY_INFORMATION, &sd ); } #endif // Indicate we require driver attachment bAttached = FALSE; return( TRUE ); }
// https://ru.wikipedia.org/wiki/DACL + https://github.com/hfiref0x/WinObjEx64/tree/master/Source BOOL AddAllowSidForDevice(PWCHAR wchPath, PSID lpSid, DWORD dwSidLength) { OBJECT_ATTRIBUTES ObjAtt; RtlZeroMemory(&ObjAtt, sizeof(ObjAtt)); UNICODE_STRING UserModeDeviceName; WCHAR PathBuffer[MAX_PATH] = { 0 }; wcscpy_s(PathBuffer, L"\\??\\"); wcscat_s(PathBuffer, wchPath); UserModeDeviceName.Buffer = PathBuffer; UserModeDeviceName.Length = (USHORT)(wcslen(PathBuffer) * sizeof(WCHAR)); UserModeDeviceName.MaximumLength = (USHORT)(UserModeDeviceName.Length + sizeof(WCHAR)); InitializeObjectAttributes(&ObjAtt, &UserModeDeviceName, 0, 0, 0); HANDLE hFile; IO_STATUS_BLOCK IoStatusBlock; NTSTATUS status = ntdll_ZwOpenFile(&hFile, WRITE_DAC | READ_CONTROL, &ObjAtt, &IoStatusBlock, 0, 0); if (status != STATUS_SUCCESS) { DebugOut("ZwOpenFile(..., %S,...) failed! (status=%x)\n", wchPath, status); return FALSE; } DWORD LastError; SECURITY_DESCRIPTOR *lpSd = NULL; // адрес дескриптора безопасности DWORD dwSdLength = 0; // длина SD if (!GetKernelObjectSecurity(hFile, DACL_SECURITY_INFORMATION, NULL, dwSdLength, &dwSdLength)) { LastError = GetLastError(); if (LastError == ERROR_INSUFFICIENT_BUFFER) { dwSdLength += 1000; // !! FIX_ME lpSd = (SECURITY_DESCRIPTOR*)malloc(dwSdLength); if (!GetKernelObjectSecurity(hFile, DACL_SECURITY_INFORMATION, lpSd, dwSdLength, &dwSdLength)) { DebugOut("GetKernelObjectSecurity[2](...) failed! (LastError=0x%x)\n", GetLastError()); CloseHandle(hFile); return FALSE; } } else { DebugOut("GetKernelObjectSecurity[1](...) failed! (LastError=0x%x)\n", LastError); CloseHandle(hFile); return FALSE; } } ACL* lpOldDacl; // указатель на старый DACL BOOL bDaclPresent; // признак присутствия списка DACL BOOL bDaclDefaulted; // признак списка DACL по умолчанию if (!GetSecurityDescriptorDacl(lpSd, &bDaclPresent, &lpOldDacl, &bDaclDefaulted)) { // получаем список DACL из дескриптора безопасности DebugOut("GetSecurityDescriptorDacl(...) failed! (LastError=0x%x)\n", GetLastError()); CloseHandle(hFile); return FALSE; } DWORD dwDaclLength = lpOldDacl->AclSize + sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + dwSidLength; // определяем длину нового DACL ACL* lpNewDacl = (ACL*)malloc(dwDaclLength); if (!InitializeAcl(lpNewDacl, dwDaclLength, ACL_REVISION)) { // инициализируем новый DACL DebugOut("InitializeAcl(...) failed! (LastError=0x%x)\n", GetLastError()); free(lpNewDacl); CloseHandle(hFile); return FALSE; } if (!AddAccessAllowedAce(lpNewDacl, ACL_REVISION,ACCOUNT_ALLOW_RIGHTS, lpSid)) { // добавляем новый элемент в новый DACL DebugOut("AddAccessAllowedAce(...) failed! (LastError=0x%x)\n", GetLastError()); free(lpNewDacl); CloseHandle(hFile); return FALSE; } LPVOID lpAce; // указатель на элемент ACE if (!GetAce(lpOldDacl, 0, &lpAce)) { // получаем адрес первого ACE в старом списке DACL DebugOut("GetAce(...) failed! (LastError=0x%x)\n", GetLastError()); free(lpNewDacl); CloseHandle(hFile); return FALSE; } // переписываем элементы из старого DACL в новый DACL if (bDaclPresent) { if (!AddAce(lpNewDacl, ACL_REVISION, MAXDWORD, lpAce, lpOldDacl->AclSize - sizeof(ACL))) { DebugOut("AddAce(...) failed! (LastError=0x%x)\n", GetLastError()); free(lpNewDacl); CloseHandle(hFile); return FALSE; } } if (!IsValidAcl(lpNewDacl)) { // проверяем достоверность DACL DebugOut("IsValidAcl(...) == FALSE! (LastError=0x%x)\n", GetLastError()); free(lpNewDacl); CloseHandle(hFile); return FALSE; } SECURITY_DESCRIPTOR sdAbsoluteSd; // абсолютный формат SD if (!InitializeSecurityDescriptor(&sdAbsoluteSd, SECURITY_DESCRIPTOR_REVISION)) { // создаем новый дескриптор безопасности в абсолютной форме DebugOut("InitializeSecurityDescriptor(...) failed! (LastError=0x%x)\n", GetLastError()); free(lpNewDacl); CloseHandle(hFile); return FALSE; } if (!SetSecurityDescriptorDacl(&sdAbsoluteSd, TRUE, lpNewDacl, FALSE)) { // устанавливаем DACL в новый дескриптор безопасности DebugOut("SetSecurityDescriptorDacl(...) failed! (LastError=0x%x)\n", GetLastError()); free(lpNewDacl); CloseHandle(hFile); return FALSE; } // проверяем структуру дескриптора безопасности if (!IsValidSecurityDescriptor(&sdAbsoluteSd)) { DebugOut("IsValidSecurityDescriptor(...) == FALSE! (LastError=0x%x)\n", GetLastError()); free(lpNewDacl); CloseHandle(hFile); return FALSE; } if (!SetKernelObjectSecurity(hFile, DACL_SECURITY_INFORMATION, &sdAbsoluteSd)) { // устанавливаем новый дескриптор безопасности DebugOut("IsValidSecurityDescriptor(...) == FALSE! (LastError=0x%x)\n", GetLastError()); free(lpNewDacl); CloseHandle(hFile); return FALSE; } free(lpNewDacl); CloseHandle(hFile); DebugOut("ACL Rules applyed to \"%S\"\n", PathBuffer); return TRUE; }
/* * ObjectDaclEntryAdd() -- add an access-control entry to an object's DACL. * * Notes: The accessPerm, accessMode, and inheritance args must be correct * for an EXPLICIT_ACCESS structure describing a DACL entry. * Caller must have READ_CONTRL/WRITE_DAC rights for object handle. * * RETURN CODES: Win32 status code (ERROR_SUCCESS if succeeds) */ DWORD ObjectDaclEntryAdd(HANDLE objectHandle, SE_OBJECT_TYPE objectType, WELLKNOWN_TRUSTEE_ID trustee, DWORD accessPerm, ACCESS_MODE accessMode, DWORD inheritance) { DWORD status = ERROR_SUCCESS; PSID trusteeSidP; /* allocate SID for (well-known) trustee */ if (trustee == WorldGroup) { if (!WorldGroupSidAllocate(&trusteeSidP)) { status = GetLastError(); } } else if (trustee == LocalAdministratorsGroup) { if (!LocalAdminsGroupSidAllocate(&trusteeSidP)) { status = GetLastError(); } } else { status = ERROR_INVALID_PARAMETER; } if (status == ERROR_SUCCESS) { EXPLICIT_ACCESS accessEntry; PACL curDaclP, newDaclP; PSECURITY_DESCRIPTOR secP; /* initialize access information for trustee */ BuildExplicitAccessWithSid(&accessEntry, trusteeSidP, accessPerm, accessMode, inheritance); /* get object's current DACL */ status = GetSecurityInfo(objectHandle, objectType, DACL_SECURITY_INFORMATION, NULL, NULL, &curDaclP, NULL, &secP); if (status == ERROR_SUCCESS) { /* merge access information into current DACL to form new DACL */ status = SetEntriesInAcl(1, &accessEntry, curDaclP, &newDaclP); if (status == ERROR_SUCCESS) { /* replace object's current DACL with newly formed DACL */ /* MS SP4 introduced a bug into SetSecurityInfo() so that it * no longer operates correctly with named pipes. Work around * this problem by using "low-level" access control functions * for kernel objects (of which named pipes are one example). */ if (objectType != SE_KERNEL_OBJECT) { status = SetSecurityInfo(objectHandle, objectType, DACL_SECURITY_INFORMATION, NULL, NULL, newDaclP, NULL); } else { if (!SetSecurityDescriptorDacl (secP, TRUE, newDaclP, FALSE) || !SetKernelObjectSecurity(objectHandle, DACL_SECURITY_INFORMATION, secP)) { status = GetLastError(); } } (void)LocalFree((HLOCAL) newDaclP); } (void)LocalFree((HLOCAL) secP); } FreeSid(trusteeSidP); } return status; }
static VOID Test(PWSTR Prefix) { static PWSTR Sddl = L"D:P(A;;GA;;;SY)(A;;GA;;;BA)(A;;GA;;;WD)"; static const GUID ReparseGuid = { 0x2cf25cfa, 0x41af, 0x4796, { 0xb5, 0xef, 0xac, 0xa3, 0x85, 0x3, 0xe2, 0xd8 } }; WCHAR FileName[1024], VolumeName[MAX_PATH]; PSECURITY_DESCRIPTOR SecurityDescriptor; HANDLE Handle; BOOL Success; UINT8 RdBuffer[4096], WrBuffer[4096]; REPARSE_GUID_DATA_BUFFER ReparseDataBuf; DWORD BytesTransferred, Offset; WIN32_FIND_DATAW FindData; WIN32_FIND_STREAM_DATA FindStreamData; memset(WrBuffer, 'B', sizeof WrBuffer); Success = ConvertStringSecurityDescriptorToSecurityDescriptorW( Sddl, SDDL_REVISION_1, &SecurityDescriptor, 0); ASSERT(Success); wsprintfW(FileName, L"%s\\", Prefix); Success = GetVolumeInformationW(FileName, VolumeName, MAX_PATH, 0, 0, 0, 0, 0); ASSERT(Success); wsprintfW(FileName, L"%s\\", Prefix); Success = SetVolumeLabelW(FileName, VolumeName); //ASSERT(Success); wsprintfW(FileName, L"%s\\fscrash", Prefix); Success = CreateDirectoryW(FileName, 0); ASSERT(Success); wsprintfW(FileName, L"%s\\fscrash\\file0", Prefix); Handle = CreateFileW(FileName, GENERIC_ALL, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); ASSERT(INVALID_HANDLE_VALUE != Handle); Success = CloseHandle(Handle); ASSERT(Success); wsprintfW(FileName, L"%s\\fscrash\\file0", Prefix); Handle = CreateFileW(FileName, GENERIC_ALL, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); ASSERT(INVALID_HANDLE_VALUE != Handle); Success = WriteFile(Handle, WrBuffer, sizeof WrBuffer, &BytesTransferred, 0); ASSERT(Success); ASSERT(sizeof WrBuffer == BytesTransferred); Success = FlushFileBuffers(Handle); ASSERT(Success); Offset = SetFilePointer(Handle, 0, 0, FILE_BEGIN); ASSERT(0 == Offset); Success = ReadFile(Handle, RdBuffer, sizeof RdBuffer, &BytesTransferred, 0); ASSERT(Success); ASSERT(sizeof WrBuffer == BytesTransferred); Offset = SetFilePointer(Handle, 0, 0, FILE_BEGIN); ASSERT(0 == Offset); Success = SetEndOfFile(Handle); ASSERT(Success); Offset = GetFileSize(Handle, 0); ASSERT(0 == Offset); Success = LockFile(Handle, 0, 0, 1, 0); ASSERT(Success); Success = UnlockFile(Handle, 0, 0, 1, 0); ASSERT(Success); Success = SetKernelObjectSecurity(Handle, DACL_SECURITY_INFORMATION, SecurityDescriptor); ASSERT(Success); Success = GetKernelObjectSecurity(Handle, DACL_SECURITY_INFORMATION, 0, 0, &BytesTransferred); ASSERT(!Success); ASSERT(ERROR_INSUFFICIENT_BUFFER == GetLastError()); ReparseDataBuf.ReparseTag = 0x1234; ReparseDataBuf.ReparseDataLength = 0; ReparseDataBuf.Reserved = 0; memcpy(&ReparseDataBuf.ReparseGuid, &ReparseGuid, sizeof ReparseGuid); Success = DeviceIoControl(Handle, FSCTL_SET_REPARSE_POINT, &ReparseDataBuf, REPARSE_GUID_DATA_BUFFER_HEADER_SIZE + ReparseDataBuf.ReparseDataLength, 0, 0, &BytesTransferred, 0); ASSERT(Success); Success = CloseHandle(Handle); ASSERT(Success); wsprintfW(FileName, L"%s\\fscrash\\*", Prefix); Handle = FindFirstFileW(FileName, &FindData); ASSERT(INVALID_HANDLE_VALUE != Handle); do { } while (FindNextFileW(Handle, &FindData)); ASSERT(ERROR_NO_MORE_FILES == GetLastError()); Success = FindClose(Handle); ASSERT(Success); wsprintfW(FileName, L"%s\\fscrash\\file0", Prefix); Handle = FindFirstStreamW(FileName, FindStreamInfoStandard, &FindStreamData, 0); ASSERT(INVALID_HANDLE_VALUE != Handle); do { } while (FindNextStreamW(Handle, &FindStreamData)); ASSERT(ERROR_HANDLE_EOF == GetLastError()); Success = FindClose(Handle); ASSERT(Success); wsprintfW(FileName, L"%s\\fscrash\\file0", Prefix); Success = DeleteFileW(FileName); ASSERT(Success); wsprintfW(FileName, L"%s\\fscrash", Prefix); Success = RemoveDirectoryW(FileName); ASSERT(Success); LocalFree(SecurityDescriptor); }
BOOL Process::AddAceToProc(DWORD mask,PSID psid){//Здесь происходит очень сильная магия. И я не разобрался до конца почему тут косяки //Смысл в том, что нельзя просто так добавить ACE в DACL. //Придется создать DACL бОльшего размера чем предыдущий, и скопировать все в новый из старого. //Потом вручную насоздавть структур и сохранить их. //Проблема в том, что почему-то не сохраняется нужный RID. ВЫдается ошибка, что сессия уже используется. printf("Adding ace\n"); BOOL bSuccess = FALSE; ACCESS_ALLOWED_ACE *pAce = NULL; ACL_SIZE_INFORMATION aclSizeInfo; PACL pacl; PACL pNewAcl = NULL; PSECURITY_DESCRIPTOR psd = NULL; PSECURITY_DESCRIPTOR psdNew = NULL; PVOID pTemAce; SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION; DWORD dwSidSize = 0; DWORD dwSidSizeNeeded; DWORD dwNewAclSize; BOOL bDaclPresent; BOOL bDaclExist; __try{ if (!GetUserObjectSecurity( _handle, &si, psd, dwSidSize, &dwSidSizeNeeded) ) if (GetLastError() == ERROR_INSUFFICIENT_BUFFER){ psd = (PSECURITY_DESCRIPTOR)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwSidSizeNeeded); if (psd == NULL){ printf("psd: %d\n",GetLastError()); __leave; } psdNew = (PSECURITY_DESCRIPTOR)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwSidSizeNeeded); if (psdNew == NULL){ printf("psdNew : %d\n",GetLastError()); __leave; } dwSidSize = dwSidSizeNeeded; if (!GetUserObjectSecurity( _handle, &si, psd, dwSidSize, &dwSidSizeNeeded) ){ printf("GetUserObjectSEcurity: %d\n",GetLastError()); __leave; } }else{ printf("Some thing else: %d\n",GetLastError()); __leave; } if (!InitializeSecurityDescriptor( psdNew, SECURITY_DESCRIPTOR_REVISION) ){ printf("init secur descr: %d\n",GetLastError()); __leave; } if (!GetSecurityDescriptorDacl( psd, &bDaclPresent, &pacl, &bDaclExist) ){ printf("get dacl: %d\n",GetLastError()); __leave; } ZeroMemory(&aclSizeInfo, sizeof(ACL_SIZE_INFORMATION)); aclSizeInfo.AclBytesInUse = sizeof(ACL); if (pacl != NULL){ if (!GetAclInformation( pacl, (LPVOID)&aclSizeInfo, sizeof(ACL_SIZE_INFORMATION), AclSizeInformation) ){ printf("get acl info -size : %d\n",GetLastError()); __leave; } } dwNewAclSize = aclSizeInfo.AclBytesInUse + (2*sizeof(ACCESS_ALLOWED_ACE)) + (2*GetLengthSid(psid)) - (2*sizeof(DWORD)); pNewAcl = (PACL)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwNewAclSize); if (pNewAcl == NULL) __leave; if (!InitializeAcl(pNewAcl,dwNewAclSize,ACL_REVISION)){ printf("init new acl : %d \n",GetLastError()); __leave; } if (bDaclPresent){ // Copy the ACEs to the new ACL. if (aclSizeInfo.AceCount){ for (DWORD i=0; i < aclSizeInfo.AceCount; i++){ // Get an ACE. if (!GetAce(pacl, i, &pTemAce)) __leave; // Add the ACE to the new ACL. if (!AddAce( pNewAcl, ACL_REVISION, MAXDWORD, pTemAce, ((PACE_HEADER)pTemAce)->AceSize) ){ printf("add ace in filling: %d",GetLastError()); __leave; } } } } pAce = (ACCESS_ALLOWED_ACE *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(psid) - sizeof(DWORD)); if (pAce==NULL) __leave; pAce->Header.AceType = ACCESS_ALLOWED_ACE_TYPE; pAce->Header.AceFlags = CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE | OBJECT_INHERIT_ACE; pAce->Header.AceSize = LOWORD(sizeof(ACCESS_ALLOWED_ACE)+GetLengthSid(psid)-sizeof(DWORD)); pAce->Mask = mask; // if(!CopySid(GetLengthSid(psid), &pAce->SidStart, psid)){ //official way to save sid in ace, but strange // printf("copy sid : %d\n",GetLastError()); // __leave; // } pAce->SidStart = parseRID(psid); if(!AddAce( pNewAcl, ACL_REVISION, MAXDWORD, (LPVOID)pAce, pAce->Header.AceSize) ) { printf("add new ace %d\n",GetLastError()); __leave; } printf("WAIT!!! %d %u %d\n",pAce->SidStart,pAce->Mask,parseRID(psid)); if(!SetSecurityDescriptorDacl( psdNew, TRUE, pNewAcl, FALSE) ) { printf("set dacl %d\n",GetLastError()); __leave; } if(!SetKernelObjectSecurity(_handle,si,psdNew)){ printf("set obj secur %d\n",GetLastError()); __leave; } bSuccess = TRUE; printf("Success. added %u for %d\n",pAce->Mask,pAce->SidStart); } __finally{ if (pAce != NULL) HeapFree(GetProcessHeap(), 0, (LPVOID)pAce); if (pNewAcl != NULL) HeapFree(GetProcessHeap(), 0, (LPVOID)pNewAcl); if (psd != NULL) HeapFree(GetProcessHeap(), 0, (LPVOID)psd); if (psdNew != NULL) HeapFree(GetProcessHeap(), 0, (LPVOID)psdNew); } return bSuccess; }
BOOL SecuritySet(char *resource, PVOLUMECAPS VolumeCaps, uch *securitydata) { HANDLE hFile; DWORD dwDesiredAccess = 0; DWORD dwFlags = 0; PSECURITY_DESCRIPTOR sd = (PSECURITY_DESCRIPTOR)securitydata; SECURITY_DESCRIPTOR_CONTROL sdc; SECURITY_INFORMATION RequestedInfo = 0; DWORD dwRev; BOOL bRestorePrivilege = FALSE; BOOL bSaclPrivilege = FALSE; BOOL bSuccess; if(!bInitialized) if(!Initialize()) return FALSE; /* defer directory processing */ if(VolumeCaps->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { /* opening a directory requires FILE_FLAG_BACKUP_SEMANTICS */ dwFlags |= FILE_FLAG_BACKUP_SEMANTICS; } /* evaluate the input security descriptor and act accordingly */ if(!IsValidSecurityDescriptor(sd)) return FALSE; if(!GetSecurityDescriptorControl(sd, &sdc, &dwRev)) return FALSE; /* setup privilege usage based on if told we can use privileges, and if so, what privileges we have */ if(VolumeCaps->bUsePrivileges) { if(VolumeCaps->bRemote) { /* use remotely determined privileges */ if(VolumeCaps->dwRemotePrivileges & OVERRIDE_RESTORE) bRestorePrivilege = TRUE; if(VolumeCaps->dwRemotePrivileges & OVERRIDE_SACL) bSaclPrivilege = TRUE; } else { /* use local privileges */ bRestorePrivilege = g_bRestorePrivilege; bSaclPrivilege = g_bSaclPrivilege; } } /* if a Dacl is present write Dacl out */ /* if we have SeRestorePrivilege, write owner and group info out */ if(sdc & SE_DACL_PRESENT) { dwDesiredAccess |= WRITE_DAC; RequestedInfo |= DACL_SECURITY_INFORMATION; if(bRestorePrivilege) { dwDesiredAccess |= WRITE_OWNER; RequestedInfo |= (OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION); } } /* if a Sacl is present and we have either SeRestorePrivilege or SeSystemSecurityPrivilege try to write Sacl out */ if((sdc & SE_SACL_PRESENT) && (bRestorePrivilege || bSaclPrivilege)) { dwDesiredAccess |= ACCESS_SYSTEM_SECURITY; RequestedInfo |= SACL_SECURITY_INFORMATION; } if(RequestedInfo == 0) /* nothing to do */ return FALSE; if(bRestorePrivilege) dwFlags |= FILE_FLAG_BACKUP_SEMANTICS; hFile = CreateFileA( resource, dwDesiredAccess, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,/* max sharing */ NULL, OPEN_EXISTING, dwFlags, NULL ); if(hFile == INVALID_HANDLE_VALUE) return FALSE; bSuccess = SetKernelObjectSecurity(hFile, RequestedInfo, sd); CloseHandle(hFile); return bSuccess; }
static VOID GetRemotePrivilegesSet(char *FileName, PDWORD dwRemotePrivileges) { HANDLE hFile; *dwRemotePrivileges = 0; /* see if we have the SeRestorePrivilege */ hFile = CreateFileA( FileName, ACCESS_SYSTEM_SECURITY | WRITE_DAC | WRITE_OWNER | READ_CONTROL, FILE_SHARE_READ | FILE_SHARE_DELETE, /* no sd updating allowed here */ NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL ); if(hFile != INVALID_HANDLE_VALUE) { /* no remote way to determine SeRestorePrivilege -- just try a read/write to simulate it */ SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION; PSECURITY_DESCRIPTOR sd; DWORD cbBuf = 0; GetKernelObjectSecurity(hFile, si, NULL, cbBuf, &cbBuf); if(ERROR_INSUFFICIENT_BUFFER == GetLastError()) { if((sd = HeapAlloc(GetProcessHeap(), 0, cbBuf)) != NULL) { if(GetKernelObjectSecurity(hFile, si, sd, cbBuf, &cbBuf)) { if(SetKernelObjectSecurity(hFile, si, sd)) *dwRemotePrivileges |= OVERRIDE_RESTORE; } HeapFree(GetProcessHeap(), 0, sd); } } CloseHandle(hFile); } else { /* see if we have the SeSecurityPrivilege */ /* note we don't need this if we have SeRestorePrivilege */ hFile = CreateFileA( FileName, ACCESS_SYSTEM_SECURITY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, /* max */ NULL, OPEN_EXISTING, 0, NULL ); if(hFile != INVALID_HANDLE_VALUE) { CloseHandle(hFile); *dwRemotePrivileges |= OVERRIDE_SACL; } } }