Exemple #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;
}
Exemple #2
0
NTSTATUS
NTAPI
ObAssignObjectSecurityDescriptor(IN PVOID Object,
                                 IN PSECURITY_DESCRIPTOR SecurityDescriptor OPTIONAL,
                                 IN POOL_TYPE PoolType)
{
    POBJECT_HEADER ObjectHeader;
    NTSTATUS Status;
    PSECURITY_DESCRIPTOR NewSd;
    PEX_FAST_REF FastRef;
    PAGED_CODE();

    /* Get the object header */
    ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
    FastRef = (PEX_FAST_REF)&ObjectHeader->SecurityDescriptor;
    if (!SecurityDescriptor)
    {
        /* Nothing to assign */
        ExInitializeFastReference(FastRef, NULL);
        return STATUS_SUCCESS;
    }

    /* Add it to our internal cache */
    Status = ObLogSecurityDescriptor(SecurityDescriptor,
                                     &NewSd,
                                     MAX_FAST_REFS + 1);
    if (NT_SUCCESS(Status))
    {
        /* Free the old copy */
        ExFreePoolWithTag(SecurityDescriptor, TAG_SD);

        /* Set the new pointer */
        ASSERT(NewSd);
        ExInitializeFastReference(FastRef, NewSd);
    }

    /* Return status */
    return Status;
}
Exemple #3
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;
}