VOID NTAPI NpDeleteFcb(IN PNP_FCB Fcb, IN PLIST_ENTRY ListEntry) { PNP_DCB Dcb; PAGED_CODE(); Dcb = Fcb->ParentDcb; if (Fcb->CurrentInstances) NpBugCheck(0, 0, 0); NpCancelWaiter(&NpVcb->WaitQueue, &Fcb->FullName, STATUS_OBJECT_NAME_NOT_FOUND, ListEntry); RemoveEntryList(&Fcb->DcbEntry); if (Fcb->SecurityDescriptor) { ObDereferenceSecurityDescriptor(Fcb->SecurityDescriptor, 1); } RtlRemoveUnicodePrefix(&NpVcb->PrefixTable, &Fcb->PrefixTableEntry); ExFreePool(Fcb->FullName.Buffer); ExFreePool(Fcb); NpCheckForNotify(Dcb, TRUE, ListEntry); }
NTSTATUS NTAPI ObQuerySecurityDescriptorInfo(IN PVOID Object, IN PSECURITY_INFORMATION SecurityInformation, OUT PSECURITY_DESCRIPTOR SecurityDescriptor, IN OUT PULONG Length, IN PSECURITY_DESCRIPTOR *OutputSecurityDescriptor) { POBJECT_HEADER ObjectHeader; NTSTATUS Status; PSECURITY_DESCRIPTOR ObjectSd; PAGED_CODE(); /* Get the object header */ ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object); /* Get the SD */ ObjectSd = ObpReferenceSecurityDescriptor(ObjectHeader); /* Query the information */ Status = SeQuerySecurityDescriptorInfo(SecurityInformation, SecurityDescriptor, Length, &ObjectSd); /* Check if we have an object SD and dereference it, if so */ if (ObjectSd) ObDereferenceSecurityDescriptor(ObjectSd, 1); /* Return status */ return Status; }
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; }
/*++ * @name ObReleaseObjectSecurity * @implemented NT4 * * The ObReleaseObjectSecurity routine <FILLMEIN> * * @param SecurityDescriptor * <FILLMEIN> * * @param MemoryAllocated * <FILLMEIN> * * @return STATUS_SUCCESS or appropriate error value. * * @remarks None. * *--*/ VOID NTAPI ObReleaseObjectSecurity(IN PSECURITY_DESCRIPTOR SecurityDescriptor, IN BOOLEAN MemoryAllocated) { PAGED_CODE(); /* Nothing to do in this case */ if (!SecurityDescriptor) return; /* Check if we had allocated it from memory */ if (MemoryAllocated) { /* Free it */ ExFreePool(SecurityDescriptor); } else { /* Otherwise this means we used an internal descriptor */ ObDereferenceSecurityDescriptor(SecurityDescriptor, 1); } }
NTSTATUS NTAPI ObDeassignSecurity(IN OUT PSECURITY_DESCRIPTOR *SecurityDescriptor) { EX_FAST_REF FastRef; ULONG_PTR Count; PSECURITY_DESCRIPTOR OldSecurityDescriptor; /* Get the fast reference and capture it */ FastRef = *(PEX_FAST_REF)SecurityDescriptor; /* Don't free again later */ *SecurityDescriptor = NULL; /* Get the descriptor and reference count */ OldSecurityDescriptor = ExGetObjectFastReference(FastRef); Count = ExGetCountFastReference(FastRef); /* Dereference the descriptor */ ObDereferenceSecurityDescriptor(OldSecurityDescriptor, Count + 1); /* All done */ return STATUS_SUCCESS; }
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; }