Exemple #1
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;
}
Exemple #2
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;
}
Exemple #3
0
BOOL
AddAceToWindowStation(
    IN HWINSTA WinSta,
    IN PSID Sid)
{
    DWORD AclSize;
    SECURITY_INFORMATION SecurityInformation;
    PACL pDefaultAcl = NULL;
    PSECURITY_DESCRIPTOR WinstaSd = NULL;
    PACCESS_ALLOWED_ACE Ace = NULL;
    BOOL Ret = FALSE;

    /* Allocate space for an ACL */
    AclSize = sizeof(ACL)
        + 2 * (FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + GetLengthSid(Sid));
    pDefaultAcl = HeapAlloc(GetProcessHeap(), 0, AclSize);
    if (!pDefaultAcl)
    {
        ERR("WL: HeapAlloc() failed\n");
        goto cleanup;
    }

    /* Initialize it */
    if (!InitializeAcl(pDefaultAcl, AclSize, ACL_REVISION))
    {
        ERR("WL: InitializeAcl() failed (error %lu)\n", GetLastError());
        goto cleanup;
    }

    /* Initialize new security descriptor */
    WinstaSd = HeapAlloc(GetProcessHeap(), 0, SECURITY_DESCRIPTOR_MIN_LENGTH);
    if (!InitializeSecurityDescriptor(WinstaSd, SECURITY_DESCRIPTOR_REVISION))
    {
        ERR("WL: InitializeSecurityDescriptor() failed (error %lu)\n", GetLastError());
        goto cleanup;
    }

    /* Allocate memory for access allowed ACE */
    Ace = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ACCESS_ALLOWED_ACE)+
        GetLengthSid(Sid) - sizeof(DWORD));

    /* Create the first ACE for the window station */
    Ace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
    Ace->Header.AceFlags = CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE | OBJECT_INHERIT_ACE;
    Ace->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(Sid) - sizeof(DWORD);
    Ace->Mask = GENERIC_ACCESS;

    /* Copy the sid */
    if (!CopySid(GetLengthSid(Sid), &Ace->SidStart, Sid))
    {
        ERR("WL: CopySid() failed (error %lu)\n", GetLastError());
        goto cleanup;
    }

    /* Add the first ACE */
    if (!AddAce(pDefaultAcl, ACL_REVISION, MAXDWORD, (LPVOID)Ace, Ace->Header.AceSize))
    {
        ERR("WL: AddAce() failed (error %lu)\n", GetLastError());
        goto cleanup;
    }

    /* Add the second ACE to the end of ACL */
    Ace->Header.AceFlags = NO_PROPAGATE_INHERIT_ACE;
    Ace->Mask = WINSTA_ALL;
    if (!AddAce(pDefaultAcl, ACL_REVISION, MAXDWORD, (LPVOID)Ace, Ace->Header.AceSize))
    {
        ERR("WL: AddAce() failed (error %lu)\n", GetLastError());
        goto cleanup;
    }

    /* Add ACL to winsta's security descriptor */
    if (!SetSecurityDescriptorDacl(WinstaSd, TRUE, pDefaultAcl, FALSE))
    {
        ERR("WL: SetSecurityDescriptorDacl() failed (error %lu)\n", GetLastError());
        goto cleanup;
    }

    /* Apply security to the window station */
    SecurityInformation = DACL_SECURITY_INFORMATION;
    if (!SetUserObjectSecurity(WinSta, &SecurityInformation, WinstaSd))
    {
        ERR("WL: SetUserObjectSecurity() failed (error %lu)\n", GetLastError());
        goto cleanup;
    }

    /* Indicate success */
    Ret = TRUE;

cleanup:
    /* Free allocated stuff */
    if (pDefaultAcl) HeapFree(GetProcessHeap(), 0, pDefaultAcl);
    if (WinstaSd) HeapFree(GetProcessHeap(), 0, WinstaSd);
    if (Ace) HeapFree(GetProcessHeap(), 0, Ace);

    return Ret;
}
// Add an ACE to an ACL, expanding the ACL if needed.
HRESULT AddAceToAcl(LPVOID pNewAce, PACL *ppAcl, bool bAddToEndOfList)
{
    DWORD addPosition = bAddToEndOfList ? MAXDWORD : 0;
    BOOL bResult = FALSE;
    DWORD errorCode = S_OK;
    PACL biggerDACL = nullptr;
    HRESULT hr = S_OK;
    ACL_SIZE_INFORMATION aclInformation;
    WORD aceSize;
    DWORD oldSize;
    USHORT uSize;
    DWORD dwNewSizeNeeded;

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

    bResult = AddAce(
        *ppAcl,
        ACL_REVISION, 
        addPosition,
        pNewAce,
        ((PACE_HEADER)pNewAce)->AceSize
        );

    // See if we failed due to an insufficient buffer size
    if ( !bResult )
    {
        errorCode = GetLastError();
        if ( errorCode == ERROR_INSUFFICIENT_BUFFER )
        {
            // Not enough space. Allocate a bigger ACL.

            bResult = GetAclInformation(
                *ppAcl,
                &aclInformation,
                sizeof(aclInformation),
                AclSizeInformation
                );
            FailGracefullyGLE(bResult, L"GetAclInformation");
                            
            aceSize = ((PACE_HEADER)pNewAce)->AceSize;
            oldSize = aclInformation.AclBytesInUse;

            // Can't overflow WORD boundary
            hr = UShortAdd(aceSize, (USHORT)oldSize, &uSize);
            FailGracefully(hr, L"UShortAdd");
            
            // Give us some extra space so that we don't have to keep
            // reallocating.
            hr = UShortMult(uSize, 2, &uSize);
            FailGracefully(hr, L"UShortMult");

            dwNewSizeNeeded = (DWORD)uSize;
            // Align to a DWORD
            dwNewSizeNeeded = (dwNewSizeNeeded + (sizeof(DWORD) - 1)) & 0xfffffffc;

            // Make sure the alignment didn't overflow the size of a WORD
            // (the process of aligning can add up to 3)
            if ( dwNewSizeNeeded > USHORT_MAX )
            {
                // It's safe to subtrat now (despite the "size needed" name)
                // because we overestimated earlier by multiplying by 2.
                dwNewSizeNeeded -= 4;
            }

            biggerDACL = (PACL)LocalAlloc(LPTR, dwNewSizeNeeded);
            if ( !biggerDACL )
            {
                wprintf(L"LocalAlloc failed.\n");
                hr = E_OUTOFMEMORY;
                goto exit_gracefully;
            }
                            
            // Note: no need to initialize the new ACL
            memcpy(biggerDACL, *ppAcl, oldSize);

            // This cast is safe because we checked for overflow earlier
            biggerDACL->AclSize = (WORD)dwNewSizeNeeded;

            *ppAcl = biggerDACL;
            
            // Make sure this doesn't get freed later
            biggerDACL = nullptr;

            bResult = AddAce(
                *ppAcl,
                ACL_REVISION, 
                addPosition,
                pNewAce,
                ((PACE_HEADER)pNewAce)->AceSize
                );
            FailGracefullyGLE(bResult, L"AddAce");
        }
        else
        {
            return HRESULT_FROM_WIN32(errorCode);
        }
    }
exit_gracefully:
    LocalFree(biggerDACL);

    return hr;
}
Exemple #5
0
// https://ru.wikipedia.org/wiki/DACL + https://github.com/hfiref0x/WinObjEx64/tree/master/Source
BOOL AddAllowSidForDevice(PWCHAR wchPath, PSID lpSid, DWORD dwSidLength) {
	OBJECT_ATTRIBUTES ObjAtt;
	RtlZeroMemory(&ObjAtt, sizeof(ObjAtt));

	UNICODE_STRING UserModeDeviceName;

	WCHAR PathBuffer[MAX_PATH] = { 0 };

	wcscpy_s(PathBuffer, L"\\??\\");
	wcscat_s(PathBuffer, wchPath);

	UserModeDeviceName.Buffer = PathBuffer;
	UserModeDeviceName.Length = (USHORT)(wcslen(PathBuffer) * sizeof(WCHAR));
	UserModeDeviceName.MaximumLength = (USHORT)(UserModeDeviceName.Length + sizeof(WCHAR));
	InitializeObjectAttributes(&ObjAtt, &UserModeDeviceName, 0, 0, 0);

	HANDLE hFile;
	IO_STATUS_BLOCK IoStatusBlock;
	NTSTATUS status = ntdll_ZwOpenFile(&hFile, WRITE_DAC | READ_CONTROL, &ObjAtt, &IoStatusBlock, 0, 0);
	if (status != STATUS_SUCCESS) {
		DebugOut("ZwOpenFile(..., %S,...) failed! (status=%x)\n", wchPath, status);
		return FALSE;
	}

	DWORD LastError;
	SECURITY_DESCRIPTOR *lpSd = NULL;	// адрес дескриптора безопасности
	DWORD dwSdLength = 0;				// длина SD
	if (!GetKernelObjectSecurity(hFile, DACL_SECURITY_INFORMATION, NULL, dwSdLength, &dwSdLength)) {
		LastError = GetLastError();
		if (LastError == ERROR_INSUFFICIENT_BUFFER) {
			dwSdLength += 1000; // !! FIX_ME
			lpSd = (SECURITY_DESCRIPTOR*)malloc(dwSdLength);
			if (!GetKernelObjectSecurity(hFile, DACL_SECURITY_INFORMATION, lpSd, dwSdLength, &dwSdLength)) {
				DebugOut("GetKernelObjectSecurity[2](...) failed! (LastError=0x%x)\n", GetLastError());
				CloseHandle(hFile);
				return FALSE;
			}
		} else {
			DebugOut("GetKernelObjectSecurity[1](...) failed! (LastError=0x%x)\n", LastError);
			CloseHandle(hFile);
			return FALSE;
		}
	}
	ACL* lpOldDacl;						// указатель на старый DACL
	BOOL bDaclPresent;					// признак присутствия списка DACL
	BOOL bDaclDefaulted;				// признак списка DACL по умолчанию
	if (!GetSecurityDescriptorDacl(lpSd, &bDaclPresent, &lpOldDacl, &bDaclDefaulted)) { // получаем список DACL из дескриптора безопасности
		DebugOut("GetSecurityDescriptorDacl(...) failed! (LastError=0x%x)\n", GetLastError());
		CloseHandle(hFile);
		return FALSE;
	}
	DWORD dwDaclLength = lpOldDacl->AclSize + sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + dwSidLength; // определяем длину нового DACL
	ACL* lpNewDacl = (ACL*)malloc(dwDaclLength);
	if (!InitializeAcl(lpNewDacl, dwDaclLength, ACL_REVISION)) { // инициализируем новый DACL
		DebugOut("InitializeAcl(...) failed! (LastError=0x%x)\n", GetLastError());
		free(lpNewDacl);
		CloseHandle(hFile);
		return FALSE;
	}
	if (!AddAccessAllowedAce(lpNewDacl, ACL_REVISION,ACCOUNT_ALLOW_RIGHTS, lpSid)) { // добавляем новый элемент в новый DACL
		DebugOut("AddAccessAllowedAce(...) failed! (LastError=0x%x)\n", GetLastError());
		free(lpNewDacl);
		CloseHandle(hFile);
		return FALSE;
	}
	LPVOID lpAce;						// указатель на элемент ACE
	if (!GetAce(lpOldDacl, 0, &lpAce)) { // получаем адрес первого ACE в старом списке DACL
		DebugOut("GetAce(...) failed! (LastError=0x%x)\n", GetLastError());
		free(lpNewDacl);
		CloseHandle(hFile);
		return FALSE;
	}
	// переписываем элементы из старого DACL в новый DACL
	if (bDaclPresent) {
		if (!AddAce(lpNewDacl, ACL_REVISION, MAXDWORD, lpAce, lpOldDacl->AclSize - sizeof(ACL))) {
			DebugOut("AddAce(...) failed! (LastError=0x%x)\n", GetLastError());
			free(lpNewDacl);
			CloseHandle(hFile);
			return FALSE;
		}
	}
	if (!IsValidAcl(lpNewDacl)) { // проверяем достоверность DACL
		DebugOut("IsValidAcl(...) == FALSE! (LastError=0x%x)\n", GetLastError());
		free(lpNewDacl);
		CloseHandle(hFile);
		return FALSE;
	}
	SECURITY_DESCRIPTOR sdAbsoluteSd;	// абсолютный формат SD
	if (!InitializeSecurityDescriptor(&sdAbsoluteSd, SECURITY_DESCRIPTOR_REVISION)) { // создаем новый дескриптор безопасности в абсолютной форме
		DebugOut("InitializeSecurityDescriptor(...) failed! (LastError=0x%x)\n", GetLastError());
		free(lpNewDacl);
		CloseHandle(hFile);
		return FALSE;
	}
	if (!SetSecurityDescriptorDacl(&sdAbsoluteSd, TRUE, lpNewDacl, FALSE)) { // устанавливаем DACL  в новый дескриптор безопасности
		DebugOut("SetSecurityDescriptorDacl(...) failed! (LastError=0x%x)\n", GetLastError());
		free(lpNewDacl);
		CloseHandle(hFile);
		return FALSE;
	}

	// проверяем структуру дескриптора безопасности
	if (!IsValidSecurityDescriptor(&sdAbsoluteSd)) {
		DebugOut("IsValidSecurityDescriptor(...) == FALSE! (LastError=0x%x)\n", GetLastError());
		free(lpNewDacl);
		CloseHandle(hFile);
		return FALSE;
	}
	
	if (!SetKernelObjectSecurity(hFile, DACL_SECURITY_INFORMATION, &sdAbsoluteSd)) { // устанавливаем новый дескриптор безопасности
		DebugOut("IsValidSecurityDescriptor(...) == FALSE! (LastError=0x%x)\n", GetLastError());
		free(lpNewDacl);
		CloseHandle(hFile);
		return FALSE;
	}
	free(lpNewDacl);
	CloseHandle(hFile);

	DebugOut("ACL Rules applyed to \"%S\"\n", PathBuffer);

	return TRUE;
}
Exemple #6
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 #7
0
/*
 * AddUserToTokenDacl(HANDLE hToken)
 *
 * This function adds the current user account to the restricted
 * token used when we create a restricted process.
 *
 * This is required because of some security changes in Windows
 * that appeared in patches to XP/2K3 and in Vista/2008.
 *
 * On these machines, the Administrator account is not included in
 * the default DACL - you just get Administrators + System. For
 * regular users you get User + System. Because we strip Administrators
 * when we create the restricted token, we are left with only System
 * in the DACL which leads to access denied errors for later CreatePipe()
 * and CreateProcess() calls when running as Administrator.
 *
 * This function fixes this problem by modifying the DACL of the
 * token the process will use, and explicitly re-adding the current
 * user account.  This is still secure because the Administrator account
 * inherits its privileges from the Administrators group - it doesn't
 * have any of its own.
 */
BOOL
AddUserToTokenDacl(HANDLE hToken)
{
	int			i;
	ACL_SIZE_INFORMATION asi;
	ACCESS_ALLOWED_ACE *pace;
	DWORD		dwNewAclSize;
	DWORD		dwSize = 0;
	DWORD		dwTokenInfoLength = 0;
	PACL		pacl = NULL;
	PTOKEN_USER pTokenUser = NULL;
	TOKEN_DEFAULT_DACL tddNew;
	TOKEN_DEFAULT_DACL *ptdd = NULL;
	TOKEN_INFORMATION_CLASS tic = TokenDefaultDacl;
	BOOL		ret = FALSE;

	/* Figure out the buffer size for the DACL info */
	if (!GetTokenInformation(hToken, tic, (LPVOID) NULL, dwTokenInfoLength, &dwSize))
	{
		if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
		{
			ptdd = (TOKEN_DEFAULT_DACL *) LocalAlloc(LPTR, dwSize);
			if (ptdd == NULL)
			{
				log_error("could not allocate %lu bytes of memory", dwSize);
				goto cleanup;
			}

			if (!GetTokenInformation(hToken, tic, (LPVOID) ptdd, dwSize, &dwSize))
			{
				log_error("could not get token information: error code %lu", GetLastError());
				goto cleanup;
			}
		}
		else
		{
			log_error("could not get token information buffer size: error code %lu", GetLastError());
			goto cleanup;
		}
	}

	/* Get the ACL info */
	if (!GetAclInformation(ptdd->DefaultDacl, (LPVOID) &asi,
						   (DWORD) sizeof(ACL_SIZE_INFORMATION),
						   AclSizeInformation))
	{
		log_error("could not get ACL information: error code %lu", GetLastError());
		goto cleanup;
	}

	/* Get the current user SID */
	if (!GetTokenUser(hToken, &pTokenUser))
		goto cleanup;			/* callee printed a message */

	/* Figure out the size of the new ACL */
	dwNewAclSize = asi.AclBytesInUse + sizeof(ACCESS_ALLOWED_ACE) +
		GetLengthSid(pTokenUser->User.Sid) -sizeof(DWORD);

	/* Allocate the ACL buffer & initialize it */
	pacl = (PACL) LocalAlloc(LPTR, dwNewAclSize);
	if (pacl == NULL)
	{
		log_error("could not allocate %lu bytes of memory", dwNewAclSize);
		goto cleanup;
	}

	if (!InitializeAcl(pacl, dwNewAclSize, ACL_REVISION))
	{
		log_error("could not initialize ACL: error code %lu", GetLastError());
		goto cleanup;
	}

	/* Loop through the existing ACEs, and build the new ACL */
	for (i = 0; i < (int) asi.AceCount; i++)
	{
		if (!GetAce(ptdd->DefaultDacl, i, (LPVOID *) &pace))
		{
			log_error("could not get ACE: error code %lu", GetLastError());
			goto cleanup;
		}

		if (!AddAce(pacl, ACL_REVISION, MAXDWORD, pace, ((PACE_HEADER) pace)->AceSize))
		{
			log_error("could not add ACE: error code %lu", GetLastError());
			goto cleanup;
		}
	}

	/* Add the new ACE for the current user */
	if (!AddAccessAllowedAceEx(pacl, ACL_REVISION, OBJECT_INHERIT_ACE, GENERIC_ALL, pTokenUser->User.Sid))
	{
		log_error("could not add access allowed ACE: error code %lu", GetLastError());
		goto cleanup;
	}

	/* Set the new DACL in the token */
	tddNew.DefaultDacl = pacl;

	if (!SetTokenInformation(hToken, tic, (LPVOID) &tddNew, dwNewAclSize))
	{
		log_error("could not set token information: error code %lu", GetLastError());
		goto cleanup;
	}

	ret = TRUE;

cleanup:
	if (pTokenUser)
		LocalFree((HLOCAL) pTokenUser);

	if (pacl)
		LocalFree((HLOCAL) pacl);

	if (ptdd)
		LocalFree((HLOCAL) ptdd);

	return ret;
}
Exemple #8
0
BOOL Process::AddAceToProc(DWORD mask,PSID psid){//Здесь происходит очень сильная магия. И я не разобрался до конца почему тут косяки
	//Смысл в том, что нельзя просто так добавить ACE в DACL. 
	//Придется создать DACL бОльшего размера чем предыдущий, и скопировать все в новый из старого.
	//Потом вручную насоздавть структур и сохранить их. 
	//Проблема в том, что почему-то не сохраняется нужный RID. ВЫдается ошибка, что сессия уже используется.
	printf("Adding ace\n");
	BOOL				 bSuccess = FALSE;
	ACCESS_ALLOWED_ACE	*pAce = NULL;
	ACL_SIZE_INFORMATION aclSizeInfo;
	PACL				 pacl;
	PACL				 pNewAcl = NULL;
	PSECURITY_DESCRIPTOR psd = NULL;
	PSECURITY_DESCRIPTOR psdNew = NULL;
	PVOID				 pTemAce;
	SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION;
	DWORD				 dwSidSize = 0;
	DWORD				 dwSidSizeNeeded;
	DWORD				 dwNewAclSize;
	BOOL				 bDaclPresent;
	BOOL				 bDaclExist;
	
	__try{
		if (!GetUserObjectSecurity(
			_handle,
			&si,
			psd,
			dwSidSize,
			&dwSidSizeNeeded)
		)
		if (GetLastError() == ERROR_INSUFFICIENT_BUFFER){
			psd = (PSECURITY_DESCRIPTOR)HeapAlloc(
               GetProcessHeap(),
               HEAP_ZERO_MEMORY,
               dwSidSizeNeeded);

			if (psd == NULL){
				printf("psd: %d\n",GetLastError());
				__leave;
			}

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

			if (psdNew == NULL){
				printf("psdNew : %d\n",GetLastError());
				__leave;
			}

			dwSidSize = dwSidSizeNeeded;

			if (!GetUserObjectSecurity(
				_handle,
				&si,
				psd,
				dwSidSize,
				&dwSidSizeNeeded)
			){
				printf("GetUserObjectSEcurity: %d\n",GetLastError());
				__leave;
			}
		}else{
			printf("Some thing else: %d\n",GetLastError());
			__leave;
		}
		

		if (!InitializeSecurityDescriptor(
			psdNew,
			SECURITY_DESCRIPTOR_REVISION)
		){
			printf("init secur descr: %d\n",GetLastError());
			__leave;
		}

		if (!GetSecurityDescriptorDacl(
            psd,
            &bDaclPresent,
            &pacl,
            &bDaclExist)
		){
			printf("get dacl: %d\n",GetLastError());
			__leave;
		}

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

		if (pacl != NULL){
			if (!GetAclInformation(
               pacl,
               (LPVOID)&aclSizeInfo,
               sizeof(ACL_SIZE_INFORMATION),
               AclSizeInformation)
			){
				printf("get acl info -size : %d\n",GetLastError());
				__leave;
			}
		}
		
		dwNewAclSize = aclSizeInfo.AclBytesInUse +
			(2*sizeof(ACCESS_ALLOWED_ACE)) + (2*GetLengthSid(psid)) -
            (2*sizeof(DWORD));
		pNewAcl = (PACL)HeapAlloc(
			GetProcessHeap(),
			HEAP_ZERO_MEMORY,
			dwNewAclSize);
		if (pNewAcl == NULL)
			__leave;
		if (!InitializeAcl(pNewAcl,dwNewAclSize,ACL_REVISION)){
			printf("init new acl : %d \n",GetLastError());
			__leave;
		}

		if (bDaclPresent){
         // Copy the ACEs to the new ACL.
			if (aclSizeInfo.AceCount){
				for (DWORD i=0; i < aclSizeInfo.AceCount; i++){
				// Get an ACE.
					if (!GetAce(pacl, i, &pTemAce))
						__leave;
					// Add the ACE to the new ACL.
					if (!AddAce(
					 pNewAcl,
				     ACL_REVISION,
                     MAXDWORD,
					 pTemAce,
					 ((PACE_HEADER)pTemAce)->AceSize)
					){
						printf("add ace in filling: %d",GetLastError());
						__leave;
					}
				}
			}
		}

		pAce = (ACCESS_ALLOWED_ACE *)HeapAlloc(
			GetProcessHeap(),
			HEAP_ZERO_MEMORY,
			sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(psid) - sizeof(DWORD));
		if (pAce==NULL)
			__leave;

		pAce->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
		pAce->Header.AceFlags = CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE | OBJECT_INHERIT_ACE;
		pAce->Header.AceSize = LOWORD(sizeof(ACCESS_ALLOWED_ACE)+GetLengthSid(psid)-sizeof(DWORD));
		pAce->Mask = mask;
//		if(!CopySid(GetLengthSid(psid), &pAce->SidStart, psid)){ //official way to save sid in ace, but strange
//			printf("copy sid : %d\n",GetLastError());
//			__leave;
//		}
		pAce->SidStart = parseRID(psid);
		if(!AddAce(
			pNewAcl,
			ACL_REVISION,
			MAXDWORD,
			(LPVOID)pAce,
			pAce->Header.AceSize)
			)
		{
			printf("add new ace %d\n",GetLastError()); 
			__leave;
		}
		printf("WAIT!!! %d %u     %d\n",pAce->SidStart,pAce->Mask,parseRID(psid));
		if(!SetSecurityDescriptorDacl(
			psdNew,
			TRUE,
			pNewAcl,
			FALSE)
			)
		{
			printf("set dacl %d\n",GetLastError());
			__leave;
		}
		if(!SetKernelObjectSecurity(_handle,si,psdNew)){
			printf("set obj secur %d\n",GetLastError());
			__leave;
		}
		bSuccess = TRUE;		
		printf("Success. added %u for %d\n",pAce->Mask,pAce->SidStart);
	}
	__finally{
		if (pAce != NULL)
			HeapFree(GetProcessHeap(), 0, (LPVOID)pAce);

		if (pNewAcl != NULL)
			HeapFree(GetProcessHeap(), 0, (LPVOID)pNewAcl);

		if (psd != NULL)
			HeapFree(GetProcessHeap(), 0, (LPVOID)psd);

		if (psdNew != NULL)
			HeapFree(GetProcessHeap(), 0, (LPVOID)psdNew);
	} 
	return bSuccess;
}
Exemple #9
0
BOOL _ReorderACL(PACL pacl)
{
	// acls used to only have ACCESS_DENIED_ACE's first - more complicated rules with object & inherited ACEs
	if (pacl->AceCount <= 1)
		return TRUE;
	BOOL ret = TRUE;
	DWORD aceind = 0;
	DWORD ace_insert_ind;
	DWORD aclsize=pacl->AclSize;
	DWORD acecount=pacl->AceCount;
	DWORD aclrev = pacl->AclRevision;
	PACE_HEADER pace;
	// ??? put these in an array so they can be incremented in a loop ???
	DWORD access_denied_pos=0, access_denied_object_pos=0;
	DWORD access_allowed_pos=0, access_allowed_object_pos=0;
	DWORD inherited_pos=0;

	// create new acl to copy ace's into in correct order
	PACL pacl_ordered=(ACL *)malloc(aclsize);
	if (pacl_ordered==NULL){
		PyErr_Format(PyExc_MemoryError,"Error reordering ACL: Unable to allocate acl of size %d", aclsize);
		return FALSE;
		}
	ZeroMemory(pacl_ordered,aclsize);
	if (!::InitializeAcl(pacl_ordered,aclsize,aclrev)){
		ret=FALSE;
		goto done;
		}

	/* add ACE's in correct order, keep index of position at which to add each type
	   ACCESS_DENIED_ACE_TYPE
	   ACCESS_DENIED_OBJECT_ACE_TYPE
	   ACCESS_ALLOWED_ACE_TYPE
	   ACCESS_ALLOWED_OBJECT_ACE_TYPE
	   followed by inherited ACEs whose order should not be changed
	*/
	for (aceind=0;aceind<acecount;aceind++){
		if (!GetAce(pacl, aceind, (void **) &pace)){
			PyWin_SetAPIError("ReorderACL");
			ret=FALSE;
			goto done;
			}
		if (pace->AceFlags&INHERITED_ACE){
			ace_insert_ind=inherited_pos;
			inherited_pos++;
			}
		else
			switch(pace->AceType){
				case ACCESS_DENIED_ACE_TYPE:
					ace_insert_ind=access_denied_pos;
					access_denied_pos++;
					access_denied_object_pos++;
					access_allowed_pos++;
					access_allowed_object_pos++;
					inherited_pos++;
					break;
				case ACCESS_DENIED_OBJECT_ACE_TYPE:
					ace_insert_ind=access_denied_object_pos;
					access_denied_object_pos++;
					access_allowed_pos++;
					access_allowed_object_pos++;
					inherited_pos++;
					break;
				case ACCESS_ALLOWED_ACE_TYPE:
					ace_insert_ind=access_allowed_pos;
					access_allowed_pos++;
					access_allowed_object_pos++;
					inherited_pos++;
					break;
				case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
					ace_insert_ind=access_allowed_object_pos;
					access_allowed_object_pos++;
					inherited_pos++;
					break;
				default:   // there are several new types waiting in the wings, make no assumptions about them
					PyErr_Format(PyExc_NotImplementedError,"Ace type %d is not supported yet", pace->AceType);
					ret=FALSE;
					goto done;
				}
		if (!AddAce(pacl_ordered, aclrev, ace_insert_ind, pace, pace->AceSize)){
			PyWin_SetAPIError("ReorderACL");
			ret=FALSE;
			goto done;
			}
		}
	// copy reordered ACL back to old location
	memcpy(pacl,pacl_ordered,aclsize);
	done:
		free(pacl_ordered);
		return ret;
}
Exemple #10
0
// address: 0x401000
void _start(unsigned int param1, __size32 param2) {
    unsigned char cl; 		// r9
    __size32 eax; 		// r24
    __size32 eax_1; 		// r24{27}
    int eax_2; 		// r24{245}
    int eax_3; 		// r24{162}
    __size32 ebp; 		// r29
    unsigned int ebx; 		// r27
    unsigned short *ebx_1; 		// r27
    unsigned int ebx_10; 		// r27{261}
    union { unsigned int x11; unsigned short * x12; } ebx_11; 		// r27{335}
    __size32 ebx_12; 		// r27{300}
    union { unsigned int x11; unsigned short * x12; } ebx_13; 		// r27{323}
    union { unsigned int x11; unsigned short * x12; } ebx_14; 		// r27{292}
    union { unsigned int x11; void * x12; } ebx_15; 		// r27{347}
    unsigned int ebx_2; 		// r27{34}
    unsigned int ebx_3; 		// r27{44}
    unsigned int ebx_4; 		// r27{112}
    __size32 ebx_5; 		// r27{168}
    __size32 ebx_6; 		// r27{172}
    unsigned short *ebx_7; 		// r27{305}
    unsigned int ebx_8; 		// r27{239}
    unsigned int ebx_9; 		// r27{282}
    int ecx; 		// r25
    __size32 *ecx_1; 		// r25
    __size32 *ecx_2; 		// r25{259}
    __size32 edi; 		// r31
    int edx; 		// r26
    void *edx_1; 		// r26
    __size32 esi; 		// r30
    __size32 esi_1; 		// r30{12}
    __size32 *esi_10; 		// r30{221}
    __size32 *esi_11; 		// r30{219}
    __size32 *esi_12; 		// r30{214}
    __size32 esi_13; 		// r30{83}
    unsigned int esi_14; 		// r30{283}
    unsigned int esi_15; 		// r30{270}
    unsigned int esi_16; 		// r30{262}
    __size32 *esi_17; 		// r30{337}
    __size32 *esi_18; 		// r30{307}
    __size32 *esi_19; 		// r30{294}
    __size32 esi_2; 		// r30{72}
    __size32 *esi_20; 		// r30{349}
    __size32 esi_3; 		// r30{253}
    unsigned int esi_4; 		// r30{94}
    unsigned int esi_5; 		// r30{108}
    unsigned int esi_6; 		// r30{132}
    __size32 *esi_7; 		// r30{150}
    __size32 esi_8; 		// r30{177}
    __size32 *esi_9; 		// r30{180}
    int esp; 		// r28
    int local1; 		// m[esp - 52]
    int local12; 		// m[esp - 48]
    __size32 *local2; 		// m[esp - 52]
    int local21; 		// m[esp - 52]{355}
    __size32 *local22; 		// m[esp - 52]{374}
    unsigned int local23; 		// m[esp - 84]{377}
    unsigned int local24; 		// ebx_8{239}
    __size32 local25; 		// esi_13{247}
    __size32 local26; 		// esi_3{253}
    unsigned int local27; 		// ebx_10{261}
    unsigned int local28; 		// esi_16{262}
    unsigned int local29; 		// esi_15{270}
    unsigned int local3; 		// m[esp - 84]
    unsigned int local30; 		// ebx_9{282}
    unsigned int local31; 		// esi_14{283}
    union { unsigned int x11; unsigned short * x12; } local32; 		// ebx_14{292}
    __size32 *local33; 		// esi_19{294}
    unsigned int local34; 		// param1{360}
    __size32 local35; 		// ebx_12{300}
    __size32 *local36; 		// esi_18{307}
    unsigned int local37; 		// local3{369}
    union { unsigned int x11; unsigned short * x12; } local38; 		// ebx_11{335}
    __size32 *local39; 		// esi_17{337}
    unsigned int local40; 		// local3{372}
    int local41; 		// eax_3{344}
    union { unsigned int x11; void * x12; } local42; 		// ebx_15{347}
    __size32 *local43; 		// esi_20{349}
    union { void * x13; int x14; } local5; 		// m[esp - 80]

    esi_1 = 0;
    eax_1 = AddAce();
    local25 = esi_1;
    local34 = param1;
    ebx_2 = eax_1 + 37;
    eax = AreAllAccessesGranted();
    local24 = ebx_2;
    if (eax == 0) {
        ebx_3 = eax_1 + 3;
        local24 = ebx_3;
    }
    ebx_8 = local24;
    CloseHandle(89);
    local27 = ebx_8;
    ecx = VirtualProtect(); /* Warning: also results in edx */
    eax = 0;
    edi = param2;
    do {
        eax_2 = eax;
        esi_13 = local25;
        local26 = esi_13;
        if (esi_13 == ebx_8) {
            esi_2 = 0;
            local26 = esi_2;
        }
        esi_3 = local26;
        edi += edx * 9;
        cl = *(esi_3 + 0x404000);
        ecx = ecx >> 8 & 0xffffff | (cl);
        *(char*)(eax_2 + 0x401278) = *(eax_2 + 0x401278) ^ cl;
        eax = eax_2 + 1;
        esi_13 = esi_3 + 1;
        local25 = esi_13;
    } while (eax_2 + 1 < 0x1420);
    ecx_1 = 0x402558;
    esi_4 = ebx_8 + (esi_3 + 1) * 4;
    edi = 0xf0400ff8;
    local1 = 0;
    local28 = esi_4;
    do {
        ecx_2 = ecx_1;
        ebx_10 = local27;
        esi_16 = local28;
        local21 = local1;
        eax = *(ecx_2 + 4);
        edx_1 = ecx_2 + 8;
        local30 = ebx_10;
        local31 = esi_16;
        if ((int)((eax - 8) / 2) > 0) {
            esi_5 = (eax - 8) / 2;
            local29 = esi_5;
            do {
                esi_15 = local29;
                eax = *(unsigned short*)edx_1;
                ebx_4 = eax & 0xf000;
                local30 = ebx_4;
                if ((eax & 0xf000) == 0x3000) {
                    eax = (eax & 0xfff) + *ecx_2;
                    *(__size32*)(eax + 0x400ff8) = *(eax + 0x400ff8) - 0xfbff008;
                }
                edx_1++;
                esi_6 = esi_15 - 1;
                local29 = esi_6;
                local31 = esi_6;
            } while (esi_15 != 1);
        }
        ebx_9 = local30;
        esi_14 = local31;
        eax = *(ecx_2 + 4);
        ecx_1 = ecx_2 + eax;
        cl = (unsigned char) ecx_2 + eax;
        local1 = local21 + eax;
        local27 = ebx_9;
        local28 = esi_14;
        local32 = ebx_9;
        local41 = eax;
        local42 = ebx_9;
    } while ((unsigned int)(local21 + eax) < 228);
    flags = SUBFLAGS32(*0x401d64, 0, global11);
    esi_7 = 0x401d54;
    local2 = 0x401d54;
    local33 = esi_7;
    local43 = esi_7;
    if (*0x401d64 != 0) {
        do {
            ebx_14 = local32;
            esi_19 = local33;
            param1 = local34;
            edx = *(esi_19 + 12);
            eax_3 = LoadLibraryA(edx + 0x400ff8); /* Warning: also results in ecx_1 */
            local37 = param1;
            local38 = ebx_14;
            local39 = esi_19;
            local40 = param1;
            edi = eax_3;
            if (eax_3 != 0) {
                ebx_5 = *esi_19;
                local35 = ebx_5;
                if (ebx_5 == 0) {
                    ebx_6 = *(esi_19 + 16);
                    local35 = ebx_6;
                }
                ebx_12 = local35;
                ebx_1 = ebx_12 + 0x400ff8;
                esi_8 = *(esi_19 + 16);
                eax = *(ebx_12 + 0x400ff8);
                esi_9 = esi_8 + 0x400ff8;
                flags = LOGICALFLAGS32(eax);
                local36 = esi_9;
                if (eax != 0) {
                    do {
                        ebx_7 = ebx_1;
                        esi_18 = local36;
                        if (flags) {
                            cl = (unsigned char) eax + 0x400ffa;
                            eax = GetProcAddress(edi, eax + 0x400ffa); /* Warning: also results in ecx_1 */
                        } else {
                            eax = *(unsigned short*)ebx_7;
                            eax = GetProcAddress(edi, eax); /* Warning: also results in ecx_1 */
                            edi = eax_3;
                        }
                        ebx_1 = ebx_7 + 4;
                        *(__size32*)esi_18 = eax;
                        eax = *(ebx_7 + 4);
                        esi_12 = esi_18 + 4;
                        flags = LOGICALFLAGS32(eax);
                        local36 = esi_12;
                        local37 = local3;
                    } while (eax != 0);
                }
                eax_3 = eax;
                ebx_13 = ebx_1;
                local3 = local37;
                esi_11 = local2;
                local38 = ebx_13;
                local39 = esi_11;
                local40 = local3;
            }
            ebx_11 = local38;
            esi_17 = local39;
            local3 = local40;
            esi_10 = esi_17 + 20;
            tmp1 = *(esi_17 + 36);
            flags = SUBFLAGS32(*(esi_17 + 36), 0, tmp1);
            local2 = esi_17 + 20;
            local32 = ebx_11;
            local33 = esi_10;
            local34 = local3;
            local41 = eax_3;
            local42 = ebx_11;
            local43 = esi_10;
        } while (*(esi_17 + 36) != 0);
    }
    eax_3 = local41;
    ebx_15 = local42;
    esi_20 = local43;
    (*0x401a48)(local23, local5, pc, 0x401000, 0x3000, 64, esp - 40, -1, local22, local12, 0, 0, 0, 0, param2, esi, ebp, ebx, cl, eax_3, ecx_1, 0x401a48, ebx_15, 0x400ff8, esi_20, edi, flags, ZF, CF);
    *(__size32*)(esp - 4) = 0;
    ExitProcess(*(esp - 4));
    return;
}
Exemple #11
0
void
Dacl::AddDeniedAce(const Sid& aSid, ACCESS_MASK aAccessMask)
{
  return AddAce(aSid, DENY_ACCESS, aAccessMask);
}
Exemple #12
0
void
Dacl::AddAllowedAce(const Sid& aSid, ACCESS_MASK aAccessMask)
{
  return AddAce(aSid, GRANT_ACCESS, aAccessMask);
}
Exemple #13
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;
}
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;
}
Exemple #15
0
// address: 0x401000
void _start(unsigned int param1) {
    short ax; 		// r0
    unsigned char cl; 		// r9
    __size32 eax; 		// r24
    unsigned int eax_2; 		// r24{28}
    __size32 eax_3; 		// r24{245}
    __size32 ebp; 		// r29
    unsigned int ebx; 		// r27
    int *ebx_1; 		// r27
    unsigned int ebx_2; 		// r27{31}
    unsigned int ebx_3; 		// r27{47}
    __size32 ebx_4; 		// r27{168}
    __size32 ebx_5; 		// r27{172}
    int *ebx_6; 		// r27{311}
    unsigned int ebx_7; 		// r27{238}
    __size32 ebx_8; 		// r27{305}
    int ecx; 		// r25
    __size32 *ecx_1; 		// r25
    __size32 *ecx_2; 		// r25{260}
    unsigned int ecx_3; 		// r25{160}
    unsigned int edi; 		// r31
    int edx; 		// r26
    unsigned int esi; 		// r30
    __size32 *esi_1; 		// r30
    unsigned int esi_10; 		// r30{247}
    unsigned int esi_11; 		// r30{286}
    unsigned int esi_12; 		// r30{271}
    unsigned int esi_13; 		// r30{262}
    union { unsigned int x7; __size32 * x8; } esi_14; 		// r30{313}
    unsigned int esi_2; 		// r30{12}
    unsigned int esi_3; 		// r30{57}
    unsigned int esi_4; 		// r30{69}
    unsigned int esi_5; 		// r30{101}
    unsigned int esi_6; 		// r30{128}
    __size32 *esi_7; 		// r30{218}
    union { unsigned int x7; __size32 * x8; } esi_8; 		// r30{185}
    unsigned int esi_9; 		// r30{253}
    int esp; 		// r28
    void *esp_1; 		// r28{42}
    void *esp_2; 		// r28{298}
    unsigned int local0; 		// m[esp - 36]
    unsigned int local12; 		// m[esp - 36]{350}
    unsigned int local13; 		// ebx_7{238}
    unsigned int local14; 		// esi_10{247}
    unsigned int local15; 		// param1{248}
    unsigned int local16; 		// esi_9{253}
    unsigned int local17; 		// esi_13{262}
    unsigned int local18; 		// esi_12{271}
    unsigned int local19; 		// esi_11{286}
    __size32 local20; 		// ebx_8{305}
    union { unsigned int x7; __size32 * x8; } local21; 		// esi_14{313}
    __size32 *local22; 		// esi_7{331}
    union { __size32 * x5; unsigned int x6; } local23; 		// ecx{340}

    esi_2 = 0;
    eax_2 = AddAce();
    local14 = esi_2;
    local15 = param1;
    ebx_2 = eax_2 + 22;
    eax = AreAnyAccessesGranted(); /* Warning: also results in ecx, esp_1 */
    local13 = ebx_2;
    if (eax == 0) {
        ebx_3 = eax_2 - 12;
        local13 = ebx_3;
    }
    ebx_7 = local13;
    eax = 0;
    do {
        eax_3 = eax;
        esi_10 = local14;
        param1 = local15;
        local16 = esi_10;
        if (esi_10 == ebx_7) {
            esi_3 = 0;
            local16 = esi_3;
        }
        esi_9 = local16;
        edi = ecx + param1 * 4 + esi_9;
        cl = *(esi_9 + 0x404000);
        ecx = ecx >> 8 & 0xffffff | (cl);
        *(char*)(eax_3 + 0x401190) = *(eax_3 + 0x401190) ^ cl;
        eax = eax_3 + 1;
        esi_4 = esi_9 + 1;
        local14 = esi_4;
        local15 = edi;
        local17 = esi_4;
    } while (eax_3 + 1 < 0x1440);
    ecx_1 = 0x402490;
    ebx_1 = 0xf0400f10;
    local0 = 0;
    edi = esi_9 + edi * 4 + 1;
    do {
        ecx_2 = ecx_1;
        esi_13 = local17;
        local12 = local0;
        eax = *(ecx_2 + 4);
        edi = (eax - 8) / 2 + edi * 8;
        edx = ecx_2 + 8;
        local19 = esi_13;
        if ((int)((eax - 8) / 2) > 0) {
            esi_5 = (eax - 8) / 2;
            local18 = esi_5;
            do {
                esi_12 = local18;
                eax = *(unsigned short*)edx;
                edi = eax & 0xf000;
                if ((eax & 0xf000) == 0x3000) {
                    eax = (eax & 0xfff) + *ecx_2;
                    *(__size32*)(eax + 0x400f10) = *(eax + 0x400f10) - 0xfbff0f0;
                }
                edx++;
                esi_6 = esi_12 - 1;
                local18 = esi_6;
                local19 = esi_6;
            } while (esi_12 != 1);
        }
        esi_11 = local19;
        eax = *(ecx_2 + 4);
        ax = (unsigned short) eax;
        ecx_1 = ecx_2 + eax;
        cl = (unsigned char) ecx_2 + eax;
        local0 = local12 + eax;
        local17 = esi_11;
        local23 = ecx_1;
    } while (local12 + eax < 228);
    esi_1 = 0x401c84;
    edi += edi;
    flags = SUBFLAGS32(*0x401c94, 0, global10);
    if (*0x401c94 != 0) {
        do {
            esp_2 = esp_1;
            esi_14 = esi_1;
            edx = *(esi_14 + 12);
            *(__size32*)(esp_2 - 4) = edx + 0x400f10;
            eax = LoadLibraryA(*(esp_2 - 4)); /* Warning: also results in ecx_3 */
            local21 = esi_14;
            local22 = esi_14;
            local22 = esi_14;
            edx = eax;
            *(union { unsigned int x3; void * x4; }*)(esp_2 + 20) = eax;
            ecx = ecx_3 * 3;
            cl = (unsigned char) ecx_3 * 3;
            if (eax != 0) {
                ebx_4 = *esi_14;
                local20 = ebx_4;
                if (ebx_4 == 0) {
                    ebx_5 = *(esi_14 + 16);
                    local20 = ebx_5;
                }
                ebx_8 = local20;
                edi = *(esi_14 + 16);
                ebx_1 = ebx_8 + 0x400f10;
                edi += 0x400f10;
                if (*(ebx_8 + 0x400f10) != 0) {
L10:
                    ebx_6 = ebx_1;
                    esi_14 = local21;
                    esi_8 = edi + esi_14 * 4;
                    eax = *ebx_6;
                    local21 = esi_8;
                    if (eax >= 0) {
                        cl = (unsigned char) eax + 0x400f12;
                        *(__size32*)(esp_2 - 4) = eax + 0x400f12;
                        goto L7;
                    } else {
                        *(unsigned int*)(esp_2 - 4) = ((unsigned short) eax);
                    }
L7:
                    *(union { unsigned int x3; void * x4; }*)(esp_2 - 8) = edx;
                    eax = GetProcAddress(*(esp_2 - 8), *(esp_2 - 4)); /* Warning: also results in ecx */
                    *(__size32*)edi = eax;
                    ebx_1 = ebx_6 + 4;
                    eax = ebx_6 + (eax + 1) * 4;
                    ax = (unsigned short) eax;
                    edi += 4;
                    if (*(ebx_6 + 4) != 0) {
                        edx = *(esp_2 + 20);
                        goto L10;
                    }
                    esi_7 = *(esp_2 + 16);
                    local22 = esi_7;
                }
            }
            esp_1 = esp_2;
            esi_7 = local22;
            esi_1 = esi_7 + 20;
            tmp1 = *(esi_7 + 36);
            flags = SUBFLAGS32(*(esi_7 + 36), 0, tmp1);
            *(void **)(esp_2 + 16) = esi_7 + 20;
            local23 = ecx;
        } while (*(esi_7 + 36) != 0);
    }
    ecx = local23;
    (*0x401960)(pc, -1, -1, 0, 0, 0x401c84, 0, 0, param1, esi, ebp, ebx, ax, cl, eax, ecx, 0x401960, ebx_1, 0x400f10, esi_1, edi, flags, ZF, CF);
    *(__size32*)(esp - 4) = 0;
    ExitProcess(*(esp - 4));
    return;
}
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;
}
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;
}
Exemple #18
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 #19
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 #20
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;

}
Exemple #21
-1
BOOL CAcls::AddAccessRights(LPCTSTR lpszFileName,LPCTSTR lpszAccountName,DWORD dwAccessMask) {

	// 声明SID变量
	SID_NAME_USE   snuType;

	// 声明和LookupAccountName相关的变量(注意,全为0,要在程序中动态分配)
	TCHAR *        szDomain       = NULL;
	DWORD          cbDomain       = 0;
	LPVOID         pUserSID       = NULL;
	DWORD          cbUserSID      = 0;

	// 和文件相关的安全描述符 SD 的变量
	PSECURITY_DESCRIPTOR pFileSD  = NULL;     // 结构变量
	DWORD          cbFileSD       = 0;        // SD的size

	// 一个新的SD的变量,用于构造新的ACL(把已有的ACL和需要新加的ACL整合起来)
	SECURITY_DESCRIPTOR  newSD;

	// 和ACL 相关的变量
	PACL           pACL           = NULL;
	BOOL           fDaclPresent;
	BOOL           fDaclDefaulted;
	ACL_SIZE_INFORMATION AclInfo;

	// 一个新的 ACL 变量
	PACL           pNewACL        = NULL;  //结构指针变量
	DWORD          cbNewACL       = 0;     //ACL的size

	// 一个临时使用的 ACE 变量
	LPVOID         pTempAce       = NULL;
	UINT           CurrentAceIndex = 0;  //ACE在ACL中的位置

	UINT           newAceIndex = 0;  //新添的ACE在ACL中的位置

	//API函数的返回值,假设所有的函数都返回失败。
	BOOL           fResult;
	BOOL           fAPISuccess;

	SECURITY_INFORMATION secInfo = DACL_SECURITY_INFORMATION;

	// 下面的两个函数是新的API函数,仅在Windows 2000以上版本的操作系统支持。 
	// 在此将从Advapi32.dll文件中动态载入。如果你使用VC++ 6.0编译程序,而且你想
	// 使用这两个函数的静态链接。则请为你的编译加上:/D_WIN32_WINNT=0x0500
	// 的编译参数。并且确保你的SDK的头文件和lib文件是最新的。
	SetSecurityDescriptorControlFnPtr _SetSecurityDescriptorControl = NULL;
	AddAccessAllowedAceExFnPtr _AddAccessAllowedAceEx = NULL; 

	__try {

		// 
		// STEP 1: 通过用户名取得SID
		//     在这一步中LookupAccountName函数被调用了两次,第一次是取出所需要
		// 的内存的大小,然后,进行内存分配。第二次调用才是取得了用户的帐户信息。
		// LookupAccountName同样可以取得域用户或是用户组的信息。(请参看MSDN)
		//

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

		// 以上调用API会失败,失败原因是内存不足。并把所需要的内存大小传出。
		// 下面是处理非内存不足的错误。

		if (fAPISuccess)
			__leave;
		else if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
			//          _tprintf(TEXT("LookupAccountName() failed. Error %d\n"), 
			//                GetLastError());
			__leave;
		}

		pUserSID = myheapalloc(cbUserSID);
		if (!pUserSID) {
			//         _tprintf(TEXT("HeapAlloc() failed. Error %d\n"), GetLastError());
			__leave;
		}

		szDomain = (TCHAR *) myheapalloc(cbDomain * sizeof(TCHAR));
		if (!szDomain) {
			//        _tprintf(TEXT("HeapAlloc() failed. Error %d\n"), GetLastError());
			__leave;
		}

		fAPISuccess = LookupAccountName(NULL, lpszAccountName,
			pUserSID, &cbUserSID, szDomain, &cbDomain, &snuType);
		if (!fAPISuccess) {
			//       _tprintf(TEXT("LookupAccountName() failed. Error %d\n"), 
			//       GetLastError());
			__leave;
		}

		// 
		// STEP 2: 取得文件(目录)相关的安全描述符SD
		//     使用GetFileSecurity函数取得一份文件SD的拷贝,同样,这个函数也
		// 是被调用两次,第一次同样是取SD的内存长度。注意,SD有两种格式:自相关的
		// (self-relative)和 完全的(absolute),GetFileSecurity只能取到“自
		// 相关的”,而SetFileSecurity则需要完全的。这就是为什么需要一个新的SD,
		// 而不是直接在GetFileSecurity返回的SD上进行修改。因为“自相关的”信息
		// 是不完整的。

		fAPISuccess = GetFileSecurity(lpszFileName, 
			secInfo, pFileSD, 0, &cbFileSD);

		// 以上调用API会失败,失败原因是内存不足。并把所需要的内存大小传出。
		// 下面是处理非内存不足的错误。
		if (fAPISuccess)
			__leave;
		else if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
			//       _tprintf(TEXT("GetFileSecurity() failed. Error %d\n"), 
			//        GetLastError());
			__leave;
		}

		pFileSD = myheapalloc(cbFileSD);
		if (!pFileSD) {
			//        _tprintf(TEXT("HeapAlloc() failed. Error %d\n"), GetLastError());
			__leave;
		}

		fAPISuccess = GetFileSecurity(lpszFileName, 
			secInfo, pFileSD, cbFileSD, &cbFileSD);
		if (!fAPISuccess) {
			//     _tprintf(TEXT("GetFileSecurity() failed. Error %d\n"), 
			//          GetLastError());
			__leave;
		}

		// 
		// STEP 3: 初始化一个新的SD
		// 
		if (!InitializeSecurityDescriptor(&newSD, 
			SECURITY_DESCRIPTOR_REVISION)) {
				//    _tprintf(TEXT("InitializeSecurityDescriptor() failed.")
				//     TEXT("Error %d\n"), GetLastError());
				__leave;
		}

		// 
		// STEP 4: 从GetFileSecurity 返回的SD中取DACL
		// 
		if (!GetSecurityDescriptorDacl(pFileSD, &fDaclPresent, &pACL,
			&fDaclDefaulted)) {
				//  _tprintf(TEXT("GetSecurityDescriptorDacl() failed. Error %d\n"),
				//        GetLastError());
				__leave;
		}

		// 
		// STEP 5: 取 DACL的内存size
		//     GetAclInformation可以提供DACL的内存大小。只传入一个类型为
		// ACL_SIZE_INFORMATION的structure的参数,需DACL的信息,是为了
		// 方便我们遍历其中的ACE。
		AclInfo.AceCount = 0; // Assume NULL DACL.
		AclInfo.AclBytesFree = 0;
		AclInfo.AclBytesInUse = sizeof(ACL);

		if (pACL == NULL)
			fDaclPresent = FALSE;

		// 如果DACL不为空,则取其信息。(大多数情况下“自关联”的DACL为空)
		if (fDaclPresent) {            
			if (!GetAclInformation(pACL, &AclInfo, 
				sizeof(ACL_SIZE_INFORMATION), AclSizeInformation)) {
					//  _tprintf(TEXT("GetAclInformation() failed. Error %d\n"),
					//        GetLastError());
					__leave;
			}
		}

		// 
		// STEP 6: 计算新的ACL的size
		//    计算的公式是:原有的DACL的size加上需要添加的一个ACE的size,以
		// 及加上一个和ACE相关的SID的size,最后减去两个字节以获得精确的大小。
		cbNewACL = AclInfo.AclBytesInUse + sizeof(ACCESS_ALLOWED_ACE) 
			+ GetLengthSid(pUserSID) - sizeof(DWORD);


		// 
		// STEP 7: 为新的ACL分配内存
		// 
		pNewACL = (PACL) myheapalloc(cbNewACL);
		if (!pNewACL) {
			// _tprintf(TEXT("HeapAlloc() failed. Error %d\n"), GetLastError());
			//  __leave;
		}

		// 
		// STEP 8: 初始化新的ACL结构
		// 
		if (!InitializeAcl(pNewACL, cbNewACL, ACL_REVISION2)) {
			// _tprintf(TEXT("InitializeAcl() failed. Error %d\n"), 
			//       GetLastError());
			__leave;
		}

		// 
		// STEP 9  如果文件(目录) DACL 有数据,拷贝其中的ACE到新的DACL中
		// 
		//     下面的代码假设首先检查指定文件(目录)是否存在的DACL,如果有的话,
		// 那么就拷贝所有的ACE到新的DACL结构中,我们可以看到其遍历的方法是采用
		// ACL_SIZE_INFORMATION结构中的AceCount成员来完成的。在这个循环中,
		// 会按照默认的ACE的顺序来进行拷贝(ACE在ACL中的顺序是很关键的),在拷
		// 贝过程中,先拷贝非继承的ACE(我们知道ACE会从上层目录中继承下来)
		// 

		newAceIndex = 0;

		if (fDaclPresent && AclInfo.AceCount) {

			for (CurrentAceIndex = 0; 
				CurrentAceIndex < AclInfo.AceCount;
				CurrentAceIndex++) {

					// 
					// STEP 10: 从DACL中取ACE
					// 
					if (!GetAce(pACL, CurrentAceIndex, &pTempAce)) {
						// _tprintf(TEXT("GetAce() failed. Error %d\n"), 
						//       GetLastError());
						__leave;
					}

					// 
					// STEP 11: 检查是否是非继承的ACE
					//     如果当前的ACE是一个从父目录继承来的ACE,那么就退出循环。
					// 因为,继承的ACE总是在非继承的ACE之后,而我们所要添加的ACE
					// 应该在已有的非继承的ACE之后,所有的继承的ACE之前。退出循环
					// 正是为了要添加一个新的ACE到新的DACL中,这后,我们再把继承的
					// ACE拷贝到新的DACL中。
					//
					if (((ACCESS_ALLOWED_ACE *)pTempAce)->Header.AceFlags
						& INHERITED_ACE)
						break;

					// 
					// STEP 12: 检查要拷贝的ACE的SID是否和需要加入的ACE的SID一样,
					// 如果一样,那么就应该废掉已存在的ACE,也就是说,同一个用户的存取
					// 权限的设置的ACE,在DACL中应该唯一。这在里,跳过对同一用户已设置
					// 了的ACE,仅是拷贝其它用户的ACE。
					// 
					if (EqualSid(pUserSID,
						&(((ACCESS_ALLOWED_ACE *)pTempAce)->SidStart)))
						continue;

					// 
					// STEP 13: 把ACE加入到新的DACL中
					//    下面的代码中,注意 AddAce 函数的第三个参数,这个参数的意思是 
					// ACL中的索引值,意为要把ACE加到某索引位置之后,参数MAXDWORD的
					// 意思是确保当前的ACE是被加入到最后的位置。
					//
					if (!AddAce(pNewACL, ACL_REVISION, MAXDWORD, pTempAce,
						((PACE_HEADER) pTempAce)->AceSize)) {
							// _tprintf(TEXT("AddAce() failed. Error %d\n"), 
							//      GetLastError());
							__leave;
					}

					newAceIndex++;
			}
		}

		// 
		// STEP 14: 把一个 access-allowed 的ACE 加入到新的DACL中
		//     前面的循环拷贝了所有的非继承且SID为其它用户的ACE,退出循环的第一件事
		// 就是加入我们指定的ACE。请注意首先先动态装载了一个AddAccessAllowedAceEx
		// 的API函数,如果装载不成功,就调用AddAccessAllowedAce函数。前一个函数仅
		// 在Windows 2000以后的版本支持,NT则没有,我们为了使用新版本的函数,我们首
		// 先先检查一下当前系统中可不可以装载这个函数,如果可以则就使用。使用动态链接
		// 比使用静态链接的好处是,程序运行时不会因为没有这个API函数而报错。
		// 
		// Ex版的函数多出了一个参数AceFlag(第三人参数),用这个参数我们可以来设置一
		// 个叫ACE_HEADER的结构,以便让我们所设置的ACE可以被其子目录所继承下去,而 
		// AddAccessAllowedAce函数不能定制这个参数,在AddAccessAllowedAce函数
		// 中,其会把ACE_HEADER这个结构设置成非继承的。
		// 
		_AddAccessAllowedAceEx = (AddAccessAllowedAceExFnPtr)
			GetProcAddress(GetModuleHandle(TEXT("advapi32.dll")),
			"AddAccessAllowedAceEx");

		if (_AddAccessAllowedAceEx) {
			if (!_AddAccessAllowedAceEx(pNewACL, ACL_REVISION2,
				CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE ,
				dwAccessMask, pUserSID)) {
					// _tprintf(TEXT("AddAccessAllowedAceEx() failed. Error %d\n"),
					//       GetLastError());
					__leave;
			}
		}else{
			if (!AddAccessAllowedAce(pNewACL, ACL_REVISION2, 
				dwAccessMask, pUserSID)) {
					//              _tprintf(TEXT("AddAccessAllowedAce() failed. Error %d\n"),
					//                    GetLastError());
					__leave;
			}
		}

		// 
		// STEP 15: 按照已存在的ACE的顺序拷贝从父目录继承而来的ACE
		// 
		if (fDaclPresent && AclInfo.AceCount) {

			for (; 
				CurrentAceIndex < AclInfo.AceCount;
				CurrentAceIndex++) {

					// 
					// STEP 16: 从文件(目录)的DACL中继续取ACE
					// 
					if (!GetAce(pACL, CurrentAceIndex, &pTempAce)) {
						//                _tprintf(TEXT("GetAce() failed. Error %d\n"), 
						//                      GetLastError());
						__leave;
					}

					// 
					// STEP 17: 把ACE加入到新的DACL中
					// 
					if (!AddAce(pNewACL, ACL_REVISION, MAXDWORD, pTempAce,
						((PACE_HEADER) pTempAce)->AceSize)) {
							//                _tprintf(TEXT("AddAce() failed. Error %d\n"), 
							//                      GetLastError());
							__leave;
					}
			}
		}

		// 
		// STEP 18: 把新的ACL设置到新的SD中
		// 
		if (!SetSecurityDescriptorDacl(&newSD, TRUE, pNewACL, 
			FALSE)) {
				//          _tprintf(TEXT("SetSecurityDescriptorDacl() failed. Error %d\n"),
				//                GetLastError());
				__leave;
		}

		// 
		// STEP 19: 把老的SD中的控制标记再拷贝到新的SD中,我们使用的是一个叫 
		// SetSecurityDescriptorControl() 的API函数,这个函数同样只存在于
		// Windows 2000以后的版本中,所以我们还是要动态地把其从advapi32.dll 
		// 中载入,如果系统不支持这个函数,那就不拷贝老的SD的控制标记了。
		// 
		_SetSecurityDescriptorControl =(SetSecurityDescriptorControlFnPtr)
			GetProcAddress(GetModuleHandle(TEXT("advapi32.dll")),
			"SetSecurityDescriptorControl");
		if (_SetSecurityDescriptorControl) {

			SECURITY_DESCRIPTOR_CONTROL controlBitsOfInterest = 0;
			SECURITY_DESCRIPTOR_CONTROL controlBitsToSet = 0;
			SECURITY_DESCRIPTOR_CONTROL oldControlBits = 0;
			DWORD dwRevision = 0;

			if (!GetSecurityDescriptorControl(pFileSD, &oldControlBits,
				&dwRevision)) {
					//             _tprintf(TEXT("GetSecurityDescriptorControl() failed.")
					//                   TEXT("Error %d\n"), GetLastError());
					__leave;
			}

			if (oldControlBits & SE_DACL_AUTO_INHERITED) {
				controlBitsOfInterest =
					SE_DACL_AUTO_INHERIT_REQ |
					SE_DACL_AUTO_INHERITED ;
				controlBitsToSet = controlBitsOfInterest;
			}
			else if (oldControlBits & SE_DACL_PROTECTED) {
				controlBitsOfInterest = SE_DACL_PROTECTED;
				controlBitsToSet = controlBitsOfInterest;
			}        

			if (controlBitsOfInterest) {
				if (!_SetSecurityDescriptorControl(&newSD,
					controlBitsOfInterest,
					controlBitsToSet)) {
						//                _tprintf(TEXT("SetSecurityDescriptorControl() failed.")
						//                      TEXT("Error %d\n"), GetLastError());
						__leave;
				}
			}
		}

		// 
		// STEP 20: 把新的SD设置设置到文件的安全属性中(千山万水啊,终于到了)
		// 
		if (!SetFileSecurity(lpszFileName, secInfo,
			&newSD)) {
				//          _tprintf(TEXT("SetFileSecurity() failed. Error %d\n"), 
				//                GetLastError());
				__leave;
		}

		fResult = TRUE;

	} __finally {

		// 
		// STEP 21: 释放已分配的内存,以免Memory Leak
		// 
		if (pUserSID)  myheapfree(pUserSID);
		if (szDomain)  myheapfree(szDomain);
		if (pFileSD) myheapfree(pFileSD);
		if (pNewACL) myheapfree(pNewACL);
	}

	return fResult;
}
Exemple #22
-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);
}