Exemple #1
0
BOOL
BackupReadSecurityData(HANDLE hFile, BACKUPCONTEXT *pbuc, BACKUPIOFRAME *pbif)
{
    if (!pbif->fProcessSecurity) {
	return(TRUE);
    }
    if (pbuc->fStreamStart) {
	while (TRUE) {
	    NTSTATUS Status;
	    DWORD cbSecurityInfo;

	    // First try to read all the security data

	    RtlZeroMemory(pbuc->pBuffer, pbuc->cbBuffer);

	    Status = NtQuerySecurityObject(
			hFile,
			OWNER_SECURITY_INFORMATION |
			    GROUP_SECURITY_INFORMATION |
			    DACL_SECURITY_INFORMATION |
			    SACL_SECURITY_INFORMATION,
			pbuc->pBuffer,
			pbuc->cbBuffer,
			&cbSecurityInfo);

	    if (!NT_SUCCESS(Status) && !BufferOverflow(Status)) {

		// Now just try everything but SACL

		Status = NtQuerySecurityObject(
			    hFile,
			    OWNER_SECURITY_INFORMATION |
				GROUP_SECURITY_INFORMATION |
				DACL_SECURITY_INFORMATION,
			    pbuc->pBuffer,
			    pbuc->cbBuffer,
			    &cbSecurityInfo);
	    }
#if 0
	    if (!NT_SUCCESS(Status) && !BufferOverflow(Status)) {

		// Now just try to read the DACL

		Status = NtQuerySecurityObject(
			    hFile,
			    OWNER_SECURITY_INFORMATION |
				GROUP_SECURITY_INFORMATION,
			    pbuc->pBuffer,
			    pbuc->cbBuffer,
			    &cbSecurityInfo);
	    }
#endif
	    if (NT_SUCCESS(Status)) {
		pbuc->fBufferReady = TRUE;
		break;
	    }
	    if (!BufferOverflow(Status)) {
		return(TRUE);	// No Security info, do next stream type
	    }
	    if (!GrowBuffer(pbuc, cbSecurityInfo)) {
		return(FALSE);	// No memory
	    }
	    // else grow succeeded
	}

	pbuc->head.dwStreamId = mwStreamList[pbuc->StreamIndex];
	pbuc->head.dwStreamAttributes = STREAM_CONTAINS_SECURITY;
	pbuc->head.dwStreamNameSize = 0;

	pbuc->cbHeader = CB_NAMELESSHEADER;

	pbuc->head.Size.LowPart = RtlLengthSecurityDescriptor(pbuc->pBuffer);
	pbuc->head.Size.HighPart = 0;

	pbuc->fStreamStart = FALSE;
    }
    else if (pbuc->liStreamOffset.HighPart != 0 ||
	     pbuc->liStreamOffset.LowPart >= pbuc->cbHeader) {
	BackupReadBuffer(pbuc, pbif);
    }
    return(TRUE);
}
Exemple #2
0
/*++
* @name ObLogSecurityDescriptor
* @implemented NT5.2
*
*     The ObLogSecurityDescriptor routine <FILLMEIN>
*
* @param InputSecurityDescriptor
*        <FILLMEIN>
*
* @param OutputSecurityDescriptor
*        <FILLMEIN>
*
* @param RefBias
*        <FILLMEIN>
*
* @return STATUS_SUCCESS or appropriate error value.
*
* @remarks None.
*
*--*/
NTSTATUS
NTAPI
ObLogSecurityDescriptor(IN PSECURITY_DESCRIPTOR InputSecurityDescriptor,
                        OUT PSECURITY_DESCRIPTOR *OutputSecurityDescriptor,
                        IN ULONG RefBias)
{
    PSECURITY_DESCRIPTOR_HEADER SdHeader = NULL, NewHeader  = NULL;
    ULONG Length, Hash, Index;
    POB_SD_CACHE_LIST CacheEntry;
    BOOLEAN Result;
    PLIST_ENTRY NextEntry;

    /* Get the length */
    Length = RtlLengthSecurityDescriptor(InputSecurityDescriptor);
    
    /* Get the hash */
    Hash = ObpHashSecurityDescriptor(InputSecurityDescriptor, Length);
    
    /* Now select the appropriate cache entry */
    Index = Hash % SD_CACHE_ENTRIES;
    CacheEntry = &ObsSecurityDescriptorCache[Index];
    
    /* Lock it shared */
    ObpSdAcquireLockShared(CacheEntry);
    
    /* Start our search */
    while (TRUE)
    {
        /* Reset result found */
        Result = FALSE;
        
        /* Loop the hash list */
        NextEntry = CacheEntry->Head.Flink;
        while (NextEntry != &CacheEntry->Head)
        {
            /* Get the header */
            SdHeader = ObpGetHeaderForEntry(NextEntry);
            
            /* Our hashes are ordered, so quickly check if we should stop now */
            if (SdHeader->FullHash > Hash) break;
            
            /* We survived the quick hash check, now check for equalness */
            if (SdHeader->FullHash == Hash)
            {
                /* Hashes match, now compare descriptors */
                Result = ObpCompareSecurityDescriptors(InputSecurityDescriptor,
                                                       Length,
                                                       &SdHeader->SecurityDescriptor);
                if (Result) break;
            }
            
            /* Go to the next entry */
            NextEntry = NextEntry->Flink;
        }
        
        /* Check if we found anything */
        if (Result)
        {
            /* Increment its reference count */
            InterlockedExchangeAdd((PLONG)&SdHeader->RefCount, RefBias);
            
            /* Release the lock */
            ObpSdReleaseLockShared(CacheEntry);
            
            /* Return the descriptor */
            *OutputSecurityDescriptor = &SdHeader->SecurityDescriptor;
            
            /* Free anything that we may have had to create */
            if (NewHeader) ExFreePool(NewHeader);
            return STATUS_SUCCESS;
        }
        
        /* Check if we got here, and didn't create a descriptor yet */
        if (!NewHeader)
        {
            /* Release the lock */
            ObpSdReleaseLockShared(CacheEntry);
            
            /* This should be our first time in the loop, create it */
            NewHeader = ObpCreateCacheEntry(InputSecurityDescriptor,
                                            Length,
                                            Hash,
                                            RefBias);
            if (!NewHeader) return STATUS_INSUFFICIENT_RESOURCES;
            
            /* Now acquire the exclusive lock and we should hit the right path */
            ObpSdAcquireLock(CacheEntry);
        }
        else
        {
            /* We have inserted the SD, we're fine now */
            break;
        }
    }
    
    /* Okay, now let's do the insert, we should have the exclusive lock */
    InsertTailList(NextEntry, &NewHeader->Link);
    
    /* Release the lock */
    ObpSdReleaseLock(CacheEntry);
    
    /* Return the SD*/
    *OutputSecurityDescriptor = &NewHeader->SecurityDescriptor;
    return STATUS_SUCCESS;
}
Exemple #3
0
NTSTATUS
AfdCreateRawSecurityDescriptor(
    VOID
    )

/*++

Routine Description:

    This routine creates a security descriptor which gives access
    only to Administrtors and LocalSystem. This descriptor is used
    to access check raw endpoint opens.

Arguments:

    None.

Return Value:

    STATUS_SUCCESS or an appropriate error code.

--*/

{
    PACL                  rawAcl;
    NTSTATUS              status;
    BOOLEAN               memoryAllocated = FALSE;
    PSECURITY_DESCRIPTOR  afdSecurityDescriptor;
    ULONG                 afdSecurityDescriptorLength;
    CHAR                  buffer[SECURITY_DESCRIPTOR_MIN_LENGTH];
    PSECURITY_DESCRIPTOR  localSecurityDescriptor =
                             (PSECURITY_DESCRIPTOR) &buffer;
    SECURITY_INFORMATION  securityInformation = DACL_SECURITY_INFORMATION;


    //
    // Get a pointer to the security descriptor from the AFD device object.
    //
    status = ObGetObjectSecurity(
                 AfdDeviceObject,
                 &afdSecurityDescriptor,
                 &memoryAllocated
                 );

    if (!NT_SUCCESS(status)) {
        KdPrint((
            "AFD: Unable to get security descriptor, error: %x\n",
            status
            ));
        ASSERT(memoryAllocated == FALSE);
        return(status);
    }

    //
    // Build a local security descriptor with an ACL giving only
    // administrators and system access.
    //
    status = AfdBuildDeviceAcl(&rawAcl);

    if (!NT_SUCCESS(status)) {
        KdPrint(("AFD: Unable to create Raw ACL, error: %x\n", status));
        goto error_exit;
    }

    (VOID) RtlCreateSecurityDescriptor(
                localSecurityDescriptor,
                SECURITY_DESCRIPTOR_REVISION
                );

    (VOID) RtlSetDaclSecurityDescriptor(
                localSecurityDescriptor,
                TRUE,
                rawAcl,
                FALSE
                );

    //
    // Make a copy of the AFD descriptor. This copy will be the raw descriptor.
    //
    afdSecurityDescriptorLength = RtlLengthSecurityDescriptor(
                                      afdSecurityDescriptor
                                      );

    AfdRawSecurityDescriptor = AFD_ALLOCATE_POOL(
                                   PagedPool,
                                   afdSecurityDescriptorLength,
                                   AFD_SECURITY_POOL_TAG
                                   );

    if (AfdRawSecurityDescriptor == NULL) {
        KdPrint(("AFD: couldn't allocate security descriptor\n"));
        goto error_exit;
    }

    RtlMoveMemory(
        AfdRawSecurityDescriptor,
        afdSecurityDescriptor,
        afdSecurityDescriptorLength
        );

    //
    // Now apply the local descriptor to the raw descriptor.
    //
    status = SeSetSecurityDescriptorInfo(
                 NULL,
                 &securityInformation,
                 localSecurityDescriptor,
                 &AfdRawSecurityDescriptor,
                 PagedPool,
                 IoGetFileObjectGenericMapping()
                 );

    if (!NT_SUCCESS(status)) {
        KdPrint(("AFD: SeSetSecurity failed, %lx\n", status));
        AFD_FREE_POOL(
            AfdRawSecurityDescriptor,
            AFD_SECURITY_POOL_TAG
            );
        AFD_FREE_POOL(
            rawAcl,
            AFD_SECURITY_POOL_TAG
            );
        AfdRawSecurityDescriptor = NULL;
        goto error_exit;
    }

    status = STATUS_SUCCESS;

error_exit:

    ObReleaseObjectSecurity(
        afdSecurityDescriptor,
        memoryAllocated
        );

    return(status);
}