getting SID of the User inside my FSFD

Hi all,

for the last couple of days I have been tryign to get the SID of the user
whose process requested the FS call. My product is somwwhat like filemon,
though there are many differences and the final objective is different too.
Nevertheless, Filespy seemed to be a good starting point and all I need at
this time is to get the SID of the user for all IRPS i log.

Is it fundamentally wrong to query for the SID in dispatch routines other
than IRP_MJ_CREATE? If so, then how do I go about finding the SIDs for each
IRP?

  • amitr0

If you just want the SID of the current process, go ahead and get it
whenever you want. That doesn’t mean it is the SID of the process that
opened the file - because that’s only guaranteed during IRP_MJ_CREATE
and certain IRP_MJ_SET_INFORMATION calls (rename and create hard link).
If you want the SID of the process that opened the file originally,
store it in your filter context or in a separate lookaside table keyed
off the FILE_OBJECT.

Specific example: the CIFS server operates on behalf of remote clients.
It impersonates the remote client only on those calls that require a
security check - ergo, when the file is created or when a potentially
destructive operation (like rename or create hard link with “delete
target of operation”) is performed. If you ask for the SID for any
other operation, you’ll get the local system SID (since the CIFS server
is implemented using a kernel driver and executes in worker threads.)

Regards,

Tony

Tony Mason

Consulting Partner

OSR Open Systems Resources, Inc.

http://www.osr.com

Looking forward to seeing you at the next OSR File Systems class in
Boston, MA April 18-21, 2006.


From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of amitr0
Sent: Friday, April 07, 2006 4:20 AM
To: ntfsd redirect
Subject: [ntfsd] getting SID of the User inside my FSFD

Hi all,

for the last couple of days I have been tryign to get the SID of the
user whose process requested the FS call. My product is somwwhat like
filemon, though there are many differences and the final objective is
different too. Nevertheless, Filespy seemed to be a good starting point
and all I need at this time is to get the SID of the user for all IRPS i
log.

Is it fundamentally wrong to query for the SID in dispatch routines
other than IRP_MJ_CREATE? If so, then how do I go about finding the SIDs
for each IRP?

>If you just want the SID of the current process, go ahead and get it
whenever you want.

I want the SID of the process that sent that particular IRP down to me.

That doesn’t mean it is the SID of the process that opened the file ?
because that’s only guaranteed during IRP_MJ_CREATE and certain
IRP_MJ_SET_INFORMATION calls (rename and create hard link). If you want
the SID of the process that opened the file originally, store it >in your
filter context or in a separate lookaside table keyed off the FILE_OBJECT.

You mean to say that Notepad.exe opened file abcd.txt (which is very large,

32 Megs, say) and the multiple IRP_MJ_READs I see on the sysetm from
Notepad, might not return me the correct SID of the guy who has launched
Notepad? Why is it do? Yes, I did read the bit about the CIFS, but still I
need more clarification, if you could kindly tell me a bit more in detail.

More over I also hav observed that the SID is not even fetched at times, I
cannot figure out why the token query functions return access violation etc.

Here is the code I use to get the SID, is it worng? I don’t query the
current thread in this code.

void GetSID(PUNICODE_STRING sidString)
{
NTSTATUS ntStatus;
PVOID Token;
HANDLE tokenHandle;
PTOKEN_USER tokenInfoBuffer;
ULONG requiredLength;
// PCHAR sidStringBuffer[512];
PWCHAR sidStringBuffer;

sidStringBuffer= ExAllocatePool(NonPagedPool, 512 );
RtlInitEmptyUnicodeString
(sidString,sidStringBuffer,512);

Token=PsReferencePrimaryToken(PsGetCurrentProcess());
ntStatus=ObOpenObjectByPointer(Token,0, NULL, TOKEN_QUERY,
NULL,KernelMode, &tokenHandle );
ObDereferenceObject(Token);
if( !NT_SUCCESS( ntStatus )) {
KdPrint((“\nGetSID: Could not open process token: %x\n”,
ntStatus ));
return;
}

//
// Pull out the SID
//
ntStatus = NtQueryInformationToken( tokenHandle, TokenUser, NULL, 0,
&requiredLength );
if( ntStatus != STATUS_BUFFER_TOO_SMALL ) {

KdPrint((“\nGetSID: Error getting token information: %x\n”,
ntStatus));
ZwClose( tokenHandle );
return;
}
tokenInfoBuffer=(PTOKEN_USER) ExAllocatePool( NonPagedPool,
requiredLength );
if( tokenInfoBuffer ) {
ntStatus = NtQueryInformationToken( tokenHandle, TokenUser,
tokenInfoBuffer, requiredLength, &requiredLength );
}
if( !NT_SUCCESS( ntStatus ) || !tokenInfoBuffer ) {
KdPrint((“\nGetSID: Error getting token information: %x\n”,
ntStatus));
if( tokenInfoBuffer )
ExFreePool( tokenInfoBuffer );
ZwClose( tokenHandle );
return;
}
ZwClose( tokenHandle );

//
// Got it, now convert to text representation
//
//memset( sidStringBuffer, 0, sizeof(sidStringBuffer ));
//sidStringBuffer= ExAllocatePool(NonPagedPool, 512 );
//sidString->Buffer = (PWCHAR) sidStringBuffer;
//sidString->MaximumLength = sizeof(sidStringBuffer);
//RtlInitEmptyUnicodeString(sidString,sidStringBuffer,512);
ntStatus = RtlConvertSidToUnicodeString( sidString, tokenInfoBuffer->
User.Sid, FALSE );
sidString->Buffer[sidString->Length+1]=‘\0’;
KdPrint((“\nGetSID: sidString = %ws\n”,sidString->Buffer));
ExFreePool( tokenInfoBuffer );
if( !NT_SUCCESS( ntStatus )) {
KdPrint((“\nGetSID: Unable to convert SID to text: %x\n”,
ntStatus ));
return;
}

}

Your advice us solicited.

amitr0

Use IoGetRequestorProcess to obtain the process that originated the IRP

  • that tells you the process that originated the request.

What you seem to miss is that there’s the cache in this mix of
operations - both read ahead and write back are going to be done in
system process context. Thus, there is definitely no guarantee that
just because notepad opened the file that it will be the notepad process
performing the I/O operations.

The code you are using is going to give you the SID of the primary
process token, which isn’t going to be the remote client for CIFS
server. Since I don’t know what you’re trying to achieve here, I can’t
say if this is what you want or not. I’ve never tried to obtain the SID
using the approach you are using (I’ve always done it via the mechanism
described on OSRONLINE article -
http://www.osronline.com/article.cfm?id=50 which doesn’t quite fit your
scenario.)

Perhaps someone else on the list has done it along the lines you are
using and can provide you with further feedback.

Regards,

Tony

Tony Mason

Consulting Partner

OSR Open Systems Resources, Inc.

http://www.osr.com

Looking forward to seeing you at the next OSR File Systems class in
Boston, MA April 18-21, 2006.


From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of amitr0
Sent: Friday, April 07, 2006 4:43 AM
To: ntfsd redirect
Subject: Re: [ntfsd] getting SID of the User inside my FSFD

If you just want the SID of the current process, go ahead and get it
whenever you want.

I want the SID of the process that sent that particular IRP down to me.

That doesn’t mean it is the SID of the process that opened the file -
because that’s only guaranteed during IRP_MJ_CREATE and certain
IRP_MJ_SET_INFORMATION calls (rename and create hard link). If you
want the SID of the process that opened the file originally, store it
in your filter context or in a separate lookaside table keyed off the
FILE_OBJECT.

You mean to say that Notepad.exe opened file abcd.txt (which is very
large, > 32 Megs, say) and the multiple IRP_MJ_READs I see on the sysetm
from Notepad, might not return me the correct SID of the guy who has
launched Notepad? Why is it do? Yes, I did read the bit about the CIFS,
but still I need more clarification, if you could kindly tell me a bit
more in detail.

More over I also hav observed that the SID is not even fetched at times,
I cannot figure out why the token query functions return access
violation etc.

Here is the code I use to get the SID, is it worng? I don’t query the
current thread in this code.

void GetSID(PUNICODE_STRING sidString)
{
NTSTATUS ntStatus;
PVOID Token;
HANDLE tokenHandle;
PTOKEN_USER tokenInfoBuffer;
ULONG requiredLength;
// PCHAR sidStringBuffer[512];
PWCHAR sidStringBuffer;

sidStringBuffer= ExAllocatePool(NonPagedPool, 512 );
RtlInitEmptyUnicodeString

(sidString,sidStringBuffer,512);

Token=PsReferencePrimaryToken(PsGetCurrentProcess());
ntStatus=ObOpenObjectByPointer(Token,0, NULL, TOKEN_QUERY,
NULL,KernelMode, &tokenHandle );
ObDereferenceObject(Token);
if( !NT_SUCCESS( ntStatus )) {
KdPrint((“\nGetSID: Could not open process token: %x\n”,
ntStatus ));
return;
}

//
// Pull out the SID
//
ntStatus = NtQueryInformationToken( tokenHandle, TokenUser, NULL, 0,
&requiredLength );
if( ntStatus != STATUS_BUFFER_TOO_SMALL ) {

KdPrint((“\nGetSID: Error getting token information: %x\n”,
ntStatus));
ZwClose( tokenHandle );
return;
}
tokenInfoBuffer=(PTOKEN_USER) ExAllocatePool( NonPagedPool,
requiredLength );
if( tokenInfoBuffer ) {
ntStatus = NtQueryInformationToken( tokenHandle, TokenUser,
tokenInfoBuffer, requiredLength, &requiredLength );
}
if( !NT_SUCCESS( ntStatus ) || !tokenInfoBuffer ) {
KdPrint((“\nGetSID: Error getting token information: %x\n”,
ntStatus));
if( tokenInfoBuffer )
ExFreePool( tokenInfoBuffer );
ZwClose( tokenHandle );
return;
}
ZwClose( tokenHandle );

//
// Got it, now convert to text representation
//
//memset( sidStringBuffer, 0, sizeof(sidStringBuffer ));
//sidStringBuffer= ExAllocatePool(NonPagedPool, 512 );
//sidString->Buffer = (PWCHAR) sidStringBuffer;
//sidString->MaximumLength = sizeof(sidStringBuffer);
//RtlInitEmptyUnicodeString(sidString,sidStringBuffer,512);
ntStatus = RtlConvertSidToUnicodeString( sidString,
tokenInfoBuffer-> User.Sid, FALSE );
sidString->Buffer[sidString->Length+1]=‘\0’;
KdPrint((“\nGetSID: sidString = %ws\n”,sidString->Buffer));
ExFreePool( tokenInfoBuffer );
if( !NT_SUCCESS( ntStatus )) {
KdPrint((“\nGetSID: Unable to convert SID to text: %x\n”,
ntStatus ));
return;
}

}

Your advice us solicited.

amitr0
— Questions? First check the IFS FAQ at
https://www.osronline.com/article.cfm?id=17 You are currently subscribed
to ntfsd as: unknown lmsubst tag argument: ‘’ To unsubscribe send a
blank email to xxxxx@lists.osr.com

Hi all,

The code below generates a lot of access violations as STATUS CODES in the
marked lines, though it also retrieves the token at otehrs. Can some one
tell me as to why this happens.

void GetSID(PUNICODE_STRING sidString)
{
NTSTATUS ntStatus;
PVOID Token;
HANDLE tokenHandle;
PTOKEN_USER tokenInfoBuffer;
ULONG requiredLength;
// PCHAR sidStringBuffer[512];
PWCHAR sidStringBuffer;

sidStringBuffer= ExAllocatePool(NonPagedPool, 512 );
RtlInitEmptyUnicodeString
(sidString,sidStringBuffer,512);

Token=PsReferencePrimaryToken(PsGetCurrentProcess());
ntStatus=ObOpenObjectByPointer(Token,0, NULL, TOKEN_QUERY,
NULL,KernelMode, &tokenHandle );
ObDereferenceObject(Token);
if( !NT_SUCCESS( ntStatus )) {
KdPrint((“\nGetSID: Could not open process token: %x\n”,
ntStatus ));
return;
}

//
// Pull out the SID
//

/* ********************** THIS IS WHERE I GET A LOT OF ACCESS VIOLATIONS AS
STATUS CODE ******************** */

ntStatus = NtQueryInformationToken( tokenHandle, TokenUser, NULL, 0,
&requiredLength );

/* ********************** THIS IS WHERE I GET A LOT OF ACCESS VIOLATIONS AS
STATUS CODE ENDS HERE******************** */
if( ntStatus != STATUS_BUFFER_TOO_SMALL ) {

KdPrint((“\nGetSID: Error getting token information: %x\n”,
ntStatus));
ZwClose( tokenHandle );
return;
}
tokenInfoBuffer=(PTOKEN_USER) ExAllocatePool( NonPagedPool,
requiredLength );
if( tokenInfoBuffer ) {
ntStatus = NtQueryInformationToken( tokenHandle, TokenUser,
tokenInfoBuffer, requiredLength, &requiredLength );
}
if( !NT_SUCCESS( ntStatus ) || !tokenInfoBuffer ) {
KdPrint((“\nGetSID: Error getting token information: %x\n”,
ntStatus));
if( tokenInfoBuffer )
ExFreePool( tokenInfoBuffer );
ZwClose( tokenHandle );
return;
}
ZwClose( tokenHandle );

//
// Got it, now convert to text representation
//
//memset( sidStringBuffer, 0, sizeof(sidStringBuffer ));
//sidStringBuffer= ExAllocatePool(NonPagedPool, 512 );
//sidString->Buffer = (PWCHAR) sidStringBuffer;
//sidString->MaximumLength = sizeof(sidStringBuffer);
//RtlInitEmptyUnicodeString(sidString,sidStringBuffer,512);
ntStatus = RtlConvertSidToUnicodeString( sidString, tokenInfoBuffer->
User.Sid, FALSE );
sidString->Buffer[sidString->Length+1]=‘\0’;
KdPrint((“\nGetSID: sidString = %ws\n”,sidString->Buffer));
ExFreePool( tokenInfoBuffer );
if( !NT_SUCCESS( ntStatus )) {
KdPrint((“\nGetSID: Unable to convert SID to text: %x\n”,
ntStatus ));
return;
}

}

Tony,

COming back to your post, first of all thanks for taking out time to reply.
Well, here are my answers marked inline…

Use IoGetRequestorProcess to obtain the process that originated the IRP ?
that tells you the process that originated the request.

Yes, I have read about this Api (thanks to Matt Martin), and will try it out
also.

What you seem to miss is that there’s the cache in this mix of operations ?
both read ahead and write back are going to be done in >system process
context. Thus, there is definitely no guarantee that just because notepad
opened the file that it will be the notepad >process performing the I/O
operations.

No I didn’t miss the point. All I Meant was that, *if* Notepad is reading,
then I should get it’s process name and SID of the user. Ofcourse cahing
reads will be there as IRPs coming from System context.

The code you are using is going to give you the SID of the primary process
token, which isn’t going to be the remote client for CIFS >server. Since I
don’t know what you’re trying to achieve here, I can’t say if this is what
you want or not. I’ve never tried to obtain the SID >using the approach you
are using (I’ve always done it via the mechanism described on OSRONLINE
article - http://www.osronline.com>/article.cfm?id=50http:which
doesn’t quite fit your scenario.)

Yes, I have rad this article too. Infact the code I posted was heavily
borrowing from the same article.

Best regards,

amitr0</http:>

>Is it fundamentally wrong to query for the SID in dispatch routines other

than IRP_MJ_CREATE?

Yes. More so - even in MJ_CREATE, you should not query the current SID, but use
Parameters.Create.SecurityContext.

I did this in some code as early as in 2001, can raise this code to look how I
did this to describe the exact steps here. I remember creating a token handle
from the pointer stored in Parameters.Create.SecurityContext by
ObOpenObjectByPointer, then using ZwQueryInformationToken.

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

>I did this in some code as early as in 2001, can raise this code to look
how I

did this to describe the exact steps here.

It would be of great help.

Use the following code … I actually had to figure this one out myself a few days ago. Note that you have to do this processing the IRP_MJ_CREATE request.

PIO_SECURITY_CONTEXT SecurityContext = IrpSp->Parameters.Create.SecurityContext;
NTSTATUS Status = STATUS_SUCCESS;
ULONG SIDLength;
TOKEN_OWNER *Towner;
PACCESS_TOKEN Token;
PSID sid;

Token = SeQuerySubjectContextToken((&(SecurityContext->AccessState->SubjectSecurityContext)));
Status = SeQueryInformationToken(Token, TokenOwner, &Towner);
if (Status == STATUS_SUCCESS) {
sid = Towner->Owner;
if (RtlValidSid(sid)) {
SIDLength = RtlLengthSid(sid);

}
// Save the sid and free the owner token
ExFreePool(Towner);
}

-Ilya.

-------------- Original message --------------
From: amitr0
>I did this in some code as early as in 2001, can raise this code to look how I
>did this to describe the exact steps here.

It would be of great help.

— Questions? First check the IFS FAQ at https://www.osronline.com/article.cfm?id=17 You are currently subscribed to ntfsd as: unknown lmsubst tag argument: ‘’ To unsubscribe send a blank email to xxxxx@lists.osr.com

>It would be of great help.

  1. Take Parameters.Create.SecurityContext

  2. Check for SecurityContext->AccessState->SubjectSecurityContext.ClientToken,
    if non-NULL - take it. If NULL, take
    SecurityContext->AccessState->SubjectSecurityContext.PrimaryToken, this will be
    TokenPtr

  3. Call ObOpenObjectByPointer(TokenPtr, OBJ_CASE_INSENSITIVE, NULL,
    TOKEN_QUERY, NULL, KernelMode, &hToken);

  4. Call ZwQueryInformationToken(hToken, TokenUser, NULL, 0, &RetLen), this will
    provide you with the length

  5. Allocate the space

  6. Call ZwQueryInformationToken(hToken, TokenUser, Buf, RetLen, &RetLen) - with
    the same RetLen. This fills the buffer with the SID_AND_ATTRIBUTES structure
    for the current user.

  7. ZwClose the handle returned by ObOpenObjectByPointer

You can write the MySeQueryUserIdToken function and put steps 3 to 7 there.

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

Maxim,

thanks for the helping hints, however, it is exactly what I am using, except
the first few lines to acquire the token, because I don’t call it *ONLY* in
the context of CREATE, my requirements are to get th SID of the process who
generated the current IRP thats all.

BTW, my ObOpenObjectByPointer call looks like
ObOpenObjectByPointer(Token,0, NULL, TOKEN_QUERY, NULL,KernelMode,
&tokenHandle );

I couldn’t find anythig like OBJ_CASE_INSENSITIVE in the DDK docs, is it
undocumented? The above line of code I borrowed from somewhere in OSR, I
cannot remember where from though. Is zero equiv to OBJ_CASE_INSENSITIVE?

Some senior developers have commented that It is not possible to get the sid
for every type of IRP generated by the system. This is exactly what is
happening, the function works fine and even returns SID for certain IRPs,
but returns nothing for other IRPS, is this a bug in my code, or is it how
Windows is designed?

void CAGetSID(PUNICODE_STRING sidString, PIRP Irp)
{
NTSTATUS ntStatus;
PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation(Irp);
PVOID Token;
HANDLE tokenHandle;
PTOKEN_USER tokenInfoBuffer;
ULONG requiredLength;
PWCHAR sidStringBuffer;

sidStringBuffer= ExAllocatePool(NonPagedPool, 512 );
RtlInitEmptyUnicodeString(sidString,sidStringBuffer,512);

Token=PsReferencePrimaryToken(PsGetCurrentProcess());
ntStatus=ObOpenObjectByPointer(Token,0, NULL, TOKEN_QUERY,
NULL,KernelMode, &tokenHandle );
if( !NT_SUCCESS( ntStatus )) {
KdPrint((“\nCAGetSID: ObOpenObjectByPointer returned status:
%x\n”, ntStatus ));
return;
}
ObDereferenceObject(Token);

//
// Pull out the SID
//
ntStatus = NtQueryInformationToken( tokenHandle, TokenUser, NULL, 0,
&requiredLength );
if( ntStatus != STATUS_BUFFER_TOO_SMALL ) {

KdPrint((“\nCAGetSID: NtQueryInformationToken returned status:
%x\n”, ntStatus));
ZwClose( tokenHandle );
return;
}
tokenInfoBuffer=(PTOKEN_USER) ExAllocatePool( NonPagedPool,
requiredLength );
if( tokenInfoBuffer ) {
ntStatus = NtQueryInformationToken( tokenHandle, TokenUser,
tokenInfoBuffer, requiredLength, &requiredLength );
if( !NT_SUCCESS( ntStatus )) {
if( tokenInfoBuffer )
ExFreePool( tokenInfoBuffer );
ZwClose( tokenHandle );
KdPrint((“\nCAGetSID: NtQueryInformationToken returned
status: %x, while fetching tokenBuffer\n”, ntStatus ));
return;
}
}
if( !NT_SUCCESS( ntStatus ) || !tokenInfoBuffer ) {
KdPrint((“\nCAGetSID: Error getting token information: %x\n”,
ntStatus));
if( tokenInfoBuffer )
ExFreePool( tokenInfoBuffer );
ZwClose( tokenHandle );
return;
}
ZwClose( tokenHandle );

//
// Got it, now convert to text representation

ntStatus = RtlConvertSidToUnicodeString( sidString, tokenInfoBuffer->
User.Sid, FALSE );
sidString->Buffer[sidString->Length+1]=‘\0’;
KdPrint((“\nCAGetSID: sidString = %ws\n”,sidString->Buffer));
ExFreePool( tokenInfoBuffer );
if( !NT_SUCCESS( ntStatus )) {
KdPrint((“\nCAGetSID: Unable to convert SID to text: %x\n”,
ntStatus ));
return;
}

}

Ilya

thank you also fro the snippet, let me see if I can customize it to my
requirements…

amitr0

In the IFS KIT there is a table of thread contexts and irql for file system
dispatch points. Please refer to this table at this point in time. For those
where the thread context is arbitrary there is no sense in the sid of the
process who generated the current irp.

You will find OBJ_CASE_INSENSITIVE described under
InitializeObjectAttributes; it doesnt come much more basic “i cant be
bothered to look i will just post ntfsd” than this case.

Now you have said that it is your requirement to get the sid of the process
who generated the current irp and you have heard more than once that you can
not deliver on this requirement. It appears that you need to work more on
your broken requirements and less on your broken code :wink:

Good luck
Lyndon

“amitr0” wrote in message news:xxxxx@ntfsd…
Maxim,

thanks for the helping hints, however, it is exactly what I am using, except
the first few lines to acquire the token, because I don’t call it ONLY in
the context of CREATE, my requirements are to get th SID of the process who
generated the current IRP thats all.

BTW, my ObOpenObjectByPointer call looks like
ObOpenObjectByPointer(Token,0, NULL, TOKEN_QUERY, NULL,KernelMode,
&tokenHandle );

I couldn’t find anythig like OBJ_CASE_INSENSITIVE in the DDK docs, is it
undocumented? The above line of code I borrowed from somewhere in OSR, I
cannot remember where from though. Is zero equiv to OBJ_CASE_INSENSITIVE?

Some senior developers have commented that It is not possible to get the sid
for every type of IRP generated by the system. This is exactly what is
happening, the function works fine and even returns SID for certain IRPs,
but returns nothing for other IRPS, is this a bug in my code, or is it how
Windows is designed?

void CAGetSID(PUNICODE_STRING sidString, PIRP Irp)
{
NTSTATUS ntStatus;
PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation(Irp);
PVOID Token;
HANDLE tokenHandle;
PTOKEN_USER tokenInfoBuffer;
ULONG requiredLength;
PWCHAR sidStringBuffer;

sidStringBuffer= ExAllocatePool(NonPagedPool, 512 );
RtlInitEmptyUnicodeString(sidString,sidStringBuffer,512);

Token=PsReferencePrimaryToken(PsGetCurrentProcess());
ntStatus=ObOpenObjectByPointer(Token,0, NULL, TOKEN_QUERY,
NULL,KernelMode, &tokenHandle );
if( !NT_SUCCESS( ntStatus )) {
KdPrint((“\nCAGetSID: ObOpenObjectByPointer returned status:
%x\n”, ntStatus ));
return;
}
ObDereferenceObject(Token);

//
// Pull out the SID
//
ntStatus = NtQueryInformationToken( tokenHandle, TokenUser, NULL, 0,
&requiredLength );
if( ntStatus != STATUS_BUFFER_TOO_SMALL ) {

KdPrint((“\nCAGetSID: NtQueryInformationToken returned status:
%x\n”, ntStatus));
ZwClose( tokenHandle );
return;
}
tokenInfoBuffer=(PTOKEN_USER) ExAllocatePool( NonPagedPool,
requiredLength );
if( tokenInfoBuffer ) {
ntStatus = NtQueryInformationToken( tokenHandle, TokenUser,
tokenInfoBuffer, requiredLength, &requiredLength );
if( !NT_SUCCESS( ntStatus )) {
if( tokenInfoBuffer )
ExFreePool( tokenInfoBuffer );
ZwClose( tokenHandle );
KdPrint((“\nCAGetSID: NtQueryInformationToken returned
status: %x, while fetching tokenBuffer\n”, ntStatus ));
return;
}
}
if( !NT_SUCCESS( ntStatus ) || !tokenInfoBuffer ) {
KdPrint((“\nCAGetSID: Error getting token information: %x\n”,
ntStatus));
if( tokenInfoBuffer )
ExFreePool( tokenInfoBuffer );
ZwClose( tokenHandle );
return;
}
ZwClose( tokenHandle );

//
// Got it, now convert to text representation

ntStatus = RtlConvertSidToUnicodeString( sidString,
tokenInfoBuffer->User.Sid, FALSE );
sidString->Buffer[sidString->Length+1]=‘\0’;
KdPrint((“\nCAGetSID: sidString = %ws\n”,sidString->Buffer));
ExFreePool( tokenInfoBuffer );
if( !NT_SUCCESS( ntStatus )) {
KdPrint((“\nCAGetSID: Unable to convert SID to text: %x\n”,
ntStatus ));
return;
}

}

Ilya

thank you also fro the snippet, let me see if I can customize it to my
requirements…

>Some senior developers have commented that It is not possible to get the sid

for every type of IRP generated by the system. This is exactly what is
happening, the function works fine and even returns SID for certain IRPs,
but returns nothing for other IRPS, is this a bug in my code, or is it how
Windows is designed?

This is by design. All security checks are done in CREATE path. After the
handle is created, SID is no more checked.

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com