Example #1
0
NTSTATUS
NTAPI
NpInitializeSecurity(IN PNP_CCB Ccb,
                     IN PSECURITY_QUALITY_OF_SERVICE SecurityQos,
                     IN PETHREAD Thread)
{
    PSECURITY_CLIENT_CONTEXT ClientContext;
    NTSTATUS Status;
    PAGED_CODE();

    if (SecurityQos)
    {
        Ccb->ClientQos = *SecurityQos;
    }
    else
    {
        Ccb->ClientQos.Length = sizeof(Ccb->ClientQos);
        Ccb->ClientQos.ImpersonationLevel = SecurityImpersonation;
        Ccb->ClientQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
        Ccb->ClientQos.EffectiveOnly = TRUE;
    }

    NpUninitializeSecurity(Ccb);

    if (Ccb->ClientQos.ContextTrackingMode == SECURITY_DYNAMIC_TRACKING)
    {
        Status = STATUS_SUCCESS;
        Ccb->ClientContext = NULL;
        return Status;
    }

    ClientContext = ExAllocatePoolWithQuotaTag(PagedPool | POOL_QUOTA_FAIL_INSTEAD_OF_RAISE,
                                               sizeof(*ClientContext),
                                               NPFS_CLIENT_SEC_CTX_TAG);
    Ccb->ClientContext = ClientContext;
    if (!ClientContext) return STATUS_INSUFFICIENT_RESOURCES;

    Status = SeCreateClientSecurity(Thread, &Ccb->ClientQos, 0, ClientContext);
    if (!NT_SUCCESS(Status))
    {
        ExFreePool(Ccb->ClientContext);
        Ccb->ClientContext = NULL;
    }

    return Status;
}
Example #2
0
NTSTATUS
NTAPI
NpListen(IN PDEVICE_OBJECT DeviceObject,
         IN PIRP Irp,
         IN PLIST_ENTRY List)
{
    ULONG NamedPipeEnd;
    PNP_CCB Ccb;
    NTSTATUS Status;
    NODE_TYPE_CODE NodeTypeCode;
    PIO_STACK_LOCATION IoStack;
    PAGED_CODE();

    IoStack = IoGetCurrentIrpStackLocation(Irp);

    NodeTypeCode = NpDecodeFileObject(IoStack->FileObject, NULL, &Ccb, &NamedPipeEnd);
    if (NodeTypeCode == NPFS_NTC_CCB)
    {
        if (NamedPipeEnd == FILE_PIPE_SERVER_END)
        {
            ExAcquireResourceExclusiveLite(&Ccb->NonPagedCcb->Lock, TRUE);

            Status = NpSetListeningPipeState(Ccb, Irp, List);

            NpUninitializeSecurity(Ccb);

            ExReleaseResourceLite(&Ccb->NonPagedCcb->Lock);
        }
        else
        {
            Status = STATUS_ILLEGAL_FUNCTION;
        }
    }
    else
    {
        Status = STATUS_ILLEGAL_FUNCTION;
    }

    return Status;
}
Example #3
0
VOID
NTAPI
NpDeleteCcb(IN PNP_CCB Ccb,
            IN PLIST_ENTRY ListEntry)
{
    PNP_ROOT_DCB_FCB RootDcbCcb;
    PAGED_CODE();

    RootDcbCcb = (PNP_ROOT_DCB_FCB)Ccb;
    if (Ccb->NodeType == NPFS_NTC_CCB)
    {
        RemoveEntryList(&Ccb->CcbEntry);
        --Ccb->Fcb->CurrentInstances;

        NpDeleteEventTableEntry(&NpVcb->EventTable,
                                Ccb->NonPagedCcb->EventBuffer[FILE_PIPE_CLIENT_END]);
        NpDeleteEventTableEntry(&NpVcb->EventTable,
                                Ccb->NonPagedCcb->EventBuffer[FILE_PIPE_SERVER_END]);
        NpUninitializeDataQueue(&Ccb->DataQueue[FILE_PIPE_INBOUND]);
        NpUninitializeDataQueue(&Ccb->DataQueue[FILE_PIPE_OUTBOUND]);
        NpCheckForNotify(Ccb->Fcb->ParentDcb, FALSE, ListEntry);
        ExDeleteResourceLite(&Ccb->NonPagedCcb->Lock);
        NpUninitializeSecurity(Ccb);
        if (Ccb->ClientSession)
        {
            ExFreePool(Ccb->ClientSession);
            Ccb->ClientSession = NULL;
        }
        ExFreePool(Ccb->NonPagedCcb);
    }
    else if (RootDcbCcb->NodeType == NPFS_NTC_ROOT_DCB_CCB && RootDcbCcb->Unknown)
    {
        ExFreePool(RootDcbCcb->Unknown);
    }

    ExFreePool(Ccb);
}
Example #4
0
NTSTATUS
NTAPI
NpSetDisconnectedPipeState(IN PNP_CCB Ccb,
                           IN PLIST_ENTRY List)
{
    PIRP Irp;
    PNP_NONPAGED_CCB NonPagedCcb;
    NTSTATUS Status;
    PLIST_ENTRY NextEntry;
    PNP_EVENT_BUFFER EventBuffer;

    NonPagedCcb = Ccb->NonPagedCcb;

    switch (Ccb->NamedPipeState)
    {
        case FILE_PIPE_DISCONNECTED_STATE:
            Status = STATUS_PIPE_DISCONNECTED;
            break;

        case FILE_PIPE_LISTENING_STATE:
            while (!IsListEmpty(&Ccb->IrpList))
            {
                NextEntry = RemoveHeadList(&Ccb->IrpList);

                Irp = CONTAINING_RECORD(NextEntry, IRP, Tail.Overlay.ListEntry);

                if (IoSetCancelRoutine(Irp, NULL))
                {
                    Irp->IoStatus.Status = STATUS_PIPE_DISCONNECTED;
                    InsertTailList(List, NextEntry);
                }
                else
                {
                    InitializeListHead(NextEntry);
                }
            }

            Status = STATUS_SUCCESS;
            break;

        case FILE_PIPE_CONNECTED_STATE:

            EventBuffer = NonPagedCcb->EventBuffer[FILE_PIPE_CLIENT_END];

            while (Ccb->DataQueue[FILE_PIPE_INBOUND].QueueState != Empty)
            {
                Irp = NpRemoveDataQueueEntry(&Ccb->DataQueue[FILE_PIPE_INBOUND], FALSE, List);
                if (Irp)
                {
                    Irp->IoStatus.Status = STATUS_PIPE_DISCONNECTED;
                    InsertTailList(List, &Irp->Tail.Overlay.ListEntry);
                }
            }

            while (Ccb->DataQueue[FILE_PIPE_OUTBOUND].QueueState != Empty)
            {
                Irp = NpRemoveDataQueueEntry(&Ccb->DataQueue[FILE_PIPE_OUTBOUND], FALSE, List);
                if (Irp)
                {
                    Irp->IoStatus.Status = STATUS_PIPE_DISCONNECTED;
                    InsertTailList(List, &Irp->Tail.Overlay.ListEntry);
                }
            }

            if (EventBuffer) KeSetEvent(EventBuffer->Event, IO_NO_INCREMENT, FALSE);

            // drop down on purpose... queue will be empty so flush code is nop
            ASSERT(Ccb->DataQueue[FILE_PIPE_OUTBOUND].QueueState == Empty);

        case FILE_PIPE_CLOSING_STATE:

            EventBuffer = NonPagedCcb->EventBuffer[FILE_PIPE_CLIENT_END];

            while (Ccb->DataQueue[FILE_PIPE_INBOUND].QueueState != Empty)
            {
                Irp = NpRemoveDataQueueEntry(&Ccb->DataQueue[FILE_PIPE_INBOUND], FALSE, List);
                if (Irp)
                {
                    Irp->IoStatus.Status = STATUS_PIPE_DISCONNECTED;
                    InsertTailList(List, &Irp->Tail.Overlay.ListEntry);
                }
            }

            ASSERT(Ccb->DataQueue[FILE_PIPE_OUTBOUND].QueueState == Empty);

            NpDeleteEventTableEntry(&NpVcb->EventTable, EventBuffer);
            NonPagedCcb->EventBuffer[FILE_PIPE_CLIENT_END] = NULL;

            NpSetFileObject(Ccb->FileObject[FILE_PIPE_CLIENT_END], NULL, NULL, FALSE);
            Ccb->FileObject[FILE_PIPE_CLIENT_END] = NULL;

            NpUninitializeSecurity(Ccb);

            if (Ccb->ClientSession)
            {
                ExFreePool(Ccb->ClientSession);
                Ccb->ClientSession = NULL;
            }

            Status = STATUS_SUCCESS;
            break;

        default:
            NpBugCheck(Ccb->NamedPipeState, 0, 0);
            break;
    }

    Ccb->NamedPipeState = FILE_PIPE_DISCONNECTED_STATE;
    return Status;
}
Example #5
0
NTSTATUS
NTAPI
NpSetClosingPipeState(IN PNP_CCB Ccb,
                      IN PIRP Irp,
                      IN ULONG NamedPipeEnd,
                      IN PLIST_ENTRY List)
{
    PNP_NONPAGED_CCB NonPagedCcb;
    PNP_FCB Fcb;
    PLIST_ENTRY NextEntry;
    PNP_DATA_QUEUE ReadQueue, WriteQueue, DataQueue;
    PNP_EVENT_BUFFER EventBuffer;
    PIRP ListIrp;

    NonPagedCcb = Ccb->NonPagedCcb;
    Fcb = Ccb->Fcb;

    switch (Ccb->NamedPipeState)
    {
        case FILE_PIPE_LISTENING_STATE:

            ASSERT(NamedPipeEnd == FILE_PIPE_SERVER_END);

            while (!IsListEmpty(&Ccb->IrpList))
            {
                NextEntry = RemoveHeadList(&Ccb->IrpList);

                ListIrp = CONTAINING_RECORD(NextEntry, IRP, Tail.Overlay.ListEntry);

                if (IoSetCancelRoutine(ListIrp, NULL))
                {
                    ListIrp->IoStatus.Status = STATUS_PIPE_BROKEN;
                    InsertTailList(List, NextEntry);
                }
                else
                {
                    InitializeListHead(NextEntry);
                }
            }

            // Drop on purpose

        case FILE_PIPE_DISCONNECTED_STATE:

            ASSERT(NamedPipeEnd == FILE_PIPE_SERVER_END);

            NpSetFileObject(Ccb->FileObject[FILE_PIPE_SERVER_END], NULL, NULL, TRUE);
            Ccb->FileObject[FILE_PIPE_SERVER_END] = NULL;

            NpSetFileObject(Ccb->FileObject[FILE_PIPE_CLIENT_END], NULL, NULL, FALSE);
            Ccb->FileObject[FILE_PIPE_CLIENT_END] = NULL;

            NpDeleteCcb(Ccb, List);
            if (!Fcb->CurrentInstances) NpDeleteFcb(Fcb, List);
            break;

        case FILE_PIPE_CLOSING_STATE:

            if (NamedPipeEnd == FILE_PIPE_SERVER_END)
            {
                DataQueue = &Ccb->DataQueue[FILE_PIPE_INBOUND];
            }
            else
            {
                DataQueue = &Ccb->DataQueue[FILE_PIPE_OUTBOUND];
            }

            NpSetFileObject(Ccb->FileObject[FILE_PIPE_SERVER_END], NULL, NULL, TRUE);
            Ccb->FileObject[FILE_PIPE_SERVER_END] = NULL;

            NpSetFileObject(Ccb->FileObject[FILE_PIPE_CLIENT_END], NULL, NULL, FALSE);
            Ccb->FileObject[FILE_PIPE_CLIENT_END] = NULL;

            while (DataQueue->QueueState != Empty)
            {
                ListIrp = NpRemoveDataQueueEntry(DataQueue, FALSE, List);
                if (ListIrp)
                {
                    ListIrp->IoStatus.Status = STATUS_PIPE_BROKEN;
                    InsertTailList(List, &ListIrp->Tail.Overlay.ListEntry);
                }
            }

            NpUninitializeSecurity(Ccb);

            if (Ccb->ClientSession)
            {
                ExFreePool(Ccb->ClientSession);
                Ccb->ClientSession = NULL;
            }

            NpDeleteCcb(Ccb, List);
            if (!Fcb->CurrentInstances) NpDeleteFcb(Fcb, List);
            break;

        case FILE_PIPE_CONNECTED_STATE:

            if (NamedPipeEnd == FILE_PIPE_SERVER_END)
            {
                ReadQueue = &Ccb->DataQueue[FILE_PIPE_INBOUND];
                WriteQueue = &Ccb->DataQueue[FILE_PIPE_OUTBOUND];

                NpSetFileObject(Ccb->FileObject[FILE_PIPE_SERVER_END], NULL, NULL, TRUE);
                Ccb->FileObject[FILE_PIPE_SERVER_END] = NULL;
            }
            else
            {
                ReadQueue = &Ccb->DataQueue[FILE_PIPE_OUTBOUND];
                WriteQueue = &Ccb->DataQueue[FILE_PIPE_INBOUND];

                NpSetFileObject(Ccb->FileObject[FILE_PIPE_CLIENT_END], NULL, NULL, FALSE);
                Ccb->FileObject[FILE_PIPE_CLIENT_END] = NULL;
            }

            EventBuffer = NonPagedCcb->EventBuffer[NamedPipeEnd];

            Ccb->NamedPipeState = FILE_PIPE_CLOSING_STATE;

            while (ReadQueue->QueueState != Empty)
            {
                ListIrp = NpRemoveDataQueueEntry(ReadQueue, FALSE, List);
                if (ListIrp)
                {
                    ListIrp->IoStatus.Status = STATUS_PIPE_BROKEN;
                    InsertTailList(List, &ListIrp->Tail.Overlay.ListEntry);
                }
            }

            while (WriteQueue->QueueState == ReadEntries)
            {
                ListIrp = NpRemoveDataQueueEntry(WriteQueue, FALSE, List);
                if (ListIrp)
                {
                    ListIrp->IoStatus.Status = STATUS_PIPE_BROKEN;
                    InsertTailList(List, &ListIrp->Tail.Overlay.ListEntry);
                }
            }

            if (EventBuffer) KeSetEvent(EventBuffer->Event, IO_NO_INCREMENT, FALSE);
            break;

        default:
            NpBugCheck(Ccb->NamedPipeState, 0, 0);
            break;
    }
    return STATUS_SUCCESS;
}