Esempio n. 1
0
/* Acquire group or user name by SID */
static HRESULT getNameByStringSID(
    const wchar_t *sid, LPWSTR buffer, LPDWORD bufferLen)
{
    HRESULT hr = S_OK;
    PSID psid = NULL;
    SID_NAME_USE groupType;
    DWORD domainNameLen = BUFFER_SIZE;
    wchar_t domainName[BUFFER_SIZE];

    chk(ConvertStringSidToSidW(sid, &psid));
    LookupAccountSidW(NULL, psid, buffer, bufferLen,
                domainName, &domainNameLen, &groupType);
    hr = HRESULT_FROM_WIN32(GetLastError());

    LocalFree(psid);

out:
    return hr;
}
Esempio n. 2
0
//MailSlot of flush DNS cache Monitor
bool __fastcall FlushDNSMailSlotMonitor(
	void)
{
//System security setting
	std::shared_ptr<SECURITY_ATTRIBUTES> SecurityAttributes(new SECURITY_ATTRIBUTES());
	std::shared_ptr<SECURITY_DESCRIPTOR> SecurityDescriptor(new SECURITY_DESCRIPTOR());
	std::shared_ptr<char> ACL_Buffer(new char[PACKET_MAXSIZE]());
	memset(ACL_Buffer.get(), 0, PACKET_MAXSIZE);
	PSID SID_Value = nullptr;

	InitializeSecurityDescriptor(SecurityDescriptor.get(), SECURITY_DESCRIPTOR_REVISION);
	InitializeAcl((PACL)ACL_Buffer.get(), PACKET_MAXSIZE, ACL_REVISION);
	ConvertStringSidToSidW(SID_ADMINISTRATORS_GROUP, &SID_Value);
	AddAccessAllowedAce((PACL)ACL_Buffer.get(), ACL_REVISION, GENERIC_ALL, SID_Value);
	SetSecurityDescriptorDacl(SecurityDescriptor.get(), true, (PACL)ACL_Buffer.get(), false);
	SecurityAttributes->lpSecurityDescriptor = SecurityDescriptor.get();
	SecurityAttributes->bInheritHandle = true;

//Create mailslot.
	HANDLE hSlot = CreateMailslotW(MAILSLOT_NAME, PACKET_MAXSIZE - 1U, MAILSLOT_WAIT_FOREVER, SecurityAttributes.get());
	if (hSlot == INVALID_HANDLE_VALUE)
	{
		LocalFree(SID_Value);

		PrintError(LOG_ERROR_SYSTEM, L"Create mailslot error", GetLastError(), nullptr, 0);
		return false;
	}

	ACL_Buffer.reset();
	LocalFree(SID_Value);

//Initialization
	BOOL Result = FALSE;
	bool FlushDNS = false;
	DWORD cbMessage = 0, cMessage = 0, cbRead = 0;
	std::shared_ptr<wchar_t> lpszBuffer(new wchar_t[PACKET_MAXSIZE]());
	wmemset(lpszBuffer.get(), 0, PACKET_MAXSIZE);

//MailSlot Monitor
	for (;;)
	{
		cbMessage = 0;
		cMessage = 0;

	//Get mailslot messages.
		Result = GetMailslotInfo(hSlot, nullptr, &cbMessage, &cMessage, nullptr);
		if (Result == FALSE)
		{
			PrintError(LOG_ERROR_SYSTEM, L"Mailslot Monitor initialization error", GetLastError(), nullptr, 0);
			
			CloseHandle(hSlot);
			return false;
		}

	//Wait for messages.
		if (cbMessage == MAILSLOT_NO_MESSAGE)
		{
			Sleep(LOOP_INTERVAL_TIME_MONITOR);
			continue;
		}

	//Got messages.
		FlushDNS = false;
		while (cMessage > 0)
		{
			Result = ReadFile(hSlot, lpszBuffer.get(), cbMessage, &cbRead, nullptr);
			if (Result == FALSE)
			{
				PrintError(LOG_ERROR_SYSTEM, L"MailSlot read messages error", GetLastError(), nullptr, 0);
				
				CloseHandle(hSlot);
				return false;
			}

			if (!FlushDNS && memcmp(lpszBuffer.get(), MAILSLOT_MESSAGE_FLUSH_DNS, wcslen(MAILSLOT_MESSAGE_FLUSH_DNS)) == EXIT_SUCCESS)
			{
				FlushDNS = true;
				FlushAllDNSCache();
			}
			memset(lpszBuffer.get(), 0, PACKET_MAXSIZE);

		//Get other mailslot messages.
			Result = GetMailslotInfo(hSlot, nullptr, &cbMessage, &cMessage, nullptr);
			if (Result == FALSE)
			{
				PrintError(LOG_ERROR_SYSTEM, L"Mailslot Monitor initialization error", GetLastError(), nullptr, 0);
				
				CloseHandle(hSlot);
				return false;
			}
		}

		Sleep(LOOP_INTERVAL_TIME_MONITOR);
	}

//Monitor terminated
	CloseHandle(hSlot);
	PrintError(LOG_ERROR_SYSTEM, L"MailSlot module Monitor terminated", 0, nullptr, 0);
	return false;
}
JNIEXPORT void JNICALL Java_com_microsoft_tfs_jni_internal_filesystem_NativeFileSystem_nativeSetOwner(JNIEnv *env,
	jclass cls, jstring jPath, jstring jOwnerSIDString)
{
    const WCHAR * path= NULL;
    const WCHAR * ownerSIDString = NULL;
    PSID ownerSID = NULL;
    DWORD result = 0;

    if (jPath == NULL)
    {
       	throwRuntimeExceptionString(env, "path must not be null");
		goto cleanup;
    }

	if (jOwnerSIDString == NULL)
	{
		throwRuntimeExceptionString(env, "user must not be null");
		goto cleanup;
	}

    if ((ownerSIDString = javaStringToPlatformChars(env, jOwnerSIDString)) == NULL)
	{
		// String allocation failed, exception already thrown
		goto cleanup;
	}
    
	if (ConvertStringSidToSidW(ownerSIDString, &ownerSID) == FALSE)
	{
		throwRuntimeExceptionCode(env, GetLastError(), "Error converting string %S sid to sid", ownerSIDString);
		goto cleanup;
	}

    if ((path = javaStringToPlatformChars(env, jPath)) == NULL)
	{
		// String allocation failed, exception already thrown
		goto cleanup;
	}

	result = SetNamedSecurityInfoW((WCHAR *) path, SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION, 
		ownerSID, NULL, NULL, NULL);
    if (result != ERROR_SUCCESS)
	{
		throwRuntimeExceptionCode(env, result, "Error getting file security info for %S", path);
		goto cleanup;
	}

cleanup:

	if (ownerSIDString != NULL)
	{
	   releasePlatformChars(env, jOwnerSIDString, ownerSIDString);
	}
	if (path != NULL)
	{
		releasePlatformChars(env, jPath, path);
	}
	if (ownerSID != NULL)
	{
		LocalFree(ownerSID);
	}
}
JNIEXPORT void JNICALL Java_com_microsoft_tfs_jni_internal_filesystem_NativeFileSystem_nativeRemoveExplicitAllowEntries(
    JNIEnv *env, jclass cls, jstring jPath, jstring jUserSIDString)
{
	const WCHAR * path = NULL;
	const WCHAR * userSIDString = NULL;
	PSID userSID = NULL;
	DWORD result = 0;
	PACL dacl = NULL;
	PSECURITY_DESCRIPTOR securityDescriptor = NULL;
	ACL_SIZE_INFORMATION aclSizeInfo;
	ULONG aceCount = 0;
	BOOL modifiedDACL = FALSE;

	if (jPath == NULL)
    {
       	throwRuntimeExceptionString(env, "path must not be null");
		goto cleanup;
    }

	if (jUserSIDString == NULL)
    {
       	throwRuntimeExceptionString(env, "user must not be null");
		goto cleanup;
    }
	
	// Convert the SID string to a struct
	if ((userSIDString = javaStringToPlatformChars(env, jUserSIDString)) == NULL)
	{
		// String allocation failed, exception already thrown
		goto cleanup;
	}

	if (ConvertStringSidToSidW(userSIDString, &userSID) == FALSE)
	{
		throwRuntimeExceptionCode(env, GetLastError(), "Error converting string sid %S to sid", userSIDString);
		goto cleanup;
	}

	if ((path = javaStringToPlatformChars(env, jPath)) == NULL)
	{
		// String allocation failed, exception already thrown
		goto cleanup;
	}

	// Get file's DACL
	result = GetNamedSecurityInfo(path, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, 
		NULL, NULL, &dacl, NULL, &securityDescriptor);
	if (result != ERROR_SUCCESS)
	{
		throwRuntimeExceptionCode(env, result, "Error getting file security info for %S", path);
		goto cleanup;
	}

	// Get the count of entries int the DACL
	if (GetAclInformation(dacl, &aclSizeInfo, sizeof(aclSizeInfo), AclSizeInformation) == 0)
	{
		throwRuntimeExceptionCode(env, GetLastError(), "Error getting DACL");
		goto cleanup;
	}

	// Loop over the DACL backwards, removing matching entries
	for (aceCount = aclSizeInfo.AceCount; aceCount > 0; aceCount--)
	{
		ULONG aceIndex = aceCount - 1;
		ACCESS_ALLOWED_ACE * ace = NULL;
		PSID sid = NULL;

		if (GetAce(dacl, aceIndex, (LPVOID *) &ace) == 0)
		{
			throwRuntimeExceptionCode(env, GetLastError(), "Error getting ACE at index %d", aceIndex);
			goto cleanup;
		}

		// Skip inherited (non-explicit) entries
		if ((((ACE_HEADER *) ace)->AceFlags & INHERITED_ACE) == INHERITED_ACE)
		{
			continue;
		}

		// Extract the SID for "allow" types
		switch(((ACE_HEADER *) ace)->AceType)
		{
			case ACCESS_ALLOWED_ACE_TYPE:
				sid = (PSID) &((ACCESS_ALLOWED_ACE *) ace)->SidStart;
				break;
			case ACCESS_ALLOWED_CALLBACK_ACE_TYPE:
				sid = (PSID) &((ACCESS_ALLOWED_CALLBACK_ACE *) ace)->SidStart;
				break;
			case ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE:
				sid = (PSID) &((ACCESS_ALLOWED_CALLBACK_OBJECT_ACE *) ace)->SidStart;
				break;
			case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
				sid = (PSID) &((ACCESS_ALLOWED_OBJECT_ACE *) ace)->SidStart;
				break;
			default:
				// These are "deny" or other entries
				break;
		}

		if (sid != NULL && EqualSid(sid, userSID))
		{
			if (DeleteAce(dacl, aceIndex) == 0)
			{
				throwRuntimeExceptionCode(env, GetLastError(), "Error deleting ACE at index %d", aceIndex);
				goto cleanup;
			}

			modifiedDACL = TRUE;
		}

		// Nothing to free in the loop, all pointers are into dacl
	}

	if (modifiedDACL)
	{
		result = SetNamedSecurityInfo((WCHAR *) path, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
			NULL, NULL, dacl, NULL);
		if (result != ERROR_SUCCESS)
		{
			throwRuntimeExceptionCode(env, result, "Error setting security info for %S", path);
			goto cleanup;
		}
	}

cleanup:

	if (path != NULL)
	{
		releasePlatformChars(env, jPath, path);
	}
	if (userSID != NULL)
	{
		LocalFree(userSID);
	}
	if (userSIDString != NULL)
	{
	   releasePlatformChars(env, jUserSIDString, userSIDString);
	}
	// dacl points inside securityDescriptor
	if (securityDescriptor != NULL)
	{
		LocalFree(securityDescriptor);
	}
}
JNIEXPORT void JNICALL Java_com_microsoft_tfs_jni_internal_filesystem_NativeFileSystem_nativeGrantInheritableFullControl(
    JNIEnv *env, jclass cls, jstring jPath, jstring jUserSIDString, jstring jCopyExplicitRulesFromPath)
{
	const WCHAR * path = NULL;
	const WCHAR * userSIDString = NULL;
	const WCHAR * copyExplicitRulesFromPath = NULL;
	DWORD result = 0;
	PACL existingDACL = NULL;
	PACL newDACL = NULL;
	PSECURITY_DESCRIPTOR securityDescriptor = NULL;
	PSID userSID = NULL;
	EXPLICIT_ACCESS fullControl;
	
	if (jPath == NULL)
    {
       	throwRuntimeExceptionString(env, "path must not be null");
		goto cleanup;
    }

	if (jUserSIDString == NULL)
	{
		throwRuntimeExceptionString(env, "user must not be null");
		goto cleanup;
	}

	// Get the existing DACL entries
	if (jCopyExplicitRulesFromPath != NULL)
	{
		if ((copyExplicitRulesFromPath = javaStringToPlatformChars(env, jCopyExplicitRulesFromPath)) == NULL)
		{
			// String allocation failed, exception already thrown
			goto cleanup;
		}

		result = GetNamedSecurityInfo(copyExplicitRulesFromPath, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, 
			NULL, NULL, &existingDACL, NULL, &securityDescriptor);

		if (result != ERROR_SUCCESS)
		{
			throwRuntimeExceptionCode(env, result, "Error getting file security info for %S", copyExplicitRulesFromPath);
			goto cleanup;
	    }
	}

	// Convert the string SID to a structure
	if ((userSIDString = javaStringToPlatformChars(env, jUserSIDString)) == NULL)
	{
		// String allocation failed, exception already thrown
		goto cleanup;
	}

	if (ConvertStringSidToSidW(userSIDString, &userSID) == FALSE)
	{
		throwRuntimeExceptionCode(env, GetLastError(), "Error converting string sid %S to sid", userSIDString);
		goto cleanup;
	}

	/*
	 * Create a new explicit access entry with rights equivalent to .NET's 
	 * FileSystemRights.FullControl (0x1F01FF; see FileSecurity.cs) and
	 * full inheritance.
	 */
	ZeroMemory(&fullControl, sizeof(EXPLICIT_ACCESS));
    fullControl.grfAccessPermissions = 0x1F01FF;
    fullControl.grfAccessMode = GRANT_ACCESS;
    fullControl.grfInheritance= CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE;
    fullControl.Trustee.TrusteeForm = TRUSTEE_IS_SID;
	fullControl.Trustee.TrusteeType = TRUSTEE_IS_USER;
    fullControl.Trustee.ptstrName = userSID;
	
	// Merge new entry with old entries into a new list
	result = SetEntriesInAcl(1, &fullControl, existingDACL, &newDACL);
    if (result != ERROR_SUCCESS)
	{
		throwRuntimeExceptionCode(env, result, "Error setting entries in ACL");
        goto cleanup;
    }

	// Set the list on the path
	if ((path = javaStringToPlatformChars(env, jPath)) == NULL)
	{
		// String allocation failed, exception already thrown
		goto cleanup;
	}

	result = SetNamedSecurityInfo((WCHAR *) path, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
		NULL, NULL, newDACL, NULL);
	if (result != ERROR_SUCCESS)
	{
		throwRuntimeExceptionCode(env, result, "Error setting file security info for %S", path);
        goto cleanup;
	}

cleanup:

	if (path != NULL)
	{
		releasePlatformChars(env, jPath, path);
	}
	if (userSIDString != NULL)
	{
		releasePlatformChars(env, jUserSIDString, userSIDString);
	}
	if (copyExplicitRulesFromPath != NULL)
	{
		releasePlatformChars(env, jCopyExplicitRulesFromPath, copyExplicitRulesFromPath);
	}
	if (securityDescriptor != NULL)
	{
		LocalFree(securityDescriptor);
	}
	if (userSID != NULL)
	{
		LocalFree(userSID);
	}
	if (newDACL != NULL)
	{
		LocalFree(newDACL);
	}
	// existingDACL points inside securityDescriptor
}
Esempio n. 6
0
//MailSlot of flush DNS cache Monitor
bool FlushDNSMailSlotMonitor(
	void)
{
//System security setting
	std::shared_ptr<uint8_t> ACL_Buffer(new uint8_t[FILE_BUFFER_SIZE]());
	memset(ACL_Buffer.get(), 0, FILE_BUFFER_SIZE);
	SECURITY_ATTRIBUTES SecurityAttributes;
	SECURITY_DESCRIPTOR SecurityDescriptor;
	memset(&SecurityAttributes, 0, sizeof(SecurityAttributes));
	memset(&SecurityDescriptor, 0, sizeof(SecurityDescriptor));
	PSID SID_Value = nullptr;

	InitializeSecurityDescriptor(&SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION);
	InitializeAcl((PACL)ACL_Buffer.get(), FILE_BUFFER_SIZE, ACL_REVISION);
	ConvertStringSidToSidW(SID_ADMINISTRATORS_GROUP, &SID_Value);
	AddAccessAllowedAce((PACL)ACL_Buffer.get(), ACL_REVISION, GENERIC_ALL, SID_Value);
	SetSecurityDescriptorDacl(&SecurityDescriptor, true, (PACL)ACL_Buffer.get(), false);
	SecurityAttributes.lpSecurityDescriptor = &SecurityDescriptor;
	SecurityAttributes.bInheritHandle = true;

//Create mailslot.
	HANDLE hSlot = CreateMailslotW(MAILSLOT_NAME, FILE_BUFFER_SIZE - 1U, MAILSLOT_WAIT_FOREVER, &SecurityAttributes);
	if (hSlot == INVALID_HANDLE_VALUE)
	{
		LocalFree(SID_Value);

		PrintError(LOG_LEVEL_2, LOG_ERROR_SYSTEM, L"Create mailslot error", GetLastError(), nullptr, 0);
		return false;
	}

	ACL_Buffer.reset();
	LocalFree(SID_Value);

//Initialization
	std::shared_ptr<wchar_t> lpszBuffer(new wchar_t[FILE_BUFFER_SIZE]());
	wmemset(lpszBuffer.get(), 0, FILE_BUFFER_SIZE);
	std::wstring Message;
	std::string Domain; 
	DWORD cbMessage = 0;
	BOOL Result = 0;

//MailSlot monitor
	for (;;)
	{
	//Reset parameters.
		wmemset(lpszBuffer.get(), 0, FILE_BUFFER_SIZE);
		cbMessage = 0;

	//Read message from mailslot.
		Result = ReadFile(hSlot, lpszBuffer.get(), FILE_BUFFER_SIZE, &cbMessage, nullptr);
		if (Result == FALSE)
		{
			PrintError(LOG_LEVEL_3, LOG_ERROR_SYSTEM, L"MailSlot read messages error", GetLastError(), nullptr, 0);

			CloseHandle(hSlot);
			return false;
		}
		else {
			Message = lpszBuffer.get();
			Domain.clear();

		//Read message.
			if (Message == MAILSLOT_MESSAGE_FLUSH_DNS) //Flush all DNS cache.
			{
				FlushDNSCache(nullptr);
			}
			else if (Message.find(MAILSLOT_MESSAGE_FLUSH_DNS_DOMAIN) == 0 && //Flush single domain cache.
				Message.length() > wcslen(MAILSLOT_MESSAGE_FLUSH_DNS_DOMAIN) + DOMAIN_MINSIZE && //Domain length check
				Message.length() < wcslen(MAILSLOT_MESSAGE_FLUSH_DNS_DOMAIN) + DOMAIN_MAXSIZE)
			{
				if (WCSToMBSString(Message.c_str() + wcslen(MAILSLOT_MESSAGE_FLUSH_DNS_DOMAIN), DOMAIN_MAXSIZE, Domain) && 
					Domain.length() > DOMAIN_MINSIZE && Domain.length() < DOMAIN_MAXSIZE)
						FlushDNSCache((const uint8_t *)Domain.c_str());
				else 
					PrintError(LOG_LEVEL_2, LOG_ERROR_SYSTEM, L"Convert multiple byte or wide char string error", 0, nullptr, 0);
			}
			else {
				Sleep(Parameter.FileRefreshTime);
			}
		}
	}

//Monitor terminated
	CloseHandle(hSlot);
	PrintError(LOG_LEVEL_2, LOG_ERROR_SYSTEM, L"MailSlot module Monitor terminated", 0, nullptr, 0);
	return false;
}
Esempio n. 7
0
//MailSlot of flush DNS cache Monitor
bool __fastcall FlushDNSMailSlotMonitor(
	void)
{
//System security setting
	std::shared_ptr<char> ACL_Buffer(new char[FILE_BUFFER_SIZE]());
	memset(ACL_Buffer.get(), 0, FILE_BUFFER_SIZE);
	SECURITY_ATTRIBUTES SecurityAttributes;
	SECURITY_DESCRIPTOR SecurityDescriptor;
	memset(&SecurityAttributes, 0, sizeof(SECURITY_ATTRIBUTES));
	memset(&SecurityDescriptor, 0, sizeof(SECURITY_DESCRIPTOR));
	PSID SID_Value = nullptr;

	InitializeSecurityDescriptor(&SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION);
	InitializeAcl((PACL)ACL_Buffer.get(), FILE_BUFFER_SIZE, ACL_REVISION);
	ConvertStringSidToSidW(SID_ADMINISTRATORS_GROUP, &SID_Value);
	AddAccessAllowedAce((PACL)ACL_Buffer.get(), ACL_REVISION, GENERIC_ALL, SID_Value);
	SetSecurityDescriptorDacl(&SecurityDescriptor, true, (PACL)ACL_Buffer.get(), false);
	SecurityAttributes.lpSecurityDescriptor = &SecurityDescriptor;
	SecurityAttributes.bInheritHandle = true;

//Create mailslot.
	HANDLE hSlot = CreateMailslotW(MAILSLOT_NAME, FILE_BUFFER_SIZE - 1U, MAILSLOT_WAIT_FOREVER, &SecurityAttributes);
	if (hSlot == INVALID_HANDLE_VALUE)
	{
		LocalFree(SID_Value);

		PrintError(LOG_LEVEL_2, LOG_ERROR_SYSTEM, L"Create mailslot error", GetLastError(), nullptr, 0);
		return false;
	}

	ACL_Buffer.reset();
	LocalFree(SID_Value);

//Initialization
	std::shared_ptr<wchar_t> lpszBuffer(new wchar_t[FILE_BUFFER_SIZE]());
	wmemset(lpszBuffer.get(), 0, FILE_BUFFER_SIZE);
	DWORD cbMessage = 0;
	BOOL Result = 0;

//MailSlot monitor
	for (;;)
	{
		Sleep(LOOP_INTERVAL_TIME_NO_DELAY);

	//Reset parameters.
		wmemset(lpszBuffer.get(), 0, FILE_BUFFER_SIZE);
		cbMessage = 0;

	//Read message from mailslot.
		Result = ReadFile(hSlot, lpszBuffer.get(), FILE_BUFFER_SIZE, &cbMessage, nullptr);
		if (Result == FALSE)
		{
			PrintError(LOG_LEVEL_3, LOG_ERROR_SYSTEM, L"MailSlot read messages error", GetLastError(), nullptr, 0);

			CloseHandle(hSlot);
			return false;
		}
		else if (memcmp(lpszBuffer.get(), MAILSLOT_MESSAGE_FLUSH_DNS, sizeof(wchar_t) * wcslen(MAILSLOT_MESSAGE_FLUSH_DNS)) == 0)
		{
			FlushAllDNSCache();
		}
		else {
			Sleep(LOOP_INTERVAL_TIME_MONITOR);
		}
	}

//Monitor terminated
	CloseHandle(hSlot);
	PrintError(LOG_LEVEL_2, LOG_ERROR_SYSTEM, L"MailSlot module Monitor terminated", 0, nullptr, 0);
	return false;
}