Esempio n. 1
0
NTSTATUS
NTAPI
NpCommonSetSecurityInfo(IN PDEVICE_OBJECT DeviceObject,
                        IN PIRP Irp)
{
    NODE_TYPE_CODE NodeTypeCode;
    PIO_STACK_LOCATION IoStack;
    NTSTATUS Status;
    PNP_FCB Fcb;
    PNP_CCB Ccb;
    ULONG NamedPipeEnd;
    PSECURITY_DESCRIPTOR OldSecurityDescriptor;
    PSECURITY_DESCRIPTOR TempSecurityDescriptor;
    PSECURITY_DESCRIPTOR NewSecurityDescriptor;
    PAGED_CODE();

    IoStack = IoGetCurrentIrpStackLocation(Irp);

    NodeTypeCode = NpDecodeFileObject(IoStack->FileObject,
                                      (PVOID*)&Fcb,
                                      &Ccb,
                                      &NamedPipeEnd);
    if (!NodeTypeCode) return STATUS_PIPE_DISCONNECTED;
    if (NodeTypeCode != NPFS_NTC_CCB) return STATUS_INVALID_PARAMETER;

    OldSecurityDescriptor = TempSecurityDescriptor = Fcb->SecurityDescriptor;
    Status = SeSetSecurityDescriptorInfo(NULL,
                                         &IoStack->Parameters.SetSecurity.SecurityInformation,
                                         IoStack->Parameters.SetSecurity.SecurityDescriptor,
                                         &TempSecurityDescriptor,
                                         TRUE,
                                         IoGetFileObjectGenericMapping());
    if (!NT_SUCCESS(Status)) return Status;

    Status = ObLogSecurityDescriptor(TempSecurityDescriptor, &NewSecurityDescriptor, 1);
    ASSERT(TempSecurityDescriptor != OldSecurityDescriptor);
    ExFreePoolWithTag(TempSecurityDescriptor, 0);

    if (!NT_SUCCESS(Status)) return Status;

    Fcb->SecurityDescriptor = NewSecurityDescriptor;
    ObDereferenceSecurityDescriptor(OldSecurityDescriptor, 1);
    return Status;
}
Esempio n. 2
0
NTSTATUS
NTAPI
ObSetSecurityDescriptorInfo(IN PVOID Object,
                            IN PSECURITY_INFORMATION SecurityInformation,
                            IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
                            IN OUT PSECURITY_DESCRIPTOR *OutputSecurityDescriptor,
                            IN POOL_TYPE PoolType,
                            IN PGENERIC_MAPPING GenericMapping)
{
    NTSTATUS Status;
    POBJECT_HEADER ObjectHeader;
    PSECURITY_DESCRIPTOR OldDescriptor, NewDescriptor, CachedDescriptor;
    PEX_FAST_REF FastRef;
    EX_FAST_REF OldValue;
    ULONG_PTR Count;
    PAGED_CODE();

    /* Get the object header */
    ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
    while (TRUE)
    {
        /* Reference the old descriptor */
        OldDescriptor = ObpReferenceSecurityDescriptor(ObjectHeader);
        NewDescriptor = OldDescriptor;

        /* Set the SD information */
        Status = SeSetSecurityDescriptorInfo(Object,
                                             SecurityInformation,
                                             SecurityDescriptor,
                                             &NewDescriptor,
                                             PoolType,
                                             GenericMapping);
        if (NT_SUCCESS(Status))
        {
            /* Now add this to the cache */
            Status = ObLogSecurityDescriptor(NewDescriptor,
                                             &CachedDescriptor,
                                             MAX_FAST_REFS + 1);

            /* Let go of our uncached copy */
            ExFreePool(NewDescriptor);

            /* Check for success */
            if (NT_SUCCESS(Status))
            {
                /* Do the swap */
                FastRef = (PEX_FAST_REF)OutputSecurityDescriptor;
                OldValue = ExCompareSwapFastReference(FastRef,
                                                      CachedDescriptor,
                                                      OldDescriptor);
                
                /* Get the security descriptor */
                SecurityDescriptor = ExGetObjectFastReference(OldValue);
                Count = ExGetCountFastReference(OldValue);
                
                /* Make sure the swap worked */
                if (SecurityDescriptor == OldDescriptor)
                {
                    /* Flush waiters */
                    ObpAcquireObjectLock(ObjectHeader);
                    ObpReleaseObjectLock(ObjectHeader);

                    /* And dereference the old one */
                    ObDereferenceSecurityDescriptor(OldDescriptor, Count + 2);
                    break;
                }
                else
                {
                    /* Someone changed it behind our back -- try again */
                    ObDereferenceSecurityDescriptor(OldDescriptor, 1);
                    ObDereferenceSecurityDescriptor(CachedDescriptor,
                                                    MAX_FAST_REFS + 1);
                }
            }
            else
            {
                /* We failed, dereference the old one */
                ObDereferenceSecurityDescriptor(OldDescriptor, 1);
                break;
            }
        }
        else
        {
            /* We failed, dereference the old one */
            if (OldDescriptor) ObDereferenceSecurityDescriptor(OldDescriptor, 1);
            break;
        }
    }

    /* Return status */
    return Status;
}
Esempio n. 3
0
NTSTATUS
IopSetDeviceSecurityDescriptors(
    IN PDEVICE_OBJECT           DeviceObject,
    IN PSECURITY_INFORMATION    SecurityInformation,
    IN PSECURITY_DESCRIPTOR     SecurityDescriptor,
    IN POOL_TYPE                PoolType,
    IN PGENERIC_MAPPING         GenericMapping,
    IN BOOLEAN                  DoAttachedDevices
    )
/*++

Routine Description:

    Call this routine to set device security descriptor

Arguments:

    DeviceObject - pointer to base device object (first one to set)
    SecurityInformation )_ passed directly from IopGetSetSecurityObject
    SecurityDescriptor  )
    PoolType            )
    GenericMapping      )
    DoAttachedDevices - if true, iterate the AttachedDevice list

ReturnValue:

    success, or error from first failure

--*/
{
    PDEVICE_OBJECT NewDeviceObject = NULL;
    PSECURITY_DESCRIPTOR OldSecurityDescriptor;
    KIRQL irql;
    NTSTATUS status;
    NTSTATUS firsterr = STATUS_SUCCESS;
    BOOLEAN first = TRUE;

    ASSERT(DeviceObject);

    IopAcquireEnumerationLock(NULL);        // ensure we have acquired P&P locks
    //
    // pre-reference this object to match the dereference later
    //
    ObReferenceObject( DeviceObject );

    do {
        KeEnterCriticalRegion();
        ExAcquireResourceExclusive( &IopSecurityResource, TRUE );

        OldSecurityDescriptor = DeviceObject->SecurityDescriptor;

        if (OldSecurityDescriptor || first) {
            //
            // always call this on the first object, only do it for others that have a security descriptor
            //
            status = SeSetSecurityDescriptorInfo( NULL,
                                                  SecurityInformation,
                                                  SecurityDescriptor,
                                                  &DeviceObject->SecurityDescriptor,
                                                  PoolType,
                                                  GenericMapping );

            if (NT_SUCCESS(firsterr)) {
                firsterr = status;
            }
            if (NT_SUCCESS( status )) {
                ASSERT(OldSecurityDescriptor);
                ExFreePool( OldSecurityDescriptor );
            }
            first = FALSE;
        }

        ExReleaseResource( &IopSecurityResource );
        KeLeaveCriticalRegion();

        //
        // get next device on attachment chain
        //
        ExAcquireSpinLock(&IopDatabaseLock,&irql);
        NewDeviceObject = DeviceObject->AttachedDevice;
        if ( NewDeviceObject != NULL ) {
            ObReferenceObject( NewDeviceObject );
        } else {
            DoAttachedDevices = FALSE;
        }
        ExReleaseSpinLock(&IopDatabaseLock,irql);

        ObDereferenceObject( DeviceObject );
        DeviceObject = NewDeviceObject;

    } while(DoAttachedDevices);

    IopReleaseEnumerationLock(NULL);

    return firsterr;    // of the PDO / single object
}
Esempio n. 4
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);
}