/*
 * StoreACL: Stores the value of the class variable pACL in the registry.
 * Returns TRUE if successful.
 */
BOOL 
vncAccessControl::StoreACL(PACL pACL){
    HKEY hk = NULL; 
	BOOL isSaveOK = FALSE;

    ACL_SIZE_INFORMATION AclInfo = {0, 0, 0};
	DWORD nAclInformationLength = sizeof(AclInfo);

	// Todo: Better error handling
	if (pACL)
		GetAclInformation(pACL, &AclInfo, nAclInformationLength, AclSizeInformation);

	__try{ if (RegCreateKey(HKEY_LOCAL_MACHINE, _T("Software\\ORL\\WinVNC3"), &hk)
			!= ERROR_SUCCESS){
			__leave;
		}
		  if (hk)
		  RegCloseKey(hk);

		if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\ORL\\WinVNC3"), 0, KEY_SET_VALUE, &hk)
			!= ERROR_SUCCESS){
			__leave;
		}
		
		if (RegSetValueEx(hk, _T("ACL"), 0, REG_BINARY, (LPBYTE) pACL, AclInfo.AclBytesInUse)
			!= ERROR_SUCCESS){
			__leave;
		}
		isSaveOK = TRUE;
	} __finally {
		if (hk)
			RegCloseKey(hk); 
	}
	return isSaveOK;
} 
Exemple #2
0
HRESULT COpcSecurity::CopyACL(PACL pDest, PACL pSrc)
{
	ACL_SIZE_INFORMATION aclSizeInfo;
	LPVOID pAce;
	ACE_HEADER *aceHeader;

	if (pSrc == NULL)
		return S_OK;

	if (!GetAclInformation(pSrc, (LPVOID) &aclSizeInfo, sizeof(ACL_SIZE_INFORMATION), AclSizeInformation))
		return HRESULT_FROM_WIN32(GetLastError());

	// Copy all of the ACEs to the new ACL
	for (UINT i = 0; i < aclSizeInfo.AceCount; i++)
	{
		if (!GetAce(pSrc, i, &pAce))
			return HRESULT_FROM_WIN32(GetLastError());

		aceHeader = (ACE_HEADER *) pAce;

		if (!AddAce(pDest, ACL_REVISION, 0xffffffff, pAce, aceHeader->AceSize))
			return HRESULT_FROM_WIN32(GetLastError());
	}

	return S_OK;
}
void DumpSD(PSECURITY_DESCRIPTOR pSD)
{
    DWORD dwSize = GetSecurityDescriptorLength(pSD);
    printf("\nSecurity Descriptor is of size %d", dwSize);

    BOOL DaclPresent, DaclDefaulted;
    PACL pDacl;
    if(GetSecurityDescriptorDacl(pSD, &DaclPresent,
                &pDacl, &DaclDefaulted) && DaclPresent)
    {

        // Dump the aces

        ACL_SIZE_INFORMATION inf;
        DWORD dwNumAces;
        if(GetAclInformation(
            pDacl,
            &inf,
            sizeof(ACL_SIZE_INFORMATION),
            AclSizeInformation
            ))
        {
            dwNumAces = inf.AceCount;
            printf("\nThe DACL has %d ACEs", dwNumAces);
            for(DWORD dwCnt = 0; dwCnt < dwNumAces; dwCnt++)
            {
                ACCESS_ALLOWED_ACE * pAce;
                if(GetAce(pDacl, dwCnt, (LPVOID *)&pAce))
                    DumpAce(pAce);
            }
        }
    }
}
static PyObject *get_perms(PyObject *self, PyObject *args)
{

	PyObject *py_perms = PyDict_New();
	//get file or directory name
    char *file;

    if (!PyArg_ParseTuple(args, "s", &file))
        return NULL;

	//setup security code
	PSECURITY_DESCRIPTOR pSD;
	PACL pDACL; 
    //GetNamedSecurityInfo() will give you the DACL when you ask for
    //DACL_SECURITY_INFORMATION. At this point, you have SIDs in the ACEs contained in the DACL. 
	ULONG result = GetNamedSecurityInfo(file,SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, 
	&pDACL, NULL, &pSD);

	if (result != ERROR_SUCCESS){ return NULL;}
	if (result == ERROR_SUCCESS){
		ACL_SIZE_INFORMATION aclSize = {0};
		if(pDACL != NULL){   
			if(!GetAclInformation(pDACL, &aclSize, sizeof(aclSize),
				AclSizeInformation)){
				return NULL;
			}
		}
	
		file_perms *fp = new file_perms[aclSize.AceCount];
		acl_info(pDACL, aclSize.AceCount, fp );
		
		//Dict
		for (ULONG i=0;i




//Boilerplate functions

//3 parts 
//name of python function
//C++ function
//flags METH_VARARGS means function takes variable number of args
static PyMethodDef fileperm_methods[] = {
	{ "get_perms", get_perms, METH_VARARGS },
	{ NULL }
};



void initfileperm()
{

Py_InitModule("fileperm",fileperm_methods);

}
HRESULT RemoveAllInheritedAces(PACL *ppAcl)
{
    BOOL bResult = FALSE;
    DWORD errorCode = S_OK;
    HRESULT hr = S_OK;
    ACL_SIZE_INFORMATION aclInformation;
    DWORD totalCount;
    DWORD aceIndex = 0;
    LPVOID ace = nullptr;
    BYTE aceFlags = 0;

    if ( !ARGUMENT_PRESENT(*ppAcl) )
    {
        return E_INVALIDARG;
    }

    bResult = GetAclInformation(
        *ppAcl,
        &aclInformation,
        sizeof(aclInformation),
        AclSizeInformation
        );
    FailGracefullyGLE(bResult, L"GetAclInformation");
    
    totalCount = aclInformation.AceCount;
    while ( aceIndex < totalCount ) 
    {
        bResult = GetAce(
            *ppAcl,
            aceIndex,
            &ace
            );
        FailGracefullyGLE(bResult, L"GetAce");
                        
        aceFlags = ((PACE_HEADER)ace)->AceFlags; 

        if (IS_FLAG_SET(aceFlags,INHERITED_ACE)) 
        {
            bResult = DeleteAce(
                *ppAcl,
                aceIndex);
            FailGracefullyGLE(bResult, L"DeleteAce");

            totalCount--;
        }
        else
        {
            aceIndex++;
        }
    }

exit_gracefully:
    return hr;
}
// This goes through every ACE in 'acl', sums the size of the inheritable
// ACEs, and puts it in dwSizeNeeded.
HRESULT GetSizeOfAllInheritableAces(PACL acl, DWORD &dwSizeNeeded)
{
    BOOL bResult;
    DWORD errorCode = S_OK;
    HRESULT hr = S_OK;
    ACL_SIZE_INFORMATION aclInformation;
    DWORD totalCount;
    LPVOID ace;
    BYTE aceFlags;

    if ( !ARGUMENT_PRESENT(acl) )
    {
        return E_INVALIDARG;
    }

    bResult = GetAclInformation(
        acl,
        &aclInformation,
        sizeof(aclInformation),
        AclSizeInformation
        );
    FailGracefullyGLE(bResult, L"GetAclInformation");

    totalCount = aclInformation.AceCount;

    // Start with zero as the size. We'll only initialize this
    // to sizeof(ACL) if we find an inheritable ACE.
    dwSizeNeeded = 0;
                    
    for ( DWORD aceIndex = 0; aceIndex < totalCount; aceIndex ++ )
    {
        bResult = GetAce(
            acl,
            aceIndex,
            &ace
            );
        FailGracefullyGLE(bResult, L"GetAce");
                        
        aceFlags = ((PACE_HEADER)ace)->AceFlags; 

        // Only count the inheritable ACEs
        if (IsInheritableAce(aceFlags)) 
        {
            // Initialize the size now that we've found an inheritable ACE
            if ( dwSizeNeeded == 0 )
            {
                dwSizeNeeded = sizeof(ACL);
            }
            dwSizeNeeded += ((PACE_HEADER)ace)->AceSize;
        }
    }
exit_gracefully:
    return hr;
}
Exemple #7
0
void Process::fillAceList(){ 
	ACL_SIZE_INFORMATION aclSizeInfo;
	ZeroMemory(&aclSizeInfo, sizeof(ACL_SIZE_INFORMATION));
    aclSizeInfo.AclBytesInUse = sizeof(ACL);

	ACL_REVISION_INFORMATION aclRevisionInformation;
	ZeroMemory(&aclRevisionInformation,sizeof(ACL_REVISION_INFORMATION));
	GetAclInformation(
		_dacl,
		(LPVOID)&aclRevisionInformation,
		sizeof(ACL_REVISION_INFORMATION),
		AclRevisionInformation);

	DWORD dwRtnCode = GetAclInformation(//Узнаем всю информацию о ACL. - Кол-во ACE  в ней
		_dacl,
		(LPVOID)&aclSizeInfo,
		sizeof(ACL_SIZE_INFORMATION),
		AclSizeInformation);

	if (!dwRtnCode)
		  throw(ProcessException("GetAclInformation error =",GetLastError()));
	
	PVOID pAce;
	for (DWORD i=0;i<aclSizeInfo.AceCount;++i){//По всем ACE
		if (GetAce(_dacl,i,&pAce)){
			switch (((ACE_HEADER*)pAce)->AceType)
			{
			case ACCESS_ALLOWED_ACE_TYPE:
				_allowedACEs.push_back((ACCESS_ALLOWED_ACE*)pAce);
				break;
			case ACCESS_DENIED_ACE_TYPE:
				_deniedACEs.push_back((ACCESS_DENIED_ACE*)pAce);
				break;
			default:
				printf("Undefined type\n");
				break;
			}
		}else
			throw(ProcessException("GetAce ERROR = ", GetLastError()));
	 }
}
void vncImportACL::GetOldACL(){
	PACL pOldACL = NULL;
	ACL_SIZE_INFORMATION asi;
	HKEY hk = NULL; 
	DWORD dwValueLength = SECURITY_DESCRIPTOR_MIN_LENGTH;
	
	__try{
		
		if (ERROR_SUCCESS != RegOpenKeyEx( HKEY_LOCAL_MACHINE,
			_T("Software\\ORL\\WinVNC3"),
			0, KEY_QUERY_VALUE, &hk )){
			__leave;
		}
		// Read the ACL value from the VNC registry key
		// First call to RegQueryValueEx just gets the buffer length.
		if (ERROR_SUCCESS != RegQueryValueEx(hk,	// subkey handle 
            _T("ACL"),					// value name 
            0,                      // must be zero 
            0,						// value type , not needed here
			NULL,					// 
            &dwValueLength)){       // length of value data 
			__leave;
		}
		pOldACL = (PACL) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwValueLength);
		
		if (ERROR_SUCCESS != RegQueryValueEx(hk,	// subkey handle 
            _T("ACL"),					// value name 
            0,										// must be zero 
            0,										// value type 
			(LPBYTE) pOldACL,
            &dwValueLength)){						// length of value data 
			__leave;
		}

	} __finally {
		if (hk)
			RegCloseKey(hk); 
	}

	if ( pOldACL == NULL )
		return;

	if (!GetAclInformation( pOldACL, &asi, sizeof asi, AclSizeInformation))	{
		_ftprintf(stderr, _T("GAI(): gle == %lu\n"), GetLastError());
		return;
	}

	for (DWORD i = 0; i < asi.AceCount; ++ i)
		ReadAce(i, pOldACL);

	HeapFree(GetProcessHeap(), 0, pOldACL);
}
Exemple #9
0
DWORD
AddAccessDeniedACEToACL (
    PACL *Acl,
    DWORD PermissionMask,
    LPTSTR Principal
    )
{
    ACL_SIZE_INFORMATION  aclSizeInfo;
    int                   aclSize;
    DWORD                 returnValue;
    PSID                  principalSID;
    PACL                  oldACL, newACL;

    oldACL = *Acl;

    returnValue = GetPrincipalSID (Principal, &principalSID);
    if (returnValue != ERROR_SUCCESS)
        return returnValue;

    GetAclInformation (oldACL, (LPVOID) &aclSizeInfo, (DWORD) sizeof (ACL_SIZE_INFORMATION), AclSizeInformation);

    aclSize = aclSizeInfo.AclBytesInUse +
              sizeof (ACL) + sizeof (ACCESS_DENIED_ACE) +
              GetLengthSid (principalSID) - sizeof (DWORD);

    newACL = (PACL) new BYTE [aclSize];

    if (!InitializeAcl (newACL, aclSize, ACL_REVISION))
    {
        free (principalSID);
        return GetLastError();
    }

    if (!AddAccessDeniedAce (newACL, ACL_REVISION2, PermissionMask, principalSID))
    {
        free (principalSID);
        return GetLastError();
    }

    returnValue = CopyACL (oldACL, newACL);
    if (returnValue != ERROR_SUCCESS)
    {
        free (principalSID);
        return returnValue;
    }

    *Acl = newACL;

    free (principalSID);
    return ERROR_SUCCESS;
}
Exemple #10
0
HRESULT COpcSecurity::AddAccessAllowedACEToACL(PACL *ppAcl, LPCTSTR pszPrincipal, DWORD dwAccessMask)
{
	ACL_SIZE_INFORMATION aclSizeInfo;
	int aclSize;
	DWORD returnValue;
	PSID principalSID;
	PACL oldACL, newACL = NULL;

	oldACL = *ppAcl;

	returnValue = GetPrincipalSID(pszPrincipal, &principalSID);
	if (FAILED(returnValue))
		return returnValue;

	aclSizeInfo.AclBytesInUse = 0;
	if (*ppAcl != NULL)
		GetAclInformation(oldACL, (LPVOID) &aclSizeInfo, (DWORD) sizeof(ACL_SIZE_INFORMATION), AclSizeInformation);

	aclSize = aclSizeInfo.AclBytesInUse + sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(principalSID) - sizeof(DWORD);

	OPCTRY(newACL = (PACL) new BYTE[aclSize]);
	if (newACL == NULL)
		return E_OUTOFMEMORY;

	if (!InitializeAcl(newACL, aclSize, ACL_REVISION))
	{
		free(principalSID);
		return HRESULT_FROM_WIN32(GetLastError());
	}

	returnValue = CopyACL(newACL, oldACL);
	if (FAILED(returnValue))
	{
		free(principalSID);
		return returnValue;
	}

	if (!AddAccessAllowedAce(newACL, ACL_REVISION2, dwAccessMask, principalSID))
	{
		free(principalSID);
		return HRESULT_FROM_WIN32(GetLastError());
	}

	*ppAcl = newACL;

	if (oldACL != NULL)
		free(oldACL);
	free(principalSID);
	return S_OK;
}
Exemple #11
0
/*
 * Returns JNI_TRUE if the specified owner is the only SID will access
 * to the file.
 */
static jboolean isAccessUserOnly(JNIEnv* env, SID* owner, ACL* acl) {
    ACL_SIZE_INFORMATION acl_size_info;
    DWORD i;

    /*
     * If there's no DACL then there's no access to the file
     */
    if (acl == NULL) {
        return JNI_TRUE;
    }

    /*
     * Get the ACE count
     */
    if (!GetAclInformation(acl, (void *) &acl_size_info, sizeof(acl_size_info),
                           AclSizeInformation)) {
        JNU_ThrowIOExceptionWithLastError(env, "GetAclInformation failed");
        return JNI_FALSE;
    }

    /*
     * Iterate over the ACEs. For each "allow" type check that the SID
     * matches the owner, and check that the access is read only.
     */
    for (i = 0; i < acl_size_info.AceCount; i++) {
        void* ace;
        ACCESS_ALLOWED_ACE *access;
        SID* sid;

        if (!GetAce(acl, i, &ace)) {
            JNU_ThrowIOExceptionWithLastError(env, "GetAce failed");
            return -1;
        }
        if (((ACCESS_ALLOWED_ACE *)ace)->Header.AceType != ACCESS_ALLOWED_ACE_TYPE) {
            continue;
        }
        access = (ACCESS_ALLOWED_ACE *)ace;
        sid = (SID *) &access->SidStart;
        if (!EqualSid(owner, sid)) {
            /*
             * If the ACE allows any access then the file is not secure.
             */
            if (access->Mask & ANY_ACCESS) {
                return JNI_FALSE;
            }
        }
    }
    return JNI_TRUE;
}
Exemple #12
0
DWORD CopyACL(
    PACL OldACL,
    PACL NewACL)
{
    ACL_SIZE_INFORMATION aclSizeInfo;
    LPVOID ace;
    ACE_HEADER *aceHeader;
    ULONG i;

    GetAclInformation(
        OldACL,
        (LPVOID) &aclSizeInfo,
        (DWORD) sizeof (aclSizeInfo),
        AclSizeInformation);

    //
    // Copy all of the ACEs to the new ACL
    //

    for (i = 0; i < aclSizeInfo.AceCount; i++)
    {
        //
        // Get the ACE and header info
        //

        if (!GetAce (OldACL, i, &ace))
        {
            return GetLastError();
        }

        aceHeader = (ACE_HEADER *) ace;

        //
        // Add the ACE to the new list
        //

        if (!AddAce(
            NewACL,
            ACL_REVISION,
            0xffffffff,
            ace,
            aceHeader->AceSize))
        {
            return GetLastError();
        }
    }

    return ERROR_SUCCESS;
}
void vncExportACL::PrintAcl(PACL acl)
{
    DWORD i;
    ACL_SIZE_INFORMATION aci;

    if ( acl == 0 )
        return;

    if (!GetAclInformation( acl, &aci, sizeof aci, AclSizeInformation))	{
        _tprintf(_T("GAI(): gle == %lu\n"), GetLastError());
        return;
    }

    for ( i = 0; i < aci.AceCount; ++ i )
        PrintAce(i, acl);

}
bool vncImportACL::SetACL(PACL pACL){
	HKEY hk = NULL; 
	bool isSaveOK = false;
	DWORD  dwDisposition;

    ACL_SIZE_INFORMATION AclInformation = {0, 0, 0};
	DWORD nAclInformationLength = sizeof(AclInformation);

	// Todo: Better error handling
	if (pACL)
		GetAclInformation(pACL, &AclInformation, nAclInformationLength, AclSizeInformation);

	__try{
		//if (ERROR_SUCCESS != RegOpenKeyEx( HKEY_LOCAL_MACHINE,
		//	_T("Software\\ORL\\WinVNC3"),
		//	0, KEY_SET_VALUE, &hk )){
		//	_ftprintf(stderr, _T("Error %d: RegOpenKeyEx\n"), GetLastError());
		//	__leave;
		//}
		
		if (ERROR_SUCCESS != RegCreateKeyEx( HKEY_LOCAL_MACHINE,
			_T("Software\\ORL\\WinVNC3"),
			0, NULL, 0, KEY_SET_VALUE, NULL, &hk, &dwDisposition )){
			_ftprintf(stderr, _T("Error %d: RegOpenKeyEx\n"), GetLastError());
			__leave;
		}

		// Add the ACL value to the VNC registry key
		if (ERROR_SUCCESS != RegSetValueEx(hk,
            _T("ACL"),
            0,
            REG_BINARY,
			(LPBYTE) pACL,
            AclInformation.AclBytesInUse)){
			_ftprintf(stderr, _T("Error %d: RegSetValueEx\n"), GetLastError());
			__leave;
		}
		isSaveOK = true;
		_ftprintf(stderr, _T("RegSetValueEx passed\n"));
	} __finally {
		if (hk)
			RegCloseKey(hk); 
	}
	return isSaveOK;
}
Exemple #15
0
bool CSecRunAsUser::SetObjectPermission(CString strDirFile, DWORD lGrantedAccess){
	if (!m_hADVAPI32_DLL){
		ASSERT ( false );
		return false;
	}
	if ( strDirFile.IsEmpty() )
		return true;

	SID_NAME_USE   snuType;
	TCHAR* szDomain = NULL;
	LPVOID pUserSID = NULL;
	PACL pNewACL = NULL;
	PSECURITY_DESCRIPTOR pSD = NULL;
	BOOL fAPISuccess;
	
	try {
		// get user sid
		DWORD cbDomain = 0;
		DWORD cbUserSID = 0;
		fAPISuccess = LookupAccountName(NULL, EMULEACCOUNTW, pUserSID, &cbUserSID, szDomain, &cbDomain, &snuType);
		if ( (!fAPISuccess) && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
			throw CString(_T("Run as unpriveleged user: Error: LookupAccountName() failed,"));

		pUserSID = MHeapAlloc(cbUserSID);
		if (!pUserSID)
			throw CString(_T("Run as unpriveleged user: Error: Allocating memory failed,"));
		
		szDomain = (TCHAR*)MHeapAlloc(cbDomain * sizeof(TCHAR));
		if (!szDomain)
			throw CString(_T("Run as unpriveleged user: Error: Allocating memory failed,"));

		fAPISuccess = LookupAccountName(NULL, EMULEACCOUNTW, pUserSID, &cbUserSID, szDomain, &cbDomain, &snuType);

		if (!fAPISuccess)
			throw CString(_T("Run as unpriveleged user: Error: LookupAccountName()2 failed"));

		if (CStringW(szDomain) != m_strDomain)
			throw CString(_T("Run as unpriveleged user: Logical Error: Domainname mismatch"));

		// get old ACL
		PACL pOldACL = NULL;
		fAPISuccess = GetNamedSecurityInfo(strDirFile.GetBuffer(), SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &pOldACL, NULL, &pSD);
		strDirFile.ReleaseBuffer();
		if (fAPISuccess != ERROR_SUCCESS){
			throw CString(_T("Run as unpriveleged user: Error: GetNamedSecurityInfo() failed"));
		}

		// calculate size for new ACL
		ACL_SIZE_INFORMATION AclInfo;
		AclInfo.AceCount = 0; // Assume NULL DACL.
		AclInfo.AclBytesFree = 0;
		AclInfo.AclBytesInUse = sizeof(ACL);

		if (pOldACL != NULL && !GetAclInformation(pOldACL, &AclInfo, sizeof(ACL_SIZE_INFORMATION), AclSizeInformation))  
			throw CString(_T("Run as unpriveleged user: Error: GetAclInformation() failed"));

		// Create new ACL
		DWORD cbNewACL = AclInfo.AclBytesInUse + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(pUserSID) - sizeof(DWORD);

		pNewACL = (PACL)MHeapAlloc(cbNewACL);
		if (!pNewACL)
			throw CString(_T("Run as unpriveleged user: Error: Allocating memory failed,"));

		if (!InitializeAcl(pNewACL, cbNewACL, ACL_REVISION2))
			throw CString(_T("Run as unpriveleged user: Error: Allocating memory failed,"));


		// copy the entries form the old acl into the new one and enter a new ace in the right order
		uint32 newAceIndex = 0;
		uint32 CurrentAceIndex = 0;
		if (AclInfo.AceCount) {
			for (CurrentAceIndex = 0; CurrentAceIndex < AclInfo.AceCount; CurrentAceIndex++) {

					LPVOID pTempAce = NULL;
					if (!GetAce(pOldACL, CurrentAceIndex, &pTempAce))
						throw CString(_T("Run as unpriveleged user: Error: GetAce() failed,"));

					if (((ACCESS_ALLOWED_ACE *)pTempAce)->Header.AceFlags
						& INHERITED_ACE)
						break;
					// no multiple entries
					if (EqualSid(pUserSID, &(((ACCESS_ALLOWED_ACE *)pTempAce)->SidStart)))
						continue;

					if (!AddAce(pNewACL, ACL_REVISION, MAXDWORD, pTempAce, ((PACE_HEADER) pTempAce)->AceSize))
						throw CString(_T("Run as unpriveleged user: Error: AddAce()1 failed,"));
					newAceIndex++;
			}
		}
		// here we add the actually entry
		if (!AddAccessAllowedAceEx(pNewACL, ACL_REVISION2, CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE, lGrantedAccess, pUserSID))
			throw CString(_T("Run as unpriveleged user: Error: AddAccessAllowedAceEx() failed,"));	
		
		// copy the rest
		if (AclInfo.AceCount) {
			for (; CurrentAceIndex < AclInfo.AceCount; CurrentAceIndex++) {

					LPVOID pTempAce = NULL;
					if (!GetAce(pOldACL, CurrentAceIndex, &pTempAce))
						throw CString(_T("Run as unpriveleged user: Error: GetAce()2 failed,"));

					if (!AddAce(pNewACL, ACL_REVISION, MAXDWORD, pTempAce, ((PACE_HEADER) pTempAce)->AceSize))
						throw CString(_T("Run as unpriveleged user: Error: AddAce()2 failed,"));
				}
		}

		fAPISuccess = SetNamedSecurityInfo(strDirFile.GetBuffer(), SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, pNewACL, NULL);
		strDirFile.ReleaseBuffer();
		if (fAPISuccess != ERROR_SUCCESS)
			throw CString(_T("Run as unpriveleged user: Error: SetNamedSecurityInfo() failed,"));
		fAPISuccess = TRUE;
	}
	catch(CString error){
		fAPISuccess = FALSE;
		theApp.QueueDebugLogLine(false, error);
	}
	// clean up
	if (pUserSID != NULL)
		MHeapFree(pUserSID);
	if (szDomain != NULL)
		MHeapFree(szDomain);
	if (pNewACL != NULL)
		MHeapFree(pNewACL);
	if (pSD != NULL)
		LocalFree(pSD);

	// finished
	return fAPISuccess!=FALSE;
}
Exemple #16
0
int
perm_granted(char *path, int perm_mask, char *user, char *realuser)
{
	int	rc;
	DWORD	i, j;
	ACL	   *pdacl = NULL;
	SECURITY_DESCRIPTOR *psd = NULL;
	ACL_SIZE_INFORMATION	sizeInfo;
	ACCESS_ALLOWED_ACE	*pace;
	struct	accessinfo	*allowed = NULL;
	struct  accessinfo	*denied = NULL;
	int			mask;
	char			*name;
	SID			*usid;

	if (GetNamedSecurityInfo(path, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
		0, 0, &pdacl, 0, &psd) != ERROR_SUCCESS) {
		errno = GetLastError();
		rc = 1;
		goto perm_chkerr;
	}

	usid = getusersid2(user, realuser);
	if (usid == NULL) {
		rc = 2;
		goto perm_chkerr;
	}

	/* make sure perm mask granted only to privilege groups or the
	 special 'owner' */

	GetAclInformation(pdacl, &sizeInfo, sizeof(sizeInfo),
		AclSizeInformation);

	allowed = (struct accessinfo *)malloc(sizeof(struct accessinfo)*sizeInfo.AceCount);
	denied = (struct accessinfo *)malloc(sizeof(struct accessinfo)*sizeInfo.AceCount);

	if (allowed == NULL || denied == NULL) {
		rc = 3;
		goto perm_chkerr;
	}

	accessinfo_init(allowed, sizeInfo.AceCount);
	accessinfo_init(denied, sizeInfo.AceCount);

	for (i=0; i < sizeInfo.AceCount; i++) {

		GetAce(pdacl, i, (void **)&pace);
		name = getgrpname_full((SID *)&pace->SidStart);
		if (name == NULL)
			name = getusername((SID *)&pace->SidStart);

		/* later, we need to also check denied access which */
		/* overrides allowed access. */
		if ( (pace->Header.AceType == ACCESS_ALLOWED_ACE_TYPE) && \
			(mask=(pace->Mask & perm_mask)) && \
			     EqualSid((SID *)&pace->SidStart, usid) ) {
			(void)accessinfo_add(allowed, sizeInfo.AceCount,
				name, (mask & 0xFFFF));
		} else if (pace->Header.AceType == ACCESS_DENIED_ACE_TYPE) {
			(void)accessinfo_add(denied, sizeInfo.AceCount,
				name, (pace->Mask & 0xFFFF));
		} else {
			if (name) {
				(void)free(name);
			}
		}

	}
	/* filter the allowed pool so that none appear in denied */
	for (i=0; i < sizeInfo.AceCount; i++) {
		for (j=0; j < sizeInfo.AceCount; j++) {
			if( allowed[i].group == NULL || \
						denied[j].group == NULL )
				continue;

			if (strcmp(allowed[i].group, denied[j].group) == 0)
				allowed[i].mask &= ~denied[j].mask;
			/* unset the denied mask from allowed */
		}
	}

	/* now filter perm_mask to those specified in allowed */
	for (i=0; i < sizeInfo.AceCount; i++) {
		if (allowed[i].group == NULL)
			continue;

		/* unset the allowed mask from perm_mask */
		perm_mask &= ~allowed[i].mask;
	}

	if (perm_mask != 0) {
		rc = 4;
		goto perm_chkerr;
	}

	rc = 0;

perm_chkerr:
	if (pdacl) LocalFree(pdacl);
	if (psd) LocalFree(psd);
	if (allowed) accessinfo_free(allowed, sizeInfo.AceCount);
	if (denied) accessinfo_free(denied, sizeInfo.AceCount);
	if (usid) LocalFree(usid);

	return (rc);
}
Exemple #17
0
/**
 * This function adjusts the specified Desktop to include the specfied
 *   user.
 *
 * See: http://msdn2.microsoft.com/en-us/library/aa379608(VS.85).aspx
 **/
BOOL AddAceToDesktop(HDESK hdesk, PSID psid)
{
   ACL_SIZE_INFORMATION aclSizeInfo;
   BOOL                 bDaclExist;
   BOOL                 bDaclPresent;
   BOOL                 bSuccess = FALSE;
   DWORD                dwNewAclSize;
   DWORD                dwSidSize = 0;
   DWORD                dwSdSizeNeeded;
   PACL                 pacl = NULL;
   PACL                 pNewAcl = NULL;
   PSECURITY_DESCRIPTOR psd = NULL;
   PSECURITY_DESCRIPTOR psdNew = NULL;
   PVOID                pTempAce;
   SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION;
   unsigned int         i;

   try
   {
      // Obtain the security descriptor for the desktop object.

      if (!GetUserObjectSecurity(
            hdesk,
            &si,
            psd,
            dwSidSize,
            &dwSdSizeNeeded))
      {
         if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
         {
            psd = (PSECURITY_DESCRIPTOR)HeapAlloc(
                  GetProcessHeap(),
                  HEAP_ZERO_MEMORY,
                  dwSdSizeNeeded );

            if (psd == NULL)
               throw;

            psdNew = (PSECURITY_DESCRIPTOR)HeapAlloc(
                  GetProcessHeap(),
                  HEAP_ZERO_MEMORY,
                  dwSdSizeNeeded);

            if (psdNew == NULL)
               throw;

            dwSidSize = dwSdSizeNeeded;

            if (!GetUserObjectSecurity(
                  hdesk,
                  &si,
                  psd,
                  dwSidSize,
                  &dwSdSizeNeeded)
            )
               throw;
         }
         else
            throw;
      }

      // Create a new security descriptor.

      if (!InitializeSecurityDescriptor(
            psdNew,
            SECURITY_DESCRIPTOR_REVISION)
      )
         throw;

      // Obtain the DACL from the security descriptor.

      if (!GetSecurityDescriptorDacl(
            psd,
            &bDaclPresent,
            &pacl,
            &bDaclExist)
      )
         throw;

      // Initialize.

      ZeroMemory(&aclSizeInfo, sizeof(ACL_SIZE_INFORMATION));
      aclSizeInfo.AclBytesInUse = sizeof(ACL);

      // Call only if NULL DACL.

      if (pacl != NULL)
      {
         // Determine the size of the ACL information.

         if (!GetAclInformation(
               pacl,
               (LPVOID)&aclSizeInfo,
               sizeof(ACL_SIZE_INFORMATION),
               AclSizeInformation)
         )
            throw;
      }

      // Compute the size of the new ACL.

      dwNewAclSize = aclSizeInfo.AclBytesInUse +
            sizeof(ACCESS_ALLOWED_ACE) +
            GetLengthSid(psid) - sizeof(DWORD);

      // Allocate buffer for the new ACL.

      pNewAcl = (PACL)HeapAlloc(
            GetProcessHeap(),
            HEAP_ZERO_MEMORY,
            dwNewAclSize);

      if (pNewAcl == NULL)
         throw;

      // Initialize the new ACL.

      if (!InitializeAcl(pNewAcl, dwNewAclSize, ACL_REVISION))
         throw;

      // If DACL is present, copy it to a new DACL.

      if (bDaclPresent)
      {
         // Copy the ACEs to the new ACL.
         if (aclSizeInfo.AceCount)
         {
            for (i=0; i < aclSizeInfo.AceCount; i++)
            {
               // Get an ACE.
               if (!GetAce(pacl, i, &pTempAce))
                  throw;

               // Add the ACE to the new ACL.
               if (!AddAce(
                  pNewAcl,
                  ACL_REVISION,
                  MAXDWORD,
                  pTempAce,
                  ((PACE_HEADER)pTempAce)->AceSize)
               )
                  throw;
            }
         }
      }

      // Add ACE to the DACL.

      if (!AddAccessAllowedAce(
            pNewAcl,
            ACL_REVISION,
            GENERIC_ALL,
            psid)
      )
         throw;

      // Set new DACL to the new security descriptor.

      if (!SetSecurityDescriptorDacl(
            psdNew,
            TRUE,
            pNewAcl,
            FALSE)
      )
         throw;

      // Set the new security descriptor for the desktop object.

      if (!SetUserObjectSecurity(hdesk, &si, psdNew))
         throw;

      // Indicate success.

      bSuccess = TRUE;
   }
   catch(...)
   {
      // Free buffers.

      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;
}
Exemple #18
0
/**
 * This function adjusts the specified WindowStation to include the specfied
 *   user.
 *
 * See: http://msdn2.microsoft.com/en-us/library/aa379608(VS.85).aspx
 **/
BOOL AddAceToWindowStation(HWINSTA hwinsta, PSID psid)
{
   ACCESS_ALLOWED_ACE   *pace = NULL;
   ACL_SIZE_INFORMATION aclSizeInfo;
   BOOL                 bDaclExist;
   BOOL                 bDaclPresent;
   BOOL                 bSuccess = FALSE;
   DWORD                dwNewAclSize;
   DWORD                dwSidSize = 0;
   DWORD                dwSdSizeNeeded;
   PACL                 pacl = NULL;
   PACL                 pNewAcl = NULL;
   PSECURITY_DESCRIPTOR psd = NULL;
   PSECURITY_DESCRIPTOR psdNew = NULL;
   PVOID                pTempAce;
   SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION;
   unsigned int         i;

   try
   {
      // Obtain the DACL for the window station.

      if (!GetUserObjectSecurity(
             hwinsta,
             &si,
             psd,
             dwSidSize,
             &dwSdSizeNeeded)
      )
      if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
      {
         psd = (PSECURITY_DESCRIPTOR)HeapAlloc(
               GetProcessHeap(),
               HEAP_ZERO_MEMORY,
               dwSdSizeNeeded);

         if (psd == NULL)
            throw;

         psdNew = (PSECURITY_DESCRIPTOR)HeapAlloc(
               GetProcessHeap(),
               HEAP_ZERO_MEMORY,
               dwSdSizeNeeded);

         if (psdNew == NULL)
            throw;

         dwSidSize = dwSdSizeNeeded;

         if (!GetUserObjectSecurity(
               hwinsta,
               &si,
               psd,
               dwSidSize,
               &dwSdSizeNeeded)
         )
            throw;
      }
      else
         throw;

      // Create a new DACL.

      if (!InitializeSecurityDescriptor(
            psdNew,
            SECURITY_DESCRIPTOR_REVISION)
      )
         throw;

      // Get the DACL from the security descriptor.

      if (!GetSecurityDescriptorDacl(
            psd,
            &bDaclPresent,
            &pacl,
            &bDaclExist)
      )
         throw;

      // Initialize the ACL.

      ZeroMemory(&aclSizeInfo, sizeof(ACL_SIZE_INFORMATION));
      aclSizeInfo.AclBytesInUse = sizeof(ACL);

      // Call only if the DACL is not NULL.

      if (pacl != NULL)
      {
         // get the file ACL size info
         if (!GetAclInformation(
               pacl,
               (LPVOID)&aclSizeInfo,
               sizeof(ACL_SIZE_INFORMATION),
               AclSizeInformation)
         )
            throw;
      }

      // Compute the size of the new ACL.

      dwNewAclSize = aclSizeInfo.AclBytesInUse +
            (2*sizeof(ACCESS_ALLOWED_ACE)) + (2*GetLengthSid(psid)) -
            (2*sizeof(DWORD));

      // Allocate memory for the new ACL.

      pNewAcl = (PACL)HeapAlloc(
            GetProcessHeap(),
            HEAP_ZERO_MEMORY,
            dwNewAclSize);

      if (pNewAcl == NULL)
         throw;

      // Initialize the new DACL.

      if (!InitializeAcl(pNewAcl, dwNewAclSize, ACL_REVISION))
         throw;

      // If DACL is present, copy it to a new DACL.

      if (bDaclPresent)
      {
         // Copy the ACEs to the new ACL.
         if (aclSizeInfo.AceCount)
         {
            for (i=0; i < aclSizeInfo.AceCount; i++)
            {
               // Get an ACE.
               if (!GetAce(pacl, i, &pTempAce))
                  throw;

               // Add the ACE to the new ACL.
               if (!AddAce(
                     pNewAcl,
                     ACL_REVISION,
                     MAXDWORD,
                     pTempAce,
                    ((PACE_HEADER)pTempAce)->AceSize)
               )
                  throw;
            }
         }
      }

      // Add the first ACE to the window station.

      pace = (ACCESS_ALLOWED_ACE *)HeapAlloc(
            GetProcessHeap(),
            HEAP_ZERO_MEMORY,
            sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(psid) - sizeof(DWORD)
      );

      if (pace == NULL)
         throw;

      pace->Header.AceType  = ACCESS_ALLOWED_ACE_TYPE;
      pace->Header.AceFlags = CONTAINER_INHERIT_ACE |
                              INHERIT_ONLY_ACE |
                              OBJECT_INHERIT_ACE;
      pace->Header.AceSize  = (WORD)sizeof(ACCESS_ALLOWED_ACE) + 
                              (WORD)GetLengthSid(psid) - 
                              (WORD)sizeof(DWORD);
      pace->Mask            = GENERIC_ALL;

      if (!CopySid(GetLengthSid(psid), &pace->SidStart, psid))
         throw;

      if (!AddAce(
            pNewAcl,
            ACL_REVISION,
            MAXDWORD,
            (LPVOID)pace,
            pace->Header.AceSize)
      )
         throw;

      // Add an ACE to the window station.

      pace->Header.AceFlags = NO_PROPAGATE_INHERIT_ACE;
      pace->Mask            = GENERIC_ALL;

      if (!AddAce(
            pNewAcl,
            ACL_REVISION,
            MAXDWORD,
            (LPVOID)pace,
            pace->Header.AceSize)
      )
         throw;

      // Set a new DACL for the security descriptor.

      if (!SetSecurityDescriptorDacl(
            psdNew,
            TRUE,
            pNewAcl,
            FALSE)
      )
         throw;

      // Set the new security descriptor for the window station.

      if (!SetUserObjectSecurity(hwinsta, &si, psdNew))
         throw;

      // Indicate success.

      bSuccess = TRUE;
   }
   catch(...)
   {
      // Free the allocated buffers.

      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;

}
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);
	}
}
Exemple #20
0
static BOOL new_acl(SaveAclStruct *save_acl){
    HANDLE tokenh;
    TOKEN_DEFAULT_DACL newdacl;
    DWORD required;
    PACL oldacl;
    PACL newacl;
    int i;
    ACL_SIZE_INFORMATION si;
    size_t newsize;
    PSID extra_sid;
    SID_IDENTIFIER_AUTHORITY nt_auth = SECURITY_NT_AUTHORITY;  
    TOKEN_DEFAULT_DACL dummy;

    save_acl->initialized = FALSE;
    if(!OpenProcessToken(GetCurrentProcess(),
			 TOKEN_READ|TOKEN_WRITE,&tokenh)){
      log_warning("Failed to open access token.");
      return FALSE;
    } 
    save_acl->defdacl = &dummy;
    required = sizeof(TOKEN_DEFAULT_DACL);
    GetTokenInformation(tokenh,
			TokenDefaultDacl,
			&(save_acl->defdacl),
			sizeof(TOKEN_DEFAULT_DACL),
			&required);
    if(required == 0){
      log_warning("Failed to get any ACL info from token.");
      CloseHandle(tokenh);
      return FALSE;
    }
    save_acl->defdacl = LocalAlloc(LPTR,required);
    if(!GetTokenInformation(tokenh,
			    TokenDefaultDacl,
			    save_acl->defdacl,
			    required,
			    &required)){
#ifdef HARDDEBUG
	{
	  char *mes;
	  FormatMessage(
			FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
			NULL,    
			GetLastError(),
			MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 
			(LPTSTR) &mes,    
			0,    
			NULL );
	  log_info(mes);
	  LocalFree(mes);
	}
#endif 
      log_warning("Failed to get default ACL from token.");
      CloseHandle(tokenh);
      return FALSE;
    }

    oldacl = save_acl->defdacl->DefaultDacl;
    if(!GetAclInformation(oldacl, &si, sizeof(si), 
			  AclSizeInformation)){
      log_warning("Failed to get size information for ACL");
      CloseHandle(tokenh);
      return FALSE;
    }

    if(!AllocateAndInitializeSid(&nt_auth,
				 2,
				 SECURITY_BUILTIN_DOMAIN_RID,
				 DOMAIN_ALIAS_RID_ADMINS,
				 0,
				 0,
				 0,
				 0,
				 0,
				 0,
				 &extra_sid)){
      log_warning("Failed to initialize administrator SID.");
      CloseHandle(tokenh);
      return FALSE;
    }

    newsize = si.AclBytesInUse + sizeof(ACL) +
      sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(extra_sid);
    
    newacl = LocalAlloc(LPTR,newsize);
    
    if(!InitializeAcl(newacl, newsize, ACL_REVISION)){
      log_warning("Failed to initialize new ACL.");
      LocalFree(newacl);
      FreeSid(extra_sid);
      CloseHandle(tokenh);
      return FALSE;
    }

    for(i=0;i<((int)si.AceCount);++i){
      ACE_HEADER *ace_header;
      if (!GetAce (oldacl, i, &ace_header)){
	log_warning("Failed to get ACE from old ACL.");
	LocalFree(newacl);
	FreeSid(extra_sid);
	CloseHandle(tokenh);
	return FALSE;
      }
      if(!AddAce(newacl,ACL_REVISION,0xffffffff,ace_header,
		 ace_header->AceSize)){
	log_warning("Failed to set ACE in new ACL.");
	LocalFree(newacl);
	FreeSid(extra_sid);
	CloseHandle(tokenh);
	return FALSE;
      }
    }  
    if(!AddAccessAllowedAce(newacl,
			   ACL_REVISION2, 
			   PROCESS_ALL_ACCESS,
			   extra_sid)){
   	log_warning("Failed to add system ACE to new ACL.");
	LocalFree(newacl);
	FreeSid(extra_sid);
	return FALSE;
    }
    
    newdacl.DefaultDacl = newacl;
    if(!SetTokenInformation(tokenh,
			    TokenDefaultDacl,
			    &newdacl,
			    sizeof(newdacl))){
      log_warning("Failed to set token information");
      LocalFree(newacl);
      FreeSid(extra_sid);
      CloseHandle(tokenh);
      return FALSE;
    }
    save_acl->initialized = TRUE;
    save_acl->newacl = newacl;
    save_acl->adminsid = extra_sid;
    CloseHandle(tokenh);

    return TRUE;
}
Exemple #21
0
DWORD
RemovePrincipalFromACL (
    PACL Acl,
    LPTSTR Principal
    )
{
    ACL_SIZE_INFORMATION    aclSizeInfo;
    ULONG                   i;
    LPVOID                  ace;
    ACCESS_ALLOWED_ACE      *accessAllowedAce;
    ACCESS_DENIED_ACE       *accessDeniedAce;
    SYSTEM_AUDIT_ACE        *systemAuditAce;
    PSID                    principalSID;
    DWORD                   returnValue;
    ACE_HEADER              *aceHeader;

    returnValue = GetPrincipalSID (Principal, &principalSID);
    if (returnValue != ERROR_SUCCESS)
        return returnValue;

    GetAclInformation (Acl, (LPVOID) &aclSizeInfo, (DWORD) sizeof (ACL_SIZE_INFORMATION), AclSizeInformation);

    for (i = 0; i < aclSizeInfo.AceCount; i++)
    {
        if (!GetAce (Acl, i, &ace))
        {
            free (principalSID);
            return GetLastError();
        }

        aceHeader = (ACE_HEADER *) ace;

        if (aceHeader->AceType == ACCESS_ALLOWED_ACE_TYPE)
        {
            accessAllowedAce = (ACCESS_ALLOWED_ACE *) ace;

            if (EqualSid (principalSID, (PSID) &accessAllowedAce->SidStart))
            {
                DeleteAce (Acl, i);
                free (principalSID);
                return ERROR_SUCCESS;
            }
        } else

        if (aceHeader->AceType == ACCESS_DENIED_ACE_TYPE)
        {
            accessDeniedAce = (ACCESS_DENIED_ACE *) ace;

            if (EqualSid (principalSID, (PSID) &accessDeniedAce->SidStart))
            {
                DeleteAce (Acl, i);
                free (principalSID);
                return ERROR_SUCCESS;
            }
        } else

        if (aceHeader->AceType == SYSTEM_AUDIT_ACE_TYPE)
        {
            systemAuditAce = (SYSTEM_AUDIT_ACE *) ace;

            if (EqualSid (principalSID, (PSID) &systemAuditAce->SidStart))
            {
                DeleteAce (Acl, i);
                free (principalSID);
                return ERROR_SUCCESS;
            }
        }
    }

    free (principalSID);
    return ERROR_SUCCESS;
}
/*---------------------------------------------------------------------------*\
 * NAME: ListACL                                                             *
 * --------------------------------------------------------------------------*
 * DESCRIPTION: 
\*---------------------------------------------------------------------------*/
void ListACL (
    PACL Acl,
    DWORD dwSDType
    )
{
    ACL_SIZE_INFORMATION     aclSizeInfo                      = {0};
    ACL_REVISION_INFORMATION aclRevInfo                       = {0};
    ULONG                    i;
    LPVOID                   pvAce                            = NULL;
    ACE_HEADER               *pAceHeader                      = NULL;
    ACCESS_ALLOWED_ACE       *pAccessAllowedAce               = NULL;
    ACCESS_DENIED_ACE        *pAccessDeniedAce                = NULL;
    TCHAR                    tszDomainName [SIZE_NAME_BUFFER] = {0};
    TCHAR                    tszUserName [SIZE_NAME_BUFFER]   = {0};
    DWORD                    cchName = 0;
    SID_NAME_USE             snu;

    if (!GetAclInformation (Acl,
                            &aclSizeInfo,
                            sizeof (ACL_SIZE_INFORMATION),
                            AclSizeInformation))
    {
        _tprintf (_T("Could not get AclSizeInformation"));
        return;
    }

    if (!GetAclInformation (Acl,
                            &aclRevInfo,
                            sizeof (ACL_REVISION_INFORMATION),
                            AclRevisionInformation))
    {
        _tprintf (_T("Could not get AclRevisionInformation"));
        return;
    }

    for (i = 0; i < aclSizeInfo.AceCount; i++)
    {
        if (!GetAce (Acl, i, &pvAce))
            return;

        pAceHeader = (ACE_HEADER *) pvAce;

        if (pAceHeader->AceType == ACCESS_ALLOWED_ACE_TYPE)
        {
            pAccessAllowedAce = (ACCESS_ALLOWED_ACE *) pvAce;
            cchName = SIZE_NAME_BUFFER-1;
            LookupAccountSid (NULL,
                              &pAccessAllowedAce->SidStart,
                              tszUserName,
                              &cchName,
                              tszDomainName,
                              &cchName,
                              &snu);


            DisplayAccess(pAccessAllowedAce->Mask, 
                          dwSDType, 
                          _T("permitted"), 
                          tszUserName, 
                          tszDomainName);

        } 
        else if (pAceHeader->AceType == ACCESS_DENIED_ACE_TYPE)
        {
            pAccessDeniedAce = (ACCESS_DENIED_ACE *) pvAce;
            cchName = SIZE_NAME_BUFFER-1;
            LookupAccountSid (NULL,
                              &pAccessDeniedAce->SidStart,
                              tszUserName,
                              &cchName,
                              tszDomainName,
                              &cchName,
                              &snu);

            DisplayAccess(pAccessDeniedAce->Mask, 
                          dwSDType, 
                          _T("denied"), 
                          tszUserName, 
                          tszDomainName);
  
        }
   }
}
Exemple #23
0
BOOL CNTService::ModifyVistaDefaultAuditing(string dir, int remove)
{
	PSECURITY_DESCRIPTOR pSD = NULL;
	HANDLE hToken;
	PACL mySacl=NULL;
	DWORD ret=0;

	TOKEN_PRIVILEGES tp;
	LUID luid;

	if ( !LookupPrivilegeValue(NULL,SE_SECURITY_NAME,&luid)) {
		printf("LookupPrivilegeValue error: %u\n", GetLastError() ); 
		return FALSE; 
	}

	tp.PrivilegeCount = 1;
	tp.Privileges[0].Luid = luid;
	tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

	// Enable the privilege or disable all privileges.
	OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);
	if ( !AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL)) { 
		  printf("AdjustTokenPrivileges error: %u\n", GetLastError() ); 
		  return FALSE; 
	} 

	if (GetLastError() == ERROR_NOT_ALL_ASSIGNED) {
		  printf("The token does not have the specified privilege. \n");
		  return FALSE;
	} 

	//recurse through the dir
	WIN32_FIND_DATA findData;
	char Match[32], Replace[32];
	if (remove){
		strncpy_s(Match,_countof(Match),"Everyone",_TRUNCATE);
		strncpy_s(Replace,_countof(Replace),"ANONYMOUS LOGON",_TRUNCATE);
	} else {
		strncpy_s(Match,_countof(Match),"ANONYMOUS LOGON",_TRUNCATE);
		strncpy_s(Replace,_countof(Replace),"Everyone",_TRUNCATE);
	}

	HANDLE hFind=FindFirstFile((dir+"\\*.*").c_str(), &findData);

	if (hFind == INVALID_HANDLE_VALUE) {
		return TRUE;
	}

	// iterate over file names in directory
	do {
		string sFileName(findData.cFileName);

		if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
			// Directory
			if (sFileName != "." && sFileName != "..") {
				// descent recursively
				if (!ModifyVistaDefaultAuditing(dir+"\\"+sFileName, remove)) return FALSE;
			}
		} else {
			// File
			// grab and modify the file SACL
			ret = GetNamedSecurityInfo((char *)(dir+"\\"+findData.cFileName).c_str(),SE_FILE_OBJECT,SACL_SECURITY_INFORMATION,NULL,NULL,NULL,&mySacl,&pSD);
			if (ret == ERROR_SUCCESS && mySacl != NULL && mySacl->AceCount > 0) {
				int SetNewAcl=0;
				PACL pNewAcl;
				ACL_SIZE_INFORMATION aclSizeInfo;
				ZeroMemory(&aclSizeInfo, sizeof(ACL_SIZE_INFORMATION));
				aclSizeInfo.AclBytesInUse = sizeof(ACL);
				
				if (!GetAclInformation(mySacl,(LPVOID)&aclSizeInfo,sizeof(ACL_SIZE_INFORMATION),AclSizeInformation)) {
					printf("Can't find ACL info, exiting\n");
					return FALSE;
				}
				pNewAcl = (PACL)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,aclSizeInfo.AclBytesInUse);
				if (!pNewAcl) {
					printf("Can't allocate new ACL, exiting\n");
					return FALSE;
				}
				if (!InitializeAcl(pNewAcl,aclSizeInfo.AclBytesInUse,ACL_REVISION)) {
					printf("Can't allocate new ACL, exiting\n");
					return FALSE;
				}
				//printf("Checking: %s[%d]\n",(char *)(dir+"\\"+findData.cFileName).c_str(),mySacl->AceCount);
				for (int i=0; i< mySacl->AceCount; i++) {
					PVOID pAce;//PACE_HEADER?
					SID *pAceSid, *pNewAceSid=NULL;
					DWORD dwCbName = 0;
					DWORD dwCbDomainName = 0;
					SID_NAME_USE SidNameUse;
					TCHAR bufName[MAX_PATH]="";
					TCHAR bufDomain[MAX_PATH]="";
					ACCESS_MASK mask;
					SYSTEM_AUDIT_ACE *SA_Ace;
					TCHAR bufNewDomain[MAX_PATH];
					DWORD dwNewCbDomainName = 0;
					DWORD dwSidSize = 0;
					dwNewCbDomainName = _countof(bufNewDomain);
					BOOL bSuccess;
					
					if (GetAce(mySacl,i,&pAce)) {
						if (((ACE_HEADER *)pAce)->AceType != SYSTEM_AUDIT_ACE_TYPE) {
							printf("ACE ERROR: not SYSTEM_AUDIT_ACE_TYPE\n");
							continue;
						}
						SA_Ace = (SYSTEM_AUDIT_ACE *)pAce;
						pAceSid = (SID *)(&SA_Ace->SidStart);
						mask = SA_Ace->Mask;
						dwCbName = _countof(bufName);
						dwCbDomainName = _countof(bufDomain);

						bSuccess = LookupAccountSid(NULL, pAceSid, bufName, &dwCbName, bufDomain, &dwCbDomainName, &SidNameUse);
						if (!bSuccess) {
							printf("Failed to grab SID [%d]", GetLastError());
							return FALSE;
						}
						//printf("ACE of %s\\%s: %d\n", bufDomain, bufName, mask);
						if (!strcmp(bufName,Match)) {
							bSuccess = LookupAccountName(NULL, Replace, NULL, &dwSidSize, bufNewDomain, &dwNewCbDomainName,&SidNameUse);
							if (!bSuccess && GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
								pNewAceSid = (SID *)malloc(dwSidSize);
								if (!pNewAceSid) {
									printf("memory failed\n");
									if (pNewAcl) HeapFree(GetProcessHeap(), 0, (LPVOID)pNewAcl);
									return FALSE;
								}
								bSuccess = LookupAccountName(NULL, Replace, pNewAceSid, &dwSidSize, bufNewDomain, &dwNewCbDomainName,&SidNameUse);
								if (bSuccess) {
									if (!AddAuditAccessAce(pNewAcl,ACL_REVISION,mask,pNewAceSid,TRUE,TRUE)) {
										printf("Failed to updated ACL[%d]\n",GetLastError());
										free(pNewAceSid);
										if (pNewAcl) HeapFree(GetProcessHeap(), 0, (LPVOID)pNewAcl);
										return FALSE;
									}
									SetNewAcl=1;
								} else {
									printf("FAILED: %d\n", GetLastError());
									//printf("\n");
								}
								free(pNewAceSid);
							} else {
								printf("FAILED to find %s\n",Replace);
							}
						} else {
							if (!AddAce(pNewAcl,ACL_REVISION,MAXDWORD,pAce,((PACE_HEADER)pAce)->AceSize)) {
								printf("Couldn't add ACE to acl [%d]\n",GetLastError());
								if (pNewAcl) HeapFree(GetProcessHeap(), 0, (LPVOID)pNewAcl);
								return FALSE;
							}
						}
					} else {
						printf("ACE error %d:%d[%d]\n",mySacl->AceCount,i,GetLastError());
						return FALSE;
					}
				}
				if (SetNewAcl && pNewAcl) {
					ret = SetNamedSecurityInfo((char *)(dir+"\\"+findData.cFileName).c_str(),SE_FILE_OBJECT,SACL_SECURITY_INFORMATION,NULL,NULL,NULL,pNewAcl);
					if (ret == ERROR_SUCCESS) {
						printf("Fixed: %s\n",(char *)(dir+"\\"+findData.cFileName).c_str());
					} else {
						printf("Failed to fix: %s\n",(char *)(dir+"\\"+findData.cFileName).c_str());
					}
				}
				if (pNewAcl) HeapFree(GetProcessHeap(), 0, (LPVOID)pNewAcl);
			} else {
				if (ret) printf("fail %d %s\n", ret,(char *)(dir+"\\"+findData.cFileName).c_str());
				//else printf("NO SACL: %s\n",(char *)(dir+"\\"+findData.cFileName).c_str());
			}
			if (pSD) LocalFree(pSD);
		}
	} while (FindNextFile(hFind, &findData));
	return TRUE;
}
Exemple #24
0
//
// get_permissions:  1 = yes, 0 = no, -1 = unknown/error
//
int perm::get_permissions( const char *file_name, ACCESS_MASK &AccessRights ) {
	DWORD retVal;
	PACL pacl;
	
	PSECURITY_DESCRIPTOR pSD;
	DWORD pSD_length = 0;
	DWORD pSD_length_needed = 0;
	BOOL acl_present = FALSE;
	BOOL acl_defaulted = FALSE;
	
	// Do the call first to find out how much space is needed.
	
	pSD = NULL;
	
	GetFileSecurity(
		file_name,					// address of string for file name
		DACL_SECURITY_INFORMATION,	// requested information
		pSD,						// address of security descriptor
		pSD_length, 				// size of security descriptor buffer
		&pSD_length_needed			// address of required size of buffer
		);
	
	if( pSD_length_needed <= 0 ) {					// Find out how much space is needed, if <=0 then error
		if ( (GetLastError() == ERROR_FILE_NOT_FOUND) || 
			(GetLastError() == ERROR_PATH_NOT_FOUND) ) {
			
			// Here we have the tricky part of walking up the directory path
			// Typically it works like this:  If the filename exists, great, we'll
			//	 get the permissions on that.  If the filename does not exist, then
			//	 we pop the filename part off the file_name and look at the
			//	 directory.  If that directory should be (for some odd reason) non-
			//	 existant, then we just pop that off, until either we find something
			//	 thats will give us a permissions bitmask, or we run out of places
			//	 to look (which shouldn't happen since c:\ should always give us
			//	 SOMETHING...
			int i = strlen( file_name ) - 1;
			while ( i >= 0 && ( file_name[i] != '\\' && file_name[i] != '/' ) ) {
				i--;
			}
			if ( i < 0 ) {	// We've nowhere else to look, and this is bad.
				return -1;	// Its not a no, its an unknown
			}
			char *new_file_name = new char[i+1];
			strncpy(new_file_name, file_name, i);
			new_file_name[i]= '\0';
			
			// Now that we've chopped off more of the filename, call get_permissions
			// again...
			retVal = get_permissions( new_file_name, AccessRights );
			delete[] new_file_name;
			
			// ... and return what it returns. (after deleting the string that was
			// allocated.
			
			return retVal;
		}
		dprintf(D_ALWAYS, "perm::GetFileSecurity failed (err=%d)\n", GetLastError());
		return -1;
	}
	
	pSD_length = pSD_length_needed + 2; 	// Add 2 for safety.
	pSD_length_needed = 0;
	pSD = new BYTE[pSD_length];
	
	// Okay, now that we've found something, and know how large of an SD we need,
	// call the thing for real and lets get ON WITH IT ALREADY...
	
	if( !GetFileSecurity(
		file_name,					// address of string for file name
		DACL_SECURITY_INFORMATION,	// requested information
		pSD,						// address of security descriptor
		pSD_length, 				// size of security descriptor buffer
		&pSD_length_needed			// address of required size of buffer
		) ) {
		dprintf(D_ALWAYS, "perm::GetFileSecurity(%s) failed (err=%d)\n", file_name, GetLastError());
		delete[] pSD;
		return -1;
	}
	
	// Now, get the ACL from the security descriptor
	if( !GetSecurityDescriptorDacl(
		pSD,							// address of security descriptor
		&acl_present,					// address of flag for presence of disc. ACL
		&pacl,							// address of pointer to ACL
		&acl_defaulted					// address of flag for default disc. ACL
		) ) {
		dprintf(D_ALWAYS, "perm::GetSecurityDescriptorDacl failed (file=%s err=%d)\n", file_name, GetLastError());
		delete[] pSD;
		return -1;
	}
	
	// This is the workaround for the broken API GetEffectiveRightsFromAcl().
	// It should be guaranteed to work on all versions of NT and 2000 but be aware
	// that nested global group permissions are not supported.
	// C. Stolley - June 2001

	ACL_SIZE_INFORMATION acl_info;
		// Structure contains the following members:
		//  DWORD   AceCount; 
		//  DWORD   AclBytesInUse; 
		//  DWORD   AclBytesFree; 



	// first get the number of ACEs in the ACL
		if (! GetAclInformation( pacl,		// acl to get info from
								&acl_info,	// buffer to receive info
								sizeof(acl_info),  // size in bytes of buffer
								AclSizeInformation // class of info to retrieve
								) ) {
			dprintf(D_ALWAYS, "Perm::GetAclInformation failed with error %d\n", GetLastError() );
			return -1;
		}

		ACCESS_MASK allow = 0x0;
		ACCESS_MASK deny = 0x0;

		unsigned int aceCount = acl_info.AceCount;
		
		int result;
		
		// now look at each ACE in the ACL and see if it contains the user we're looking for
		for (unsigned int i=0; i < aceCount; i++) {
			LPVOID current_ace;

			if (! GetAce(	pacl,	// pointer to ACL 
							i,		// index of ACE we want
							&current_ace	// pointer to ACE
							) ) {
				dprintf(D_ALWAYS, "Perm::GetAce() failed! Error code %d\n", GetLastError() );
				return -1;
			}

			dprintf(D_FULLDEBUG, "Calling Perm::userInAce() for %s\\%s\n",
				   (Domain_name) ? Domain_name : "NULL",
				   (Account_name) ? Account_name : "NULL" );
			result = userInAce ( current_ace, Account_name, Domain_name );		
			
			if (result == 1) {
				switch ( ( (PACE_HEADER) current_ace)->AceType ) {				
				case ACCESS_ALLOWED_ACE_TYPE:
				case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
					allow |= ( (ACCESS_ALLOWED_ACE*) current_ace)->Mask;
					break;
				case ACCESS_DENIED_ACE_TYPE:
				case ACCESS_DENIED_OBJECT_ACE_TYPE:
					deny |= ( (ACCESS_DENIED_ACE*) current_ace)->Mask;
					break;
				}
			}
		}
		
		AccessRights = allow;
		AccessRights &= ~deny;

	// and now if we've made this far everything's happy so return true
	return 1;
}
Exemple #25
0
/**
 * @brief
 * 	perm_granted_admin_and_name: returns 0 if permission mask in 'disallow' has
 *	been granted to only admin-type of accounts and 'owner'. 'owner' can be
 *	set to NULL. Otherwise, it will return the values EPERM or EACCESS with
 *	error message returned in 'errmsg'.
 */
int
perm_granted_admin_and_owner(char *path, int disallow, char *owner, char *errmsg)
{
	int	rc;
	DWORD	i, j;
	SID	*powner = NULL;
	char	*powner_s = NULL;

	ACL	   *pdacl = NULL;
	SECURITY_DESCRIPTOR *psd = NULL;
	ACL_SIZE_INFORMATION	sizeInfo;
	ACCESS_ALLOWED_ACE	*pace;
	int			violate = 0;
	struct	accessinfo	*allowed = NULL;
	struct  accessinfo	*denied = NULL;
	int			mask;
	char			*name;
	SID			*esid = getusersid("Everyone");

	if (GetNamedSecurityInfo(path, SE_FILE_OBJECT,
		OWNER_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION,
		&powner, 0, &pdacl, 0, &psd) != ERROR_SUCCESS) {
		errno = GetLastError();
		rc = errno;
		sprintf(errmsg, "GetNameSecurityInfo on file %s failed", path);
		goto chkerr;
	}

	/* is owner SID a privilege user? */
	powner_s = getusername(powner);
	if (powner_s == NULL)
		powner_s = getgrpname(powner);

	if (powner_s != NULL) {
		if ( !sidIsAdminPrivilege(powner) || \
			( (owner != NULL) && strcmp(owner, powner_s) != 0 )  ) {
			rc = EPERM;
			sprintf(errmsg, "File %s not owned by user %s or an admin-type user!",
				path, owner);
			goto chkerr;
		}
	}

	/* make sure perm mask granted only to privilege groups or the
	 special 'owner' */

	GetAclInformation(pdacl, &sizeInfo, sizeof(sizeInfo),
		AclSizeInformation);

	allowed = (struct accessinfo *)malloc(sizeof(struct accessinfo)*sizeInfo.AceCount);
	denied = (struct accessinfo *)malloc(sizeof(struct accessinfo)*sizeInfo.AceCount);

	if (allowed == NULL || denied == NULL) {
		rc = errno;
		strcpy(errmsg, "malloc of allowed or denied struct failed!");
		goto chkerr;
	}

	accessinfo_init(allowed, sizeInfo.AceCount);
	accessinfo_init(denied, sizeInfo.AceCount);

	for (i=0; i < sizeInfo.AceCount; i++) {

		GetAce(pdacl, i, (void **)&pace);
		name = getgrpname_full((SID *)&pace->SidStart);
		if (name == NULL)
			name = getusername((SID *)&pace->SidStart);

		/* later, we need to also check denied access which */
		/* overrides allowed access. */
		if ( pace->Header.AceType == ACCESS_ALLOWED_ACE_TYPE &&\
			 (mask=(pace->Mask & disallow)) && \
			 ( EqualSid((SID *)&pace->SidStart, esid) || \
			sid2rid((SID *)&pace->SidStart) != \
					 SECURITY_CREATOR_OWNER_RID ) && \
			(!sidIsAdminPrivilege( (SID *)&pace->SidStart)) || \
   			((owner != NULL) && strcmp(name, owner) != 0) ) {
			(void)accessinfo_add(allowed, sizeInfo.AceCount,
				name, (mask & 0xFFFF));
		} else if (pace->Header.AceType == ACCESS_DENIED_ACE_TYPE) {
			(void)accessinfo_add(denied, sizeInfo.AceCount,
				name, (pace->Mask & 0xFFFF));
		} else {
			if (name) {
				(void)free(name);
			}
		}
	}
	/* validate */
	for (i=0; i < sizeInfo.AceCount; i++) {
		for (j=0; j < sizeInfo.AceCount; j++) {
			if( allowed[i].group == NULL || \
						denied[j].group == NULL )
				continue;

			if (strcmp(allowed[i].group, denied[j].group) == 0)
				allowed[i].mask &= ~denied[j].mask;
			/* unset the denied mask from allowed */
		}
	}


	if (!accessinfo_mask_allzero(allowed, sizeInfo.AceCount)) {
		rc = EACCES;
		sprintf(errmsg, "File %s has following disallowed perm masks: ",
			path);
		strcat(errmsg, accessinfo_values(allowed, sizeInfo.AceCount));
		goto chkerr;
	}

	rc = 0;

chkerr:
	if (powner_s)(void)free(powner_s);
	/* NOTE: powner and pdacl hang off of psd, so a free of psd would */
	/* automatically free them */
	if (psd) LocalFree(psd);
	if (allowed) accessinfo_free(allowed, sizeInfo.AceCount);
	if (denied) accessinfo_free(denied, sizeInfo.AceCount);
	if (esid) LocalFree(esid);

	return (rc);
}
BOOL AddAceToWindowStation(HWINSTA hwinsta, PSID psid)
{
    // Obtain the DACL for the window station.
    SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION;
    DWORD sd_length = 0;
    if (!GetUserObjectSecurity(hwinsta, &si, NULL, 0, &sd_length)) {
        if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
            printf("GetUserObjectSecurity() failed: %d\n", GetLastError());
            return FALSE;
        }
    }
    auto_buffer<PSECURITY_DESCRIPTOR> psd(sd_length);
    if (!GetUserObjectSecurity(hwinsta, &si, psd.get(), sd_length, &sd_length)) {
        printf("GetUserObjectSecurity() failed: %d\n", GetLastError());
        return FALSE;
    }

    // Create a new DACL.
    auto_buffer<PSECURITY_DESCRIPTOR> psd_new(sd_length);
    if (!InitializeSecurityDescriptor(psd_new.get(), SECURITY_DESCRIPTOR_REVISION)) {
        printf("InitializeSecurityDescriptor() failed: %d\n", GetLastError());
        return FALSE;
    }

    // Get the DACL from the security descriptor.
    BOOL bDaclPresent;
    PACL pacl;
    BOOL bDaclExist;
    if (!GetSecurityDescriptorDacl(psd.get(), &bDaclPresent, &pacl, &bDaclExist)) {
        printf("GetSecurityDescriptorDacl() failed: %d\n", GetLastError());
        return FALSE;
    }
    
    // Initialize the ACL.
    ACL_SIZE_INFORMATION aclSizeInfo = {};
    aclSizeInfo.AclBytesInUse = sizeof(ACL);
    if (NULL != pacl) {
        // get the file ACL size info
        if (!GetAclInformation(pacl, &aclSizeInfo, sizeof aclSizeInfo, AclSizeInformation)) {
            printf("GetAclInformation() failed: %d\n", GetLastError());
            return FALSE;
        }
    }

    // Compute the size of the new ACL.
    DWORD new_acl_size = aclSizeInfo.AclBytesInUse +
                         (2 * sizeof(ACCESS_ALLOWED_ACE)) + 
                         (2 * GetLengthSid(psid)) - (2 * sizeof(DWORD));
    auto_buffer<PACL> new_acl(new_acl_size);

    // Initialize the new DACL.
    if (!InitializeAcl(new_acl.get(), new_acl_size, ACL_REVISION)) {
        printf("InitializeAcl() failed: %d\n", GetLastError());
        return FALSE;
    }

    // If DACL is present, copy it to a new DACL.
    if (bDaclPresent) {
        // Copy the ACEs to the new ACL.
        if (aclSizeInfo.AceCount) {
            for (DWORD i = 0; i != aclSizeInfo.AceCount; ++i) {
                LPVOID pTempAce;
                if (!GetAce(pacl, i, &pTempAce)) {
                    printf("GetAce() failed: %d\n", GetLastError());
                    return FALSE;
                }
                if (!AddAce(new_acl.get(), ACL_REVISION, MAXDWORD,
                            pTempAce, ((PACE_HEADER)pTempAce)->AceSize)) {
                    printf("AddAce() failed: %d\n", GetLastError());
                    return FALSE;
                }
            }
        }
    }

    // Add the first ACE to the window station.
    auto_buffer<ACCESS_ALLOWED_ACE*> ace(sizeof(ACCESS_ALLOWED_ACE) +
                                         GetLengthSid(psid) -
                                         sizeof(DWORD));
    ace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
    ace->Header.AceFlags = CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE | OBJECT_INHERIT_ACE;
    ace->Header.AceSize = (WORD) (sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(psid) - sizeof(DWORD));
    ace->Mask = GENERIC_ACCESS;
    if (!CopySid(GetLengthSid(psid), &ace->SidStart, psid)) {
        printf("CopySid() failed: %d\n", GetLastError());
        return FALSE;
    }
    if (!AddAce(new_acl.get(), ACL_REVISION, MAXDWORD, ace.get(), ace->Header.AceSize)) {
        printf("AddAce() failed: %d\n", GetLastError());
        return FALSE;
    }

    // Add the second ACE to the window station.
    ace->Header.AceFlags = NO_PROPAGATE_INHERIT_ACE;
    ace->Mask = WINSTA_ALL;
    if (!AddAce(new_acl.get(), ACL_REVISION,MAXDWORD, ace.get(), ace->Header.AceSize)) {
        printf("AddAce() failed: %d\n", GetLastError());
        return FALSE;
    }

    // Set a new DACL for the security descriptor.
    if (!SetSecurityDescriptorDacl(psd_new.get(), TRUE, new_acl.get(), FALSE)) {
        printf("SetSecurityDescriptorDacl() failed: %d\n", GetLastError());
        return FALSE;
    }

    // Set the new security descriptor for the window station.
    if (!SetUserObjectSecurity(hwinsta, &si, psd_new.get())) {
        printf("SetUserObjectSecurity() failed: %d\n", GetLastError());
        return FALSE;
    }

    return TRUE;
}
BOOL RemoveAceFromDesktop(HDESK hdesk, PSID psid)
{
    // Obtain the security descriptor for the desktop object.
    SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION;
    DWORD sd_size = 0;
    if (!GetUserObjectSecurity(hdesk, &si, NULL, 0, &sd_size)) {
         if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
            printf("GetUserObjectSecurity() failed: %d\n", GetLastError());
            return FALSE;
         }
    }
    auto_buffer<PSECURITY_DESCRIPTOR> psd(sd_size);
    if (!GetUserObjectSecurity(hdesk, &si, psd.get(), sd_size, &sd_size)) {
        printf("GetUserObjectSecurity() failed: %d\n", GetLastError());
        return FALSE;
    }

    // Create a new security descriptor.
    auto_buffer<PSECURITY_DESCRIPTOR> psd_new(sd_size);
    if (!InitializeSecurityDescriptor(psd_new.get(), SECURITY_DESCRIPTOR_REVISION)) {
        printf("InitializeSecurityDescriptor() failed: %d\n", GetLastError());
        return FALSE;
    }

    // Obtain the DACL from the security descriptor.
    BOOL bDaclPresent;
    PACL pacl;
    BOOL bDaclExist;
    if (!GetSecurityDescriptorDacl(psd.get(), &bDaclPresent, &pacl, &bDaclExist)) {
        printf("GetSecurityDescriptorDacl() failed: %d\n", GetLastError());
        return FALSE;
    }

    // Initialize.
    ACL_SIZE_INFORMATION aclSizeInfo = {};
    aclSizeInfo.AclBytesInUse = sizeof(ACL);
    if (pacl != NULL) {
        // Determine the size of the ACL information.
        if (!GetAclInformation(pacl, (LPVOID)&aclSizeInfo, sizeof aclSizeInfo, AclSizeInformation)) {
            printf("GetAclInformation() failed: %d\n", GetLastError());
            return FALSE;
        }
    }

    // Allocate buffer for the new ACL.
    DWORD dwNewAclSize = aclSizeInfo.AclBytesInUse -
                         (sizeof(ACCESS_ALLOWED_ACE) +
                          GetLengthSid(psid) - sizeof(DWORD));
    auto_buffer<PACL> new_acl(dwNewAclSize);

    // Initialize the new ACL.
    if (!InitializeAcl(new_acl.get(), dwNewAclSize, ACL_REVISION)) {
        printf("InitializeAcl() failed: %d\n", GetLastError());
        return FALSE;
    }

    // If DACL is present, copy it to a new DACL.
    if (bDaclPresent) {
        // Copy the ACEs to the new ACL.
        for (DWORD i = 0; i != aclSizeInfo.AceCount; ++i) {
            // Get an ACE.
            ACCESS_ALLOWED_ACE* pace;
            if (!GetAce(pacl, i, (void**)&pace)) {
                printf("GetAce() failed: %d\n", GetLastError());
                return FALSE;
            }
            if (!EqualSid(psid, &pace->SidStart)) {
                // Add the ACE to the new ACL.
                if (!AddAce(new_acl.get(), ACL_REVISION,MAXDWORD, pace,
                            pace->Header.AceSize)) {
                    printf("AddAce() failed: %d\n", GetLastError());
                    return FALSE;
                }
            }
        }
    }

    // Set new DACL to the new security descriptor.
    if (!SetSecurityDescriptorDacl(psd_new.get(), TRUE, new_acl.get(), FALSE)) {
        printf("SetSecurityDescriptorDacl() failed: %d\n", GetLastError());
        return FALSE;
    }

    // Set the new security descriptor for the desktop object.
    if (!SetUserObjectSecurity(hdesk, &si, psd_new.get())) {
        printf("SetUserObjectSecurity() failed: %d\n", GetLastError());
        return FALSE;
    }
    
    return TRUE;
}
BOOL RemoveAceFromWindowStation(HWINSTA hwinsta, PSID psid)
{
    // Obtain the DACL for the window station.
    SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION;
    DWORD sd_length = 0;
    if (!GetUserObjectSecurity(hwinsta, &si, NULL, 0, &sd_length)) {
        if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
            printf("GetUserObjectSecurity() failed: %d\n", GetLastError());
            return FALSE;
        }
    }
    auto_buffer<PSECURITY_DESCRIPTOR> psd(sd_length);
    if (!GetUserObjectSecurity(hwinsta, &si, psd.get(), sd_length, &sd_length)) {
        printf("GetUserObjectSecurity() failed: %d\n", GetLastError());
        return FALSE;
    }

    // Create a new DACL.
    auto_buffer<PSECURITY_DESCRIPTOR> psd_new(sd_length);
    if (!InitializeSecurityDescriptor(psd_new.get(), SECURITY_DESCRIPTOR_REVISION)) {
        printf("InitializeSecurityDescriptor() failed: %d\n", GetLastError());
        return FALSE;
    }

    // Get the DACL from the security descriptor.
    BOOL bDaclPresent;
    PACL pacl;
    BOOL bDaclExist;
    if (!GetSecurityDescriptorDacl(psd.get(), &bDaclPresent, &pacl, &bDaclExist)) {
        printf("GetSecurityDescriptorDacl() failed: %d\n", GetLastError());
        return FALSE;
    }
    
    // Initialize the ACL.
    ACL_SIZE_INFORMATION aclSizeInfo = {};
    aclSizeInfo.AclBytesInUse = sizeof(ACL);
    if (NULL != pacl) {
        // get the file ACL size info
        if (!GetAclInformation(pacl, &aclSizeInfo, sizeof aclSizeInfo, AclSizeInformation)) {
            printf("GetAclInformation() failed: %d\n", GetLastError());
            return FALSE;
        }
    }

    // Compute the size of the new ACL.
    DWORD new_acl_size = aclSizeInfo.AclBytesInUse -
                         ((2 * sizeof(ACCESS_ALLOWED_ACE)) + 
                          (2 * GetLengthSid(psid)) - (2 * sizeof(DWORD)));
    auto_buffer<PACL> new_acl(new_acl_size);

    // Initialize the new DACL.
    if (!InitializeAcl(new_acl.get(), new_acl_size, ACL_REVISION)) {
        printf("InitializeAcl() failed: %d\n", GetLastError());
        return FALSE;
    }

    // If DACL is present, copy it to a new DACL.
    if (bDaclPresent) {
        // Copy the ACEs to the new ACL.
        for (DWORD i = 0; i != aclSizeInfo.AceCount; ++i) {
            ACCESS_ALLOWED_ACE* pace;
            if (!GetAce(pacl, i, (void**)&pace)) {
                printf("GetAce() failed: %d\n", GetLastError());
                return FALSE;
            }
            if (!EqualSid(psid, &pace->SidStart)) {
                if (!AddAce(new_acl.get(), ACL_REVISION, MAXDWORD,
                            pace, pace->Header.AceSize)) {
                    printf("AddAce() failed: %d\n", GetLastError());
                    return FALSE;
                }
            }
        }
    }

    // Set a new DACL for the security descriptor.
    if (!SetSecurityDescriptorDacl(psd_new.get(), TRUE, new_acl.get(), FALSE)) {
        printf("SetSecurityDescriptorDacl() failed: %d\n", GetLastError());
        return FALSE;
    }

    // Set the new security descriptor for the window station.
    if (!SetUserObjectSecurity(hwinsta, &si, psd_new.get())) {
        printf("SetUserObjectSecurity() failed: %d\n", GetLastError());
        return FALSE;
    }

    return TRUE;
}
Exemple #29
0
HRESULT COpcSecurity::RemovePrincipalFromACL(PACL pAcl, LPCTSTR pszPrincipal)
{
	ACL_SIZE_INFORMATION aclSizeInfo;
	ULONG i;
	LPVOID ace;
	ACCESS_ALLOWED_ACE *accessAllowedAce;
	ACCESS_DENIED_ACE *accessDeniedAce;
	SYSTEM_AUDIT_ACE *systemAuditAce;
	PSID principalSID;
	DWORD returnValue;
	ACE_HEADER *aceHeader;

	returnValue = GetPrincipalSID(pszPrincipal, &principalSID);
	if (FAILED(returnValue))
		return returnValue;

	GetAclInformation(pAcl, (LPVOID) &aclSizeInfo, (DWORD) sizeof(ACL_SIZE_INFORMATION), AclSizeInformation);

	for (i = 0; i < aclSizeInfo.AceCount; i++)
	{
		if (!GetAce(pAcl, i, &ace))
		{
			free(principalSID);
			return HRESULT_FROM_WIN32(GetLastError());
		}

		aceHeader = (ACE_HEADER *) ace;

		if (aceHeader->AceType == ACCESS_ALLOWED_ACE_TYPE)
		{
			accessAllowedAce = (ACCESS_ALLOWED_ACE *) ace;

			if (EqualSid(principalSID, (PSID) &accessAllowedAce->SidStart))
			{
				DeleteAce(pAcl, i);
				free(principalSID);
				return S_OK;
			}
		} else

		if (aceHeader->AceType == ACCESS_DENIED_ACE_TYPE)
		{
			accessDeniedAce = (ACCESS_DENIED_ACE *) ace;

			if (EqualSid(principalSID, (PSID) &accessDeniedAce->SidStart))
			{
				DeleteAce(pAcl, i);
				free(principalSID);
				return S_OK;
			}
		} else

		if (aceHeader->AceType == SYSTEM_AUDIT_ACE_TYPE)
		{
			systemAuditAce = (SYSTEM_AUDIT_ACE *) ace;

			if (EqualSid(principalSID, (PSID) &systemAuditAce->SidStart))
			{
				DeleteAce(pAcl, i);
				free(principalSID);
				return S_OK;
			}
		}
	}
	free(principalSID);
	return S_OK;
}
Exemple #30
-1
static int
TestplatformChmod(
    const char *nativePath,
    int pmode)
{
    static const SECURITY_INFORMATION infoBits = OWNER_SECURITY_INFORMATION
	    | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION;
    static const DWORD readOnlyMask = FILE_DELETE_CHILD | FILE_ADD_FILE
	    | FILE_ADD_SUBDIRECTORY | FILE_WRITE_EA | FILE_APPEND_DATA
	    | FILE_WRITE_DATA | DELETE;

    /*
     * References to security functions (only available on NT and later).
     */

    const BOOL set_readOnly = !(pmode & 0222);
    BOOL acl_readOnly_found = FALSE, curAclPresent, curAclDefaulted;
    SID_IDENTIFIER_AUTHORITY userSidAuthority = {
	SECURITY_WORLD_SID_AUTHORITY
    };
    BYTE *secDesc = 0;
    DWORD secDescLen, attr, newAclSize;
    ACL_SIZE_INFORMATION ACLSize;
    PACL curAcl, newAcl = 0;
    WORD j;
    SID *userSid = 0;
    char *userDomain = 0;
    int res = 0;

    /*
     * Process the chmod request.
     */

    attr = GetFileAttributesA(nativePath);

    /*
     * nativePath not found
     */

    if (attr == 0xffffffff) {
	res = -1;
	goto done;
    }

    /*
     * If nativePath is not a directory, there is no special handling.
     */

    if (!(attr & FILE_ATTRIBUTE_DIRECTORY)) {
	goto done;
    }

    /*
     * Set the result to error, if the ACL change is successful it will be
     * reset to 0.
     */

    res = -1;

    /*
     * Read the security descriptor for the directory. Note the first call
     * obtains the size of the security descriptor.
     */

    if (!GetFileSecurityA(nativePath, infoBits, NULL, 0, &secDescLen)) {
	DWORD secDescLen2 = 0;

	if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
	    goto done;
	}

	secDesc = (BYTE *) ckalloc(secDescLen);
	if (!GetFileSecurityA(nativePath, infoBits,
		(PSECURITY_DESCRIPTOR) secDesc, secDescLen, &secDescLen2)
		|| (secDescLen < secDescLen2)) {
	    goto done;
	}
    }

    /*
     * Get the World SID.
     */

    userSid = (SID *) ckalloc(GetSidLengthRequired((UCHAR) 1));
    InitializeSid(userSid, &userSidAuthority, (BYTE) 1);
    *(GetSidSubAuthority(userSid, 0)) = SECURITY_WORLD_RID;

    /*
     * If curAclPresent == false then curAcl and curAclDefaulted not valid.
     */

    if (!GetSecurityDescriptorDacl((PSECURITY_DESCRIPTOR) secDesc,
	    &curAclPresent, &curAcl, &curAclDefaulted)) {
	goto done;
    }
    if (!curAclPresent || !curAcl) {
	ACLSize.AclBytesInUse = 0;
	ACLSize.AceCount = 0;
    } else if (!GetAclInformation(curAcl, &ACLSize, sizeof(ACLSize),
	    AclSizeInformation)) {
	goto done;
    }

    /*
     * Allocate memory for the new ACL.
     */

    newAclSize = ACLSize.AclBytesInUse + sizeof(ACCESS_DENIED_ACE)
	    + GetLengthSid(userSid) - sizeof(DWORD);
    newAcl = (ACL *) ckalloc(newAclSize);

    /*
     * Initialize the new ACL.
     */

    if (!InitializeAcl(newAcl, newAclSize, ACL_REVISION)) {
	goto done;
    }

    /*
     * Add denied to make readonly, this will be known as a "read-only tag".
     */

    if (set_readOnly && !AddAccessDeniedAce(newAcl, ACL_REVISION,
	    readOnlyMask, userSid)) {
	goto done;
    }

    acl_readOnly_found = FALSE;
    for (j = 0; j < ACLSize.AceCount; j++) {
	LPVOID pACE2;
	ACE_HEADER *phACE2;

	if (!GetAce(curAcl, j, &pACE2)) {
	    goto done;
	}

	phACE2 = (ACE_HEADER *) pACE2;

	/*
	 * Do NOT propagate inherited ACEs.
	 */

	if (phACE2->AceFlags & INHERITED_ACE) {
	    continue;
	}

	/*
	 * Skip the "read-only tag" restriction (either added above, or it is
	 * being removed).
	 */

	if (phACE2->AceType == ACCESS_DENIED_ACE_TYPE) {
	    ACCESS_DENIED_ACE *pACEd = (ACCESS_DENIED_ACE *) phACE2;

	    if (pACEd->Mask == readOnlyMask
		    && EqualSid(userSid, (PSID) &pACEd->SidStart)) {
		acl_readOnly_found = TRUE;
		continue;
	    }
	}

	/*
	 * Copy the current ACE from the old to the new ACL.
	 */

	if (!AddAce(newAcl, ACL_REVISION, MAXDWORD, (PACL *) pACE2,
		((PACE_HEADER) pACE2)->AceSize)) {
	    goto done;
	}
    }

    /*
     * Apply the new ACL.
     */

    if (set_readOnly == acl_readOnly_found || SetNamedSecurityInfoA(
	    (LPSTR) nativePath, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
	    NULL, NULL, newAcl, NULL) == ERROR_SUCCESS) {
	res = 0;
    }

  done:
    if (secDesc) {
	ckfree((char *) secDesc);
    }
    if (newAcl) {
	ckfree((char *) newAcl);
    }
    if (userSid) {
	ckfree((char *) userSid);
    }
    if (userDomain) {
	ckfree((char *) userDomain);
    }

    if (res != 0) {
	return res;
    }

    /*
     * Run normal chmod command.
     */

    return chmod(nativePath, pmode);
}