Getting User SID issue in PreCreate (Difference between legacy and MiniFilter driver)

Hi All,

I am seeing a different behavior between legacy driver and MiniFilter
driver when i am trying to get the SID of the requesting thread.

I have one folder shared on my server and clients are accessing that
share. Let’s say user2 is logged into the client system, then system
impersonate to system/NT Authority and sends the request down the stack.
So far so good.

I am trying to get the SID of the requesting thread in PreCreate (i am
not interested in SID of the impersonating thread). I tried to search
about this issue but only found the FAQ on OSR Site

"For remote calls, however, the CIFS server routinely utilizes
impersonation during IRP_MJ_CREATE and for some IRP_MJ_SET_INFORMATION
operations. Otherwise, the CIFS server uses the local system’s
credentials. To handle this case, a filter must store away the
credential information of the original caller. In the case of
IRP_MJ_CREATE the original caller’s token is specified as part of the
IO_SECURITY_CONTEXT parameter. The ACCESS_STATE structure in turn
contains the SECURITY_SUBJECT_CONTEXT and the filter can retrieve a
pointer to the token using SeQuerySubjectContextToken. The SID can then
be retrieved from the token using SeQueryInformationToken.
"

This is exactly what i did and below is the code snippet.

But i don’t get the SID of the requesting thread. When i dug deep into
this, this is what i found in _SECURITY_SUBJECT_CONTEXT structure in my
minifilter driver.

ClientToken = NULL;
ImpersonationLevel = SecurityAnonymous; ??
PrimaryToken = “token of impersonating thread (system/NT Authority)”;

Why i am unable to get the clienttoken in minifilter? or how do i get
the SID of the requesting thread in minifilter?

When i install my legacy driver, i am able to get the clienttoken. No
changes in the system setup or anywhere else. Its the same call, same
request.

Here is the code…

Token2 =
SeQuerySubjectContextToken(&(Cbd->Iopb->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext));

// Get User SID
Status = SeQueryInformationToken(Token, TokenUser, (PVOID *) & kenUser);

if (!NT_SUCCESS(Status)) {
DoTraceLevelMessage(TRACE_LEVEL_CRITICAL, FILE_TRACE_FLAG,
“%s SeQueryInformationToken(File - %wZ, Token - %p, Cbd - %p,
TOKEN_USER) failed with error - 0x%X\n”,
TRACE_PREFIX,
FILENAME_FROM_FILEOBJECT
(FltObjects->FileObject), Token, Cbd,
Status);
LEAVE;
}

thanks in advance

Its not an answer, but what happens if you look for the security context in the irp (from the debugger) - is it the same thing, or different?

Hi,
Its the same information in the IRP and Cbd->Iopb->Parameters…

1: kd> ?? ((nt!_io_stack_location
*)${ioStack})->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext
struct _SECURITY_SUBJECT_CONTEXT
+0x000 ClientToken : (null)
+0x008 ImpersonationLevel : 0 ( SecurityAnonymous )
+0x010 PrimaryToken : 0xfffffa8000000940 +0x018 ProcessAuditId : 0x0000000000000004

1: kd> ??
Cbd->Iopb->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext
struct _SECURITY_SUBJECT_CONTEXT
+0x000 ClientToken : (null)
+0x008 ImpersonationLevel : 0 ( SecurityAnonymous )
+0x010 PrimaryToken : 0xfffffa8000000940 +0x018 ProcessAuditId : 0x0000000000000004

picked up the irp from the stack…and dumped it

1: kd> !irp fffffabe`c5758ca0 1
Irp is active with 9 stacks 8 is current (= 0xfffffabec5758f68)
No Mdl: No System Buffer: Thread fffffadfe5d64bf0: Irp stack trace.
Flags = 40000884
ThreadListEntry.Flink = fffffadfe5d64f88
ThreadListEntry.Blink = fffffadfe5d64f88
IoStatus.Status = 00000000
IoStatus.Information = 00000000
RequestorMode = 00000000
Cancel = 00
CancelIrql = 0
ApcEnvironment = 00
UserIosb = fffffadfe27ea320
UserEvent = 00000000
Overlay.AsynchronousParameters.UserApcRoutine = 00000000
Overlay.AsynchronousParameters.UserApcContext = 00000000
Overlay.AllocationSize = 00000000 - 00000000
CancelRoutine = 00000000
UserBuffer = 00000000
&Tail.Overlay.DeviceQueueEntry = fffffabec5758d18
Tail.Overlay.Thread = fffffadfe5d64bf0
Tail.Overlay.AuxiliaryBuffer = 00000000
Tail.Overlay.ListEntry.Flink = 00000000
Tail.Overlay.ListEntry.Blink = 00000000
Tail.Overlay.CurrentStackLocation = fffffabec5758f68
Tail.Overlay.OriginalFileObject = fffffadfe7255c40
Tail.Apc = 00000000
Tail.CompletionKey = 00000000
cmd flg cl Device File Completion-Context
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
>[0, 0] 0 e1 fffffadfe744d040 fffffadfe7255c40
fffffadfe3f8d200-fffffadfff31dcb0 Success Error Cancel pending
\FileSystem\FltMgr fltmgr!FltpSynchronizedOperationCompletion
Args: fffffadfe27ea378 01000001 00030000 00000000
[0, 0] 0 0 fffffadfe73d0800 fffffadfe7255c40 00000000-00000000
\FileSystem\FltMgr
Args: fffffadfe27ea378 01000001 00030000 00000000
1: kd> as ioStack 0xfffffabec5758f68
1: kd> ?? ((nt!_io_stack_location
*)${ioStack})->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext
struct _SECURITY_SUBJECT_CONTEXT
+0x000 ClientToken : (null)
+0x008 ImpersonationLevel : 0 ( SecurityAnonymous )
+0x010 PrimaryToken : 0xfffffa8000000940 +0x018 ProcessAuditId : 0x0000000000000004

xxxxx@steadingsoftware.com wrote:

Its not an answer, but what happens if you look for the security context in the irp (from the debugger) - is it the same thing, or different?

> Its the same information in the IRP and Cbd->Iopb->Parameters…

So (and again this is no immediately help but might help direct your
researches), there is no difference between old and new, so you need to dig
further as what is different between your legacy and minifilter versions.

It is worth also pointing out that not all SRV creates come with
impersonation…

Thanks Rod for the information.

“It is worth also pointing out that not all SRV creates come with
impersonation…”

Is it possible to force all the SRV with impersonation?

I read article on MS site (
http://msdn.microsoft.com/en-us/library/aa378832(VS.85).aspx),
which indicates that we can change impersonation level in the service
directory. I changes the impersonation level in the server directory,
but it didn’t help.
As you pointed out, not all SRV comes with impersonation, i will not be
able to retrieve the user information. If i can force the server with
“SecurityImpersonation” then i will be able to retrieve the user
information.

thanks
Rod Widdowson wrote:

> Its the same information in the IRP and Cbd->Iopb->Parameters…

So (and again this is no immediately help but might help direct your
researches), there is no difference between old and new, so you need to
dig further as what is different between your legacy and minifilter
versions.

It is worth also pointing out that not all SRV creates come with
impersonation…