+/* Get basename of path */
+char *basename_ex(char *path)
+{
+ return (PathFindFileNameA(path));
+}
+
+/* Rename file or directory */
+int rename_ex(const char *source, const char *destination)
+{
+ if (!MoveFileEx(source, destination, MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH)) {
+ log2file(
+ "%s: ERROR: Could not move (%s) to (%s) which returned (%lu)",
+ __local_name,
+ source,
+ destination,
+ GetLastError()
+ );
+
+ return (-1);
+ }
+
+ return (0);
+}
+
+/* Create a temporary file */
+int mkstemp_ex(char *tmp_path)
+{
+ DWORD dwResult;
+ int result;
+ int status = -1;
+
+ HANDLE h = NULL;
+ PACL pACL = NULL;
+ PSECURITY_DESCRIPTOR pSD = NULL;
+ EXPLICIT_ACCESS ea[2];
+ SECURITY_ATTRIBUTES sa;
+
+ PSID pAdminGroupSID = NULL;
+ PSID pSystemGroupSID = NULL;
+ SID_IDENTIFIER_AUTHORITY SIDAuthNT = {SECURITY_NT_AUTHORITY};
+
+#if defined(_MSC_VER) && _MSC_VER >= 1500
+ result = _mktemp_s(tmp_path, strlen(tmp_path) + 1);
+
+ if (result != 0) {
+ log2file(
+ "%s: ERROR: Could not create temporary file (%s) which returned (%d)",
+ __local_name,
+ tmp_path,
+ result
+ );
+
+ return (-1);
+ }
+#else
+ if (_mktemp(tmp_path) == NULL) {
+ log2file(
+ "%s: ERROR: Could not create temporary file (%s) which returned [(%d)-(%s)]",
+ __local_name,
+ tmp_path,
+ errno,
+ strerror(errno)
+ );
+
+ return (-1);
+ }
+#endif
+
+ /* Create SID for the BUILTIN\Administrators group */
+ result = AllocateAndInitializeSid(
+ &SIDAuthNT,
+ 2,
+ SECURITY_BUILTIN_DOMAIN_RID,
+ DOMAIN_ALIAS_RID_ADMINS,
+ 0, 0, 0, 0, 0, 0,
+ &pAdminGroupSID
+ );
+
+ if (!result) {
+ log2file(
+ "%s: ERROR: Could not create BUILTIN\\Administrators group SID which returned (%lu)",
+ __local_name,
+ GetLastError()
+ );
+
+ goto cleanup;
+ }
+
+ /* Create SID for the SYSTEM group */
+ result = AllocateAndInitializeSid(
+ &SIDAuthNT,
+ 1,
+ SECURITY_LOCAL_SYSTEM_RID,
+ 0, 0, 0, 0, 0, 0, 0,
+ &pSystemGroupSID
+ );
+
+ if (!result) {
+ log2file(
+ "%s: ERROR: Could not create SYSTEM group SID which returned (%lu)",
+ __local_name,
+ GetLastError()
+ );
+
+ goto cleanup;
+ }
+
+ /* Initialize an EXPLICIT_ACCESS structure for an ACE */
+ ZeroMemory(&ea, 2 * sizeof(EXPLICIT_ACCESS));
+
+ /* Add Administrators group */
+ ea[0].grfAccessPermissions = GENERIC_ALL;
+ ea[0].grfAccessMode = SET_ACCESS;
+ ea[0].grfInheritance = NO_INHERITANCE;
+ ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
+ ea[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
+ ea[0].Trustee.ptstrName = (LPTSTR)pAdminGroupSID;
+
+ /* Add SYSTEM group */
+ ea[1].grfAccessPermissions = GENERIC_ALL;
+ ea[1].grfAccessMode = SET_ACCESS;
+ ea[1].grfInheritance = NO_INHERITANCE;
+ ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
+ ea[1].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
+ ea[1].Trustee.ptstrName = (LPTSTR)pSystemGroupSID;
+
+ /* Set entries in ACL */
+ dwResult = SetEntriesInAcl(2, ea, NULL, &pACL);
+
+ if (dwResult != ERROR_SUCCESS) {
+ log2file(
+ "%s: ERROR: Could not set ACL entries which returned (%lu)",
+ __local_name,
+ dwResult
+ );
+
+ goto cleanup;
+ }
+
+ /* Initialize security descriptor */
+ pSD = (PSECURITY_DESCRIPTOR)LocalAlloc(
+ LPTR,
+ SECURITY_DESCRIPTOR_MIN_LENGTH
+ );
+
+ if (pSD == NULL) {
+ log2file(
+ "%s: ERROR: Could not initalize SECURITY_DESCRIPTOR because of a LocalAlloc() failure which returned (%lu)",
+ __local_name,
+ GetLastError()
+ );
+
+ goto cleanup;
+ }
+
+ if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION)) {
+ log2file(
+ "%s: ERROR: Could not initalize SECURITY_DESCRIPTOR because of an InitializeSecurityDescriptor() failure which returned (%lu)",
+ __local_name,
+ GetLastError()
+ );
+
+ goto cleanup;
+ }
+
+ /* Set owner */
+ if (!SetSecurityDescriptorOwner(pSD, NULL, FALSE)) {
+ log2file(
+ "%s: ERROR: Could not set owner which returned (%lu)",
+ __local_name,
+ GetLastError()
+ );
+
+ goto cleanup;
+ }
+
+ /* Set group owner */
+ if (!SetSecurityDescriptorGroup(pSD, NULL, FALSE)) {
+ log2file(
+ "%s: ERROR: Could not set group owner which returned (%lu)",
+ __local_name,
+ GetLastError()
+ );
+
+ goto cleanup;
+ }
+
+ /* Add ACL to security descriptor */
+ if (!SetSecurityDescriptorDacl(pSD, TRUE, pACL, FALSE)) {
+ log2file(
+ "%s: ERROR: Could not set SECURITY_DESCRIPTOR DACL which returned (%lu)",
+ __local_name,
+ GetLastError()
+ );
+
+ goto cleanup;
+ }
+
+ /* Initialize security attributes structure */
+ sa.nLength = sizeof (SECURITY_ATTRIBUTES);
+ sa.lpSecurityDescriptor = pSD;
+ sa.bInheritHandle = FALSE;
+
+ h = CreateFileA(
+ tmp_path,
+ GENERIC_WRITE,
+ 0,
+ &sa,
+ CREATE_NEW,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL
+ );
+
+ if (h == INVALID_HANDLE_VALUE) {
+ log2file(
+ "%s: ERROR: Could not create temporary file (%s) which returned (%lu)",
+ __local_name,
+ tmp_path,
+ GetLastError()
+ );
+
+ goto cleanup;
+ }
+
+ if (!CloseHandle(h)) {
+ log2file(
+ "%s: ERROR: Could not close file handle to (%s) which returned (%lu)",
+ __local_name,
+ tmp_path,
+ GetLastError()
+ );
+
+ goto cleanup;
+ }
+
+ /* Success */
+ status = 0;
+
+cleanup:
+ if (pAdminGroupSID) {
+ FreeSid(pAdminGroupSID);
+ }
+
+ if (pSystemGroupSID) {
+ FreeSid(pSystemGroupSID);
+ }
+
+ if (pACL) {
+ LocalFree(pACL);
+ }
+
+ if (pSD) {
+ LocalFree(pSD);
+ }
+
+ return (status);
+}