Beispiel #1
0
int main(int argc, char* argv[])
#endif
{
    if (GetVersion() & 0x80000000)
    {
		_tprintf(_T("This application only runs on Windows NT/2000 or later"));
		return 0;
    }

	if (!ParseCommandLine(argc, argv))
		return 0;

	if (g_eat != ExamineAccessTokenNo)
	{
		CAccessToken at;
		if (!at.GetProcessToken(TOKEN_READ | TOKEN_QUERY_SOURCE))
			Log(_T("Could not open process token"));
		else
		{
			Log(_T("Process Access Token:"));
			DumpAccessToken(at);
		}
	}

	for (size_t i=0; i<g_aObjects.GetCount(); i++)
	{
		Log(_T("Security Descriptor for object %s:"), (LPCTSTR)g_aObjects[i]);
		switch (g_eot)
		{
		case ExamineObjectTypeDefault:
		case ExamineObjectTypeFile:
			DumpSecurityDescriptor(g_aObjects[i], SE_FILE_OBJECT, mapFileAccess);
			break;
		case ExamineObjectTypeRegkey:
			DumpSecurityDescriptor(g_aObjects[i], SE_REGISTRY_KEY, mapRegkeyAccess);
			break;
		case ExamineObjectTypeService:
			DumpSecurityDescriptor(g_aObjects[i], SE_SERVICE, mapServiceAccess);
			break;
		case ExamineObjectTypeKernel:
			DumpSecurityDescriptor(g_aObjects[i], SE_KERNEL_OBJECT, mapKernelAccess);
			break;
		case ExamineObjectTypePrinter:
			DumpSecurityDescriptor(g_aObjects[i], SE_PRINTER, mapPrinterAccess);
			break;
		default:
			ATLASSERT(FALSE);
		}
	}

	return 0;
}
Beispiel #2
0
void DumpSecurityDescriptor(LPCTSTR szObject, SE_OBJECT_TYPE type, Mapping* pAccessMappings)
{
	CSecurityDesc sd;
	SECURITY_INFORMATION si =
		OWNER_SECURITY_INFORMATION |
		GROUP_SECURITY_INFORMATION |
		DACL_SECURITY_INFORMATION |
		SACL_SECURITY_INFORMATION;

	if (!AtlGetSecurityDescriptor(szObject, type, &sd))
	{
		CIndent scope;

		si =
			OWNER_SECURITY_INFORMATION |
			GROUP_SECURITY_INFORMATION |
			DACL_SECURITY_INFORMATION;
		if (!AtlGetSecurityDescriptor(szObject, type, &sd, si))
		{
			Log(_T("Could not retrieve security descriptor"));
			return;
		}
		Log(_T("Could not retrieve SACL"));
	}

	DumpSecurityDescriptor(sd, si, pAccessMappings);
}
Beispiel #3
0
STDMETHODIMP
CObjSecurity::SetSecurity(SECURITY_INFORMATION si,
                           PSECURITY_DESCRIPTOR pSD)
{
	if(!::IsValidSecurityDescriptor(pSD))
	{
		return E_POINTER;
	}

    DWORD dwErr = 0;
	PSECURITY_DESCRIPTOR pParentSD = NULL;

	if (mp_NewSD)
	{
		LocalFree(mp_NewSD);
		mp_NewSD = NULL;
	}

	if (mhk_ParentRead != NULL)
	{
		dwErr = mp_Worker->GetKeySecurity(mhk_ParentRead, DACL_SECURITY_INFORMATION|SACL_SECURITY_INFORMATION, &pParentSD);
	}
	
	dwErr = CreateNewDescriptor(m_pOrigSD, // Old
					pParentSD, // Used for inheritance calculation, may be NULL
					si, pSD, // Changed (it must be merged with Old)
					&mp_NewSD, &m_SI); // Resultant
	
	if ((dwErr == 0) && (mhk_Write != NULL))
	{
		//dwErr = SetKeySecurityWindows(mhk_Write, m_SI, mp_NewSD);
		dwErr = mp_Worker->SetKeySecurity(mhk_Write, m_SI, mp_NewSD);
		
		// сразу чистим дескриптор, независимо от того "успешно или нет"
		LocalFree(mp_NewSD);
		mp_NewSD = NULL;
	}

	if (pParentSD)
		LocalFree(pParentSD);
						  
	return HRESULT_FROM_WIN32(dwErr);
	
#if 0 
	TCHAR szDbgLabel[64];
	wsprintf(szDbgLabel, _T("CObjSecurity::SetSecurity(0x%X)"), si);
    DumpSecurityDescriptor(pSD, si, szDbgLabel);

	PSID pNewOwner = NULL; BOOL lbOwnerDefaulted = FALSE;
	TRUSTEE *ptNewOwner = NULL, NewOwner = {NULL, NO_MULTIPLE_TRUSTEE, TRUSTEE_IS_SID, TRUSTEE_IS_UNKNOWN};
	if (!dwErr && (si & OWNER_SECURITY_INFORMATION))
	{
		if (::GetSecurityDescriptorOwner(pSD, &pNewOwner, &lbOwnerDefaulted))
		{
			NewOwner.ptstrName = (LPTSTR)pNewOwner;
			ptNewOwner = &NewOwner;
		}
		else
			dwErr = GetLastError();
	}
	PSID pNewGroup = NULL; BOOL lbGroupDefaulted = FALSE;
	TRUSTEE *ptNewGroup = NULL, NewGroup = {NULL, NO_MULTIPLE_TRUSTEE, TRUSTEE_IS_SID, TRUSTEE_IS_UNKNOWN};
	if (!dwErr && (si & GROUP_SECURITY_INFORMATION))
	{
		if (::GetSecurityDescriptorGroup(pSD, &pNewGroup, &lbGroupDefaulted))
		{
			NewGroup.ptstrName = (LPTSTR)pNewGroup;
			ptNewGroup = &NewGroup;
		}
		else
			dwErr = GetLastError();
	}
	PACL pNewDacl = NULL; BOOL lbDacl = FALSE, lbDaclDefaulted = FALSE;
	ULONG nDaclCount = 0; PEXPLICIT_ACCESS pDaclEntries = NULL;
	if (!dwErr && (si & DACL_SECURITY_INFORMATION))
	{
		if (::GetSecurityDescriptorDacl(pSD, &lbDacl, &pNewDacl, &lbDaclDefaulted))
		{
			dwErr = ::GetExplicitEntriesFromAcl(pNewDacl, &nDaclCount, &pDaclEntries);
		}
		else
			dwErr = GetLastError();
	}
	PACL pNewSacl = NULL; BOOL lbSacl = FALSE, lbSaclDefaulted = FALSE;
	ULONG nSaclCount = 0; PEXPLICIT_ACCESS pSaclEntries = NULL;
	if (!dwErr && (si & SACL_SECURITY_INFORMATION))
	{
		if (::GetSecurityDescriptorSacl(pSD, &lbSacl, &pNewSacl, &lbSaclDefaulted))
		{
			dwErr = ::GetExplicitEntriesFromAcl(pNewSacl, &nSaclCount, &pSaclEntries);
		}
		else
			dwErr = GetLastError();
	}

	PSECURITY_DESCRIPTOR pNewSD = NULL; ULONG nNewSize = 0;
	BOOL lbRc = FALSE;
	
	if (dwErr == 0)
		dwErr = BuildSecurityDescriptor(ptNewOwner, ptNewGroup, nDaclCount, pDaclEntries, nSaclCount, pSaclEntries,
			m_pOrigSD/*self-relative!*/, &nNewSize, &pNewSD);
	if (dwErr == 0)
	{
		DumpSecurityDescriptor(pNewSD, OWNER_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION|SACL_SECURITY_INFORMATION, _T("After BuildSecurityDescriptor"));
		if (pNewOwner)
		{
			if (!::SetSecurityDescriptorOwner(pNewSD, pNewOwner, lbOwnerDefaulted))
				dwErr = GetLastError();
			else
				DumpSecurityDescriptor(pNewSD, OWNER_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION|SACL_SECURITY_INFORMATION, _T("After SetSecurityDescriptorOwner"));
		}
		if (dwErr != 0)
			LocalFree(pNewSD);
		else
		{
			if (mp_NewSD)
				LocalFree(mp_NewSD);
			mp_NewSD = pNewSD;
			m_SI = si;
		}
	}
	else
		dwErr = GetLastError();

	//BOOL lb1 = IsValidSecurityDescriptor((PSECURITY_DESCRIPTOR)m_ppSD);
	//BOOL lb2 = IsValidSecurityDescriptor(*m_ppSD);
	//DumpSecurityDescriptor(*m_ppSD, OWNER_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION, _T("Stored descriptor pointer"));

	//WARNING("BuildSecurityDescriptor");
	//// она корректно выполнит
	//// builds the new security descriptor by merging the specified owner, group, access control,
	//// and audit-control information with the information in this security descriptor
	//// Наверное вообще не нужно со строками заморачиваться - сразу звать Build из SetSecurity.
	//// Ведь в m_pSD(новая!) уже лежит наша копия дескриптора.
	//// Ест-но в SetSecurity нужно проверить, что вернулось - если Absolute - звать MakeSelfRelativeSD
	//WARNING("Сделать OR на новую переменную масок - что юзер поменял");
	//
	//if (si & DACL_SECURITY_INFORMATION)
	//{
	//	if (mp_DaclSD)
	//	{
	//		LocalFree(mp_DaclSD);
	//		mp_DaclSD = NULL;
	//	}
	//	if (mpsz_DaclSD)
	//	{
	//		LocalFree(mpsz_DaclSD);
	//		mpsz_DaclSD = NULL;
	//	}

	//	ULONG nLen = 0;
	//	if (!ConvertSecurityDescriptorToStringSecurityDescriptor(pSD, SDDL_REVISION_1, DACL_SECURITY_INFORMATION,
	//			&mpsz_DaclSD, &nLen))
	//		dwErr = GetLastError();
	//}

	//if (si & OWNER_SECURITY_INFORMATION)
	//{
	//	if (mp_OwnerSD)
	//	{
	//		LocalFree(mp_OwnerSD);
	//		mp_OwnerSD = NULL;
	//	}
	//	if (mpsz_OwnerSD)
	//	{
	//		LocalFree(mpsz_OwnerSD);
	//		mpsz_OwnerSD = NULL;
	//	}

	//	ULONG nLen = 0;
	//	if (!ConvertSecurityDescriptorToStringSecurityDescriptor(pSD, SDDL_REVISION_1, OWNER_SECURITY_INFORMATION,
	//			&mpsz_OwnerSD, &nLen))
	//		dwErr = GetLastError();

	//	//DWORD nLen = GetSecurityDescriptorLength(pSD);
	//	//if (nLen)
	//	//{
	//	//	mp_OwnerSD = LocalAlloc(LPTR, nLen);
	//	//	if (mp_OwnerSD)
	//	//		memmove(mp_OwnerSD, pSD, nLen);
	//	//}
	//	//else
	//	//{
	//	//	mp_OwnerSD = NULL;
	//	//}
	//	//PSID pOwner = NULL; BOOL lbOwnerDefaulted = FALSE;
	//	//if (GetSecurityDescriptorOwner(pSD, &pOwner, &lbOwnerDefaulted))
	//	//{
	//	//	if (SetSecurityDescriptorOwner(*m_ppSD, pOwner, lbOwnerDefaulted))
	//	//	{
	//	//		DumpSecurityDescriptor(pSD, si, _T("CObjSecurity::SetSecurity Applied"));
	//	//	}
	//	//	else
	//	//	{
	//	//		dwErr = GetLastError();
	//	//	}
	//	//}
	//	//else
	//	//{
	//	//	dwErr = GetLastError();
	//	//}
	//}

#ifdef APPLY_SECURITY_TO_REG
    //
    // Assume that required privileges have already been enabled
    //
    //if (!SetPrivateObjectSecurity(si, pSD, m_ppSD, &ObjMap, mh_Token))
    //    dwErr = GetLastError();

	if (mpsz_KeyPath && *mpsz_KeyPath)
	{
		HKEY hk;
		dwErr = RegOpenKeyExW(mhk_Root, mpsz_KeyPath, 0, mdw_RegFlags, &hk);
		if (dwErr == 0)
		{
			dwErr = RegSetKeySecurity(hk, DACL_SECURITY_INFORMATION, pSD);
			RegCloseKey(hk);
		}
	}
	else
	{
		dwErr = RegSetKeySecurity(mhk_Root, DACL_SECURITY_INFORMATION, pSD);
	}

	if (dwErr == 0)
	{
	    DWORD dwLength = 0;
	    //
	    // Assume that required privileges have already been enabled
	    //
	    GetPrivateObjectSecurity(pSD, DACL_SECURITY_INFORMATION, NULL, 0, &dwLength);
	    if (dwLength)
	    {
	    	PSECURITY_DESCRIPTOR pNewSD = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR, dwLength);
	        if (pNewSD &&
	            !GetPrivateObjectSecurity(pSD, DACL_SECURITY_INFORMATION, pNewSD, dwLength, &dwLength))
	        {
	            dwErr = GetLastError();
	            LocalFree(pNewSD);
	            pNewSD = NULL;
	        }
	        else
	        {
	        	LocalFree((HLOCAL)*m_ppSD);
	        	*m_ppSD = pNewSD;
	        }
	    }
	    else
	        dwErr = GetLastError();
	}
#endif
	
    return HRESULT_FROM_WIN32(dwErr);
#endif
}
Beispiel #4
-1
STDMETHODIMP
CObjSecurity::Initialize(
		DWORD                  dwFlags,
		PSECURITY_DESCRIPTOR   pSD,
		LPCWSTR pszServerName,
		DWORD sam,
		MRegistryBase* apWorker,
		HKEY hkRoot,
		LPCWSTR pszKeyName,
		HKEY hkWrite, HKEY hkParentRead)
{
    HRESULT hr = S_OK;

	// Обязательно сделать копию дескриптора MakeSelfRelativeSD, т.к. функция GetSecurity тупо делает memcopy
	// Но учесть, что если он уже self-relative - то звать функцию здесь не нужно - просто сразу сделать копию памяти
	DWORD dwRevision = 0, nNewLen = 0;
	if (!GetSecurityDescriptorControl(pSD, &m_OrigControl, &dwRevision))
		return HRESULT_FROM_WIN32(GetLastError());
	if (m_OrigControl & SE_SELF_RELATIVE)
	{
		m_pOrigSD = pSD;
		mb_OrigSdDuplicated = FALSE;
	}
	else
	{
		//nNewLen = 8192;
		//m_pOrigSD = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR, nNewLen);
		if ((!::MakeSelfRelativeSD(pSD, NULL, &nNewLen) && !nNewLen) || !nNewLen)
			return HRESULT_FROM_WIN32(GetLastError());
		m_pOrigSD = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR, nNewLen);
		if (!::MakeSelfRelativeSD(pSD, &m_pOrigSD, &nNewLen))
			return HRESULT_FROM_WIN32(GetLastError());
		mb_OrigSdDuplicated = TRUE;
	}

#ifdef _DEBUG
	PACL pNewDacl = NULL; BOOL lbDacl = FALSE, lbDaclDefaulted = FALSE;
	ULONG nDaclCount = 0; PEXPLICIT_ACCESS pDaclEntries = NULL;
	DWORD dwErr = 0;
	PTRUSTEE pOwner = NULL, pGroup = NULL;
	ULONG nSaclCount = 0; PEXPLICIT_ACCESS pSaclEntries = NULL;
	dwErr = ::GetSecurityDescriptorDacl(m_pOrigSD, &lbDacl, &pNewDacl, &lbDaclDefaulted);
	ACL_SIZE_INFORMATION size_info = {0};
	ACCESS_ALLOWED_ACE *Ace = NULL;
	BOOL lbAce = FALSE;
	if (pNewDacl)
	{
		dwErr = ::GetAclInformation(pNewDacl, &size_info, sizeof(size_info), AclSizeInformation);
		for (UINT i = 0; i < size_info.AceCount; i++)
		{
			lbAce = ::GetAce(pNewDacl, i, (void**)&Ace);
		}
	}
	dwErr = ::LookupSecurityDescriptorParts(&pOwner, &pGroup, &nDaclCount, &pDaclEntries,
		&nSaclCount, &pSaclEntries, m_pOrigSD);
	DumpSecurityDescriptor(m_pOrigSD, DACL_SECURITY_INFORMATION|SACL_SECURITY_INFORMATION|OWNER_SECURITY_INFORMATION, _T("CObjSecurity::Initialize"));
#endif

    m_dwSIFlags = dwFlags;
	//#ifdef _DEBUG
	//	m_dwSIFlags = SI_ADVANCED | SI_EDIT_ALL;
	//#endif

    //m_wClient = wClient;
    //mh_Token = hToken;
	mp_Worker = apWorker;
	mhk_Write = hkWrite;
	mhk_ParentRead = hkParentRead;
	mhk_Root = hkRoot;
	mpsz_KeyPath = pszKeyName;
	mn_WowSamDesired = sam;
	//TODO: А нужно ли "\\" перед именем сервера?
	hr = LocalAllocString(&m_pszServerName, pszServerName);
	LPCWSTR pszName = NULL, pszRoot = NULL;
	if (hkRoot == HKEY_CLASSES_ROOT)
		pszRoot = L"CLASSES_ROOT";
	else if (hkRoot == HKEY_CURRENT_USER)
		pszRoot = L"CURRENT_USER";
	else if (hkRoot == HKEY_LOCAL_MACHINE)
		pszRoot = L"MACHINE";
	else if (hkRoot == HKEY_USERS)
		pszRoot = L"USERS";
	else
		pszRoot = L"UNKNOWN";
	if (pszKeyName && *pszKeyName)
	{
		pszName = wcsrchr(pszKeyName, L'\\');
		if (pszName) pszName++; else pszName = pszKeyName;
	}
	else
	{
		pszName = pszRoot ? pszRoot : L"<Unknown>";
	}
	hr = LocalAllocString(&m_pszObjectName, pszName);


	BOOL lbAllowInheritLookup = (sam == 0);
	if (!lbAllowInheritLookup)
	{
		#ifdef _WIN64
		lbAllowInheritLookup = (sam & KEY_WOW64_64KEY) == KEY_WOW64_64KEY;
		#else
		lbAllowInheritLookup = (sam & KEY_WOW64_32KEY) == KEY_WOW64_32KEY;
		#endif
	}
	// Если наследование проверить можно - создаем полный путь
	if (lbAllowInheritLookup)
	{
		int nFullLen = 10
			+ (pszServerName ? lstrlenW(pszServerName) : 0)
			+ (lstrlenW(pszRoot))
			+ (pszKeyName ? lstrlenW(pszKeyName) : 0);
		mpsz_KeyForInherit = (wchar_t*)calloc(nFullLen,sizeof(wchar_t));
		if (pszServerName && *pszServerName)
		{
			while (*pszServerName == L'\\' || *pszServerName == L'/') pszServerName++;
			lstrcatW(mpsz_KeyForInherit, L"\\\\");
			lstrcatW(mpsz_KeyForInherit, pszServerName);
			lstrcatW(mpsz_KeyForInherit, L"\\");
		}
		lstrcatW(mpsz_KeyForInherit, pszRoot);
		if (pszKeyName && *pszKeyName)
		{
			lstrcatW(mpsz_KeyForInherit, L"\\");
			lstrcatW(mpsz_KeyForInherit, pszKeyName);
		}
	}
	

	// Result
	//mp_OwnerSD = mp_DaclSD = NULL;
	mp_NewSD = NULL;
	m_SI = 0;


    return hr;
}