Windows: AFSInvalidateObject can overwrite input param
[openafs.git] / src / WINNT / afsrdr / kernel / fs / AFSProcessSupport.cpp
1 /*
2  * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
3  * Copyright (c) 2009, 2010, 2011 Your File System, Inc.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * - Redistributions of source code must retain the above copyright notice,
11  *   this list of conditions and the following disclaimer.
12  * - Redistributions in binary form must reproduce the above copyright
13  *   notice,
14  *   this list of conditions and the following disclaimer in the
15  *   documentation
16  *   and/or other materials provided with the distribution.
17  * - Neither the names of Kernel Drivers, LLC and Your File System, Inc.
18  *   nor the names of their contributors may be used to endorse or promote
19  *   products derived from this software without specific prior written
20  *   permission from Kernel Drivers, LLC and Your File System, Inc.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
26  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  */
34
35 //
36 // File: AFSProcessSupport.cpp
37 //
38
39 #include "AFSCommon.h"
40
41 void
42 AFSProcessNotify( IN HANDLE  ParentId,
43                   IN HANDLE  ProcessId,
44                   IN BOOLEAN  Create)
45 {
46
47     //
48     // If this is a create notification then update our tree, otherwise remove the
49     // entry
50     //
51
52     if( Create)
53     {
54
55         AFSProcessCreate( ParentId,
56                           ProcessId,
57                           PsGetCurrentProcessId(),
58                           PsGetCurrentThreadId());
59     }
60     else
61     {
62
63         AFSProcessDestroy( ProcessId);
64     }
65
66     return;
67 }
68
69 void
70 AFSProcessNotifyEx( IN OUT PEPROCESS Process,
71                     IN     HANDLE ProcessId,
72                     IN OUT PPS_CREATE_NOTIFY_INFO CreateInfo)
73 {
74
75     if ( CreateInfo)
76     {
77
78         AFSProcessCreate( CreateInfo->ParentProcessId,
79                           ProcessId,
80                           CreateInfo->CreatingThreadId.UniqueProcess,
81                           CreateInfo->CreatingThreadId.UniqueThread);
82     }
83     else
84     {
85
86         AFSProcessDestroy( ProcessId);
87     }
88 }
89
90
91 void
92 AFSProcessCreate( IN HANDLE ParentId,
93                   IN HANDLE ProcessId,
94                   IN HANDLE CreatingProcessId,
95                   IN HANDLE CreatingThreadId)
96 {
97     NTSTATUS ntStatus = STATUS_SUCCESS;
98     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
99     AFSProcessCB *pProcessCB = NULL;
100
101     __Enter
102     {
103
104         AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
105                       AFS_TRACE_LEVEL_VERBOSE,
106                       "AFSProcessCreate Acquiring Control ProcessTree.TreeLock lock %08lX EXCL %08lX\n",
107                       pDeviceExt->Specific.Control.ProcessTree.TreeLock,
108                       PsGetCurrentThread());
109
110         AFSAcquireExcl( pDeviceExt->Specific.Control.ProcessTree.TreeLock,
111                         TRUE);
112
113         AFSDbgLogMsg( AFS_SUBSYSTEM_PROCESS_PROCESSING,
114                       AFS_TRACE_LEVEL_VERBOSE,
115                       "AFSProcessCreate Parent %08lX Process %08lX %08lX\n",
116                       ParentId,
117                       ProcessId,
118                       PsGetCurrentThread());
119
120         pProcessCB = AFSInitializeProcessCB( (ULONGLONG)ParentId,
121                                              (ULONGLONG)ProcessId);
122
123         if( pProcessCB != NULL)
124         {
125
126             pProcessCB->CreatingProcessId = (ULONGLONG)CreatingProcessId;
127
128             pProcessCB->CreatingThreadId = (ULONGLONG)CreatingThreadId;
129         }
130
131         //
132         // Now assign the AuthGroup ACE
133         //
134
135         AFSValidateProcessEntry( ProcessId);
136
137         AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock);
138     }
139
140     return;
141 }
142
143 void
144 AFSProcessDestroy( IN HANDLE ProcessId)
145 {
146
147     NTSTATUS ntStatus = STATUS_SUCCESS;
148     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
149     AFSProcessCB *pProcessCB = NULL, *pParentProcessCB = NULL;
150     AFSProcessAuthGroupCB *pProcessAuthGroup = NULL, *pLastAuthGroup = NULL;
151     AFSThreadCB *pThreadCB = NULL, *pNextThreadCB = NULL;
152
153     __Enter
154     {
155
156         AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
157                       AFS_TRACE_LEVEL_VERBOSE,
158                       "AFSProcessDestroy Acquiring Control ProcessTree.TreeLock lock %08lX EXCL %08lX\n",
159                       pDeviceExt->Specific.Control.ProcessTree.TreeLock,
160                       PsGetCurrentThreadId());
161
162         AFSAcquireExcl( pDeviceExt->Specific.Control.ProcessTree.TreeLock,
163                         TRUE);
164         //
165         // It's a remove so pull the entry
166         //
167
168         AFSDbgLogMsg( AFS_SUBSYSTEM_PROCESS_PROCESSING,
169                       AFS_TRACE_LEVEL_VERBOSE,
170                       "AFSProcessDestroy Process %08lX %08lX\n",
171                       ProcessId,
172                       PsGetCurrentThread());
173
174         ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.ProcessTree.TreeHead,
175                                        (ULONGLONG)ProcessId,
176                                        (AFSBTreeEntry **)&pProcessCB);
177
178         if( NT_SUCCESS( ntStatus) &&
179             pProcessCB != NULL)
180         {
181
182             AFSRemoveHashEntry( &pDeviceExt->Specific.Control.ProcessTree.TreeHead,
183                                 (AFSBTreeEntry *)pProcessCB);
184
185             pProcessAuthGroup = pProcessCB->AuthGroupList;
186
187             while( pProcessAuthGroup != NULL)
188             {
189
190                 pLastAuthGroup = pProcessAuthGroup->Next;
191
192                 ExFreePool( pProcessAuthGroup);
193
194                 pProcessAuthGroup = pLastAuthGroup;
195             }
196
197             pThreadCB = pProcessCB->ThreadList;
198
199             while( pThreadCB != NULL)
200             {
201
202                 pNextThreadCB = pThreadCB->Next;
203
204                 ExFreePool( pThreadCB);
205
206                 pThreadCB = pNextThreadCB;
207             }
208
209             ExDeleteResourceLite( &pProcessCB->Lock);
210
211             ExFreePool( pProcessCB);
212         }
213         else
214         {
215             AFSDbgLogMsg( AFS_SUBSYSTEM_PROCESS_PROCESSING,
216                           AFS_TRACE_LEVEL_WARNING,
217                           "AFSProcessDestroy Process %08lX not found in ProcessTree Status %08lX %08lX\n",
218                           ProcessId,
219                           ntStatus,
220                           PsGetCurrentThread());
221         }
222
223         AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock);
224     }
225
226     return;
227 }
228
229 //
230 // AFSValidateProcessEntry verifies the consistency of the current process
231 // entry which includes assigning an authentication group ACE if one is not
232 // present.  A reference to the active authentication group GUID is returned.
233 //
234
235 GUID *
236 AFSValidateProcessEntry( IN HANDLE ProcessId)
237 {
238
239     GUID *pAuthGroup = NULL;
240     NTSTATUS ntStatus = STATUS_SUCCESS;
241     AFSProcessCB *pProcessCB = NULL, *pParentProcessCB = NULL;
242     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
243     ULONGLONG ullProcessID = (ULONGLONG)ProcessId;
244     UNICODE_STRING uniSIDString;
245     ULONG ulSIDHash = 0;
246     AFSSIDEntryCB *pSIDEntryCB = NULL;
247     ULONG ulSessionId = 0;
248     ULONGLONG ullTableHash = 0;
249     AFSThreadCB *pParentThreadCB = NULL;
250     UNICODE_STRING uniGUID;
251     BOOLEAN bImpersonation = FALSE;
252
253     __Enter
254     {
255
256         AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
257                       AFS_TRACE_LEVEL_VERBOSE,
258                       "AFSValidateProcessEntry Acquiring Control ProcessTree.TreeLock lock %08lX SHARED %08lX\n",
259                       pDeviceExt->Specific.Control.ProcessTree.TreeLock,
260                       PsGetCurrentThread());
261
262         uniSIDString.Length = 0;
263         uniSIDString.MaximumLength = 0;
264         uniSIDString.Buffer = NULL;
265
266         AFSAcquireShared( pDeviceExt->Specific.Control.ProcessTree.TreeLock,
267                           TRUE);
268
269         AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
270                       AFS_TRACE_LEVEL_VERBOSE,
271                       "%s Entry for ProcessID %I64X\n",
272                       __FUNCTION__,
273                       ullProcessID);
274
275         ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.ProcessTree.TreeHead,
276                                        ullProcessID,
277                                        (AFSBTreeEntry **)&pProcessCB);
278
279         if( !NT_SUCCESS( ntStatus) ||
280             pProcessCB == NULL)
281         {
282
283             AFSProcessCreate( 0,
284                               ProcessId,
285                               0,
286                               0);
287         }
288
289         if( !NT_SUCCESS( ntStatus) ||
290             pProcessCB == NULL)
291         {
292
293             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
294                           AFS_TRACE_LEVEL_ERROR,
295                           "%s Failed to locate process entry for ProcessID %I64X\n",
296                           __FUNCTION__,
297                           ullProcessID);
298
299             AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock);
300
301             try_return( ntStatus = STATUS_UNSUCCESSFUL);
302         }
303
304         //
305         // Locate and lock the ParentProcessCB if we have one
306         //
307
308         if( pProcessCB->ParentProcessId != 0)
309         {
310
311             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
312                           AFS_TRACE_LEVEL_VERBOSE,
313                           "%s Locating process entry for Parent ProcessID %I64X\n",
314                           __FUNCTION__,
315                           pProcessCB->ParentProcessId);
316
317             ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.ProcessTree.TreeHead,
318                                            (ULONGLONG)pProcessCB->ParentProcessId,
319                                            (AFSBTreeEntry **)&pParentProcessCB);
320
321             if( NT_SUCCESS( ntStatus) &&
322                 pParentProcessCB != NULL)
323             {
324                 AFSAcquireExcl( &pParentProcessCB->Lock,
325                                 TRUE);
326
327                 AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
328                               AFS_TRACE_LEVEL_VERBOSE,
329                               "%s Located process entry for Parent ProcessID %I64X\n",
330                               __FUNCTION__,
331                               pProcessCB->ParentProcessId);
332             }
333         }
334         else
335         {
336
337             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
338                           AFS_TRACE_LEVEL_VERBOSE,
339                           "%s No parent ID for ProcessID %I64X\n",
340                           __FUNCTION__,
341                           ullProcessID);
342         }
343
344         AFSAcquireExcl( &pProcessCB->Lock,
345                         TRUE);
346
347         AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock);
348
349         //
350         // Locate the SID for the caller
351         //
352
353         ntStatus = AFSGetCallerSID( &uniSIDString, &bImpersonation);
354
355         if( !NT_SUCCESS( ntStatus))
356         {
357
358             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
359                           AFS_TRACE_LEVEL_ERROR,
360                           "%s Failed to locate callers SID for ProcessID %I64X\n",
361                           __FUNCTION__,
362                           ullProcessID);
363
364             try_return( ntStatus);
365         }
366
367         ulSessionId = AFSGetSessionId( (HANDLE)ullProcessID, &bImpersonation);
368
369         if( ulSessionId == (ULONG)-1)
370         {
371
372             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
373                           AFS_TRACE_LEVEL_ERROR,
374                           "%s Failed to retrieve session ID for ProcessID %I64X\n",
375                           __FUNCTION__,
376                           ullProcessID);
377
378             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
379         }
380
381         AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
382                       AFS_TRACE_LEVEL_VERBOSE,
383                       "%s Retrieved callers SID %wZ for ProcessID %I64X Session %08lX\n",
384                       __FUNCTION__,
385                       &uniSIDString,
386                       ullProcessID,
387                       ulSessionId);
388
389         //
390         // If there is an Auth Group for the current process,
391         // our job is finished.
392         //
393
394         if ( bImpersonation == FALSE)
395         {
396             pAuthGroup = pProcessCB->ActiveAuthGroup;
397
398             if( pAuthGroup != NULL &&
399                 !AFSIsNoPAGAuthGroup( pAuthGroup))
400             {
401
402                 uniGUID.Buffer = NULL;
403
404                 RtlStringFromGUID( *pAuthGroup,
405                                    &uniGUID);
406
407                 AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
408                               AFS_TRACE_LEVEL_VERBOSE,
409                               "%s Located valid AuthGroup GUID %wZ for SID %wZ ProcessID %I64X Session %08lX\n",
410                               __FUNCTION__,
411                               &uniGUID,
412                               &uniSIDString,
413                               ullProcessID,
414                               ulSessionId);
415
416                 if( uniGUID.Buffer != NULL)
417                 {
418                     RtlFreeUnicodeString( &uniGUID);
419                 }
420
421                 try_return( ntStatus = STATUS_SUCCESS);
422             }
423
424             //
425             // The current process does not yet have an Auth Group.  Try to inherit
426             // one from the parent process thread that created this process.
427             //
428
429             if( pParentProcessCB != NULL)
430             {
431
432                 for ( pParentThreadCB = pParentProcessCB->ThreadList;
433                       pParentThreadCB != NULL;
434                       pParentThreadCB = pParentThreadCB->Next)
435                 {
436
437                     if( pParentThreadCB->ThreadId == pProcessCB->CreatingThreadId)
438                     {
439                         break;
440                     }
441                 }
442
443                 //
444                 // If the creating thread was found and it has a thread specific
445                 // Auth Group, use that even if it is the No PAG
446                 //
447
448                 if( pParentThreadCB != NULL &&
449                     pParentThreadCB->ActiveAuthGroup != NULL &&
450                     !AFSIsNoPAGAuthGroup( pParentThreadCB->ActiveAuthGroup))
451                 {
452                     pProcessCB->ActiveAuthGroup = pParentThreadCB->ActiveAuthGroup;
453
454                     uniGUID.Buffer = NULL;
455
456                     RtlStringFromGUID( *(pProcessCB->ActiveAuthGroup),
457                                        &uniGUID);
458
459                     AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
460                                   AFS_TRACE_LEVEL_VERBOSE,
461                                   "%s PID %08lX Session %08lX inherited Active AuthGroup %wZ from thread %I64X\n",
462                                   __FUNCTION__,
463                                   ullProcessID,
464                                   ulSessionId,
465                                   &uniGUID,
466                                   pParentThreadCB->ThreadId);
467
468                     if( uniGUID.Buffer != NULL)
469                     {
470                         RtlFreeUnicodeString( &uniGUID);
471                     }
472                 }
473
474                 //
475                 // If the parent thread was not found or does not have an auth group
476                 //
477
478                 else if( pParentProcessCB->ActiveAuthGroup != NULL &&
479                          !AFSIsNoPAGAuthGroup( pParentProcessCB->ActiveAuthGroup))
480                 {
481                     pProcessCB->ActiveAuthGroup = pParentProcessCB->ActiveAuthGroup;
482
483                     uniGUID.Buffer = NULL;
484
485                     RtlStringFromGUID( *(pProcessCB->ActiveAuthGroup),
486                                        &uniGUID);
487
488                     AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
489                                   AFS_TRACE_LEVEL_VERBOSE,
490                                   "%s PID %08lX Session %08lX inherited Active AuthGroup %wZ from parent PID %I64X\n",
491                                   __FUNCTION__,
492                                   ullProcessID,
493                                   ulSessionId,
494                                   &uniGUID,
495                                   pParentProcessCB->TreeEntry.HashIndex);
496
497                     if( uniGUID.Buffer != NULL)
498                     {
499                         RtlFreeUnicodeString( &uniGUID);
500                     }
501                 }
502
503                 //
504                 // If an Auth Group was inherited, set it to be the active group
505                 //
506
507                 if( pProcessCB->ActiveAuthGroup != NULL &&
508                     !AFSIsNoPAGAuthGroup( pParentProcessCB->ActiveAuthGroup))
509                 {
510                     pAuthGroup = pProcessCB->ActiveAuthGroup;
511
512                     uniGUID.Buffer = NULL;
513
514                     RtlStringFromGUID( *(pProcessCB->ActiveAuthGroup),
515                                        &uniGUID);
516
517                     AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
518                                   AFS_TRACE_LEVEL_VERBOSE,
519                                   "%s Returning(1) Active AuthGroup %wZ for SID %wZ PID %I64X Session %08lX\n",
520                                   __FUNCTION__,
521                                   &uniGUID,
522                                   &uniSIDString,
523                                   ullProcessID,
524                                   ulSessionId);
525
526                     if( uniGUID.Buffer != NULL)
527                     {
528                         RtlFreeUnicodeString( &uniGUID);
529                     }
530
531                     try_return( ntStatus);
532                 }
533             }
534         }
535
536         //
537         // If no Auth Group was inherited, assign one based upon the Session and SID
538         //
539
540         ntStatus = RtlHashUnicodeString( &uniSIDString,
541                                          TRUE,
542                                          HASH_STRING_ALGORITHM_DEFAULT,
543                                          &ulSIDHash);
544
545         if( !NT_SUCCESS( ntStatus))
546         {
547
548             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
549                           AFS_TRACE_LEVEL_ERROR,
550                           "%s Failed to hash SID %wZ for PID %I64X Session %08lX Status %08lX\n",
551                           __FUNCTION__,
552                           &uniSIDString,
553                           ullProcessID,
554                           ulSessionId,
555                           ntStatus);
556
557             try_return( ntStatus);
558         }
559
560         ullTableHash = ( ((ULONGLONG)ulSessionId << 32) | ulSIDHash);
561
562         AFSAcquireShared( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock,
563                           TRUE);
564
565         ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.AuthGroupTree.TreeHead,
566                                        (ULONGLONG)ullTableHash,
567                                        (AFSBTreeEntry **)&pSIDEntryCB);
568
569         if( !NT_SUCCESS( ntStatus) ||
570             pSIDEntryCB == NULL)
571         {
572
573             AFSReleaseResource( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock);
574
575             AFSAcquireExcl( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock,
576                             TRUE);
577
578             ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.AuthGroupTree.TreeHead,
579                                            (ULONGLONG)ullTableHash,
580                                            (AFSBTreeEntry **)&pSIDEntryCB);
581
582             if( !NT_SUCCESS( ntStatus) ||
583                 pSIDEntryCB == NULL)
584             {
585
586                 pSIDEntryCB = (AFSSIDEntryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
587                                                                          sizeof( AFSSIDEntryCB),
588                                                                          AFS_AG_ENTRY_CB_TAG);
589
590                 if( pSIDEntryCB == NULL)
591                 {
592
593                     AFSReleaseResource( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock);
594
595                     try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
596                 }
597
598                 RtlZeroMemory( pSIDEntryCB,
599                                sizeof( AFSSIDEntryCB));
600
601                 pSIDEntryCB->TreeEntry.HashIndex = (ULONGLONG)ullTableHash;
602
603                 while( ExUuidCreate( &pSIDEntryCB->AuthGroup) == STATUS_RETRY);
604
605                 uniGUID.Buffer = NULL;
606
607                 RtlStringFromGUID( pSIDEntryCB->AuthGroup,
608                                    &uniGUID);
609
610                 AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
611                               AFS_TRACE_LEVEL_VERBOSE,
612                               "%s  SID %wZ PID %I64X Session %08lX generated NEW AG %wZ\n",
613                               __FUNCTION__,
614                               &uniSIDString,
615                               ullProcessID,
616                               ulSessionId,
617                               &uniGUID);
618
619                 if( uniGUID.Buffer != NULL)
620                 {
621                     RtlFreeUnicodeString( &uniGUID);
622                 }
623
624                 if( pDeviceExt->Specific.Control.AuthGroupTree.TreeHead == NULL)
625                 {
626                     pDeviceExt->Specific.Control.AuthGroupTree.TreeHead = (AFSBTreeEntry *)pSIDEntryCB;
627                 }
628                 else
629                 {
630                     AFSInsertHashEntry( pDeviceExt->Specific.Control.AuthGroupTree.TreeHead,
631                                         &pSIDEntryCB->TreeEntry);
632                 }
633             }
634
635             AFSConvertToShared( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock);
636         }
637
638
639         AFSReleaseResource( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock);
640
641         //
642         // Store the auth group into the process cb
643         //
644
645         pProcessCB->ActiveAuthGroup = &pSIDEntryCB->AuthGroup;
646
647         uniGUID.Buffer = NULL;
648
649         RtlStringFromGUID( pSIDEntryCB->AuthGroup,
650                            &uniGUID);
651
652         AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
653                       AFS_TRACE_LEVEL_VERBOSE,
654                       "%s SID %wZ PID %I64X Session %08lX assigned AG %wZ\n",
655                       __FUNCTION__,
656                       &uniSIDString,
657                       ullProcessID,
658                       ulSessionId,
659                       &uniGUID);
660
661         if( uniGUID.Buffer != NULL)
662         {
663             RtlFreeUnicodeString( &uniGUID);
664         }
665
666         //
667         // Set the AFS_PROCESS_LOCAL_SYSTEM_AUTH flag if the process SID
668         // is LOCAL_SYSTEM
669         //
670
671         if( AFSIsLocalSystemSID( &uniSIDString))
672         {
673             SetFlag( pProcessCB->Flags, AFS_PROCESS_LOCAL_SYSTEM_AUTH);
674
675             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
676                           AFS_TRACE_LEVEL_VERBOSE,
677                           "%s Setting PID %I64X Session %08lX with LOCAL SYSTEM AUTHORITY\n",
678                           __FUNCTION__,
679                           ullProcessID,
680                           ulSessionId);
681         }
682
683         //
684         // Return the auth group
685         //
686
687         pAuthGroup = pProcessCB->ActiveAuthGroup;
688
689         uniGUID.Buffer = NULL;
690
691         RtlStringFromGUID( *(pProcessCB->ActiveAuthGroup),
692                            &uniGUID);
693
694         AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
695                       AFS_TRACE_LEVEL_VERBOSE,
696                       "%s Returning(2) Active AuthGroup %wZ for SID %wZ PID %I64X Session %08lX\n",
697                       __FUNCTION__,
698                       &uniGUID,
699                       &uniSIDString,
700                       ullProcessID,
701                       ulSessionId);
702
703         if( uniGUID.Buffer != NULL)
704         {
705             RtlFreeUnicodeString( &uniGUID);
706         }
707
708 try_exit:
709
710         if( pProcessCB != NULL)
711         {
712
713             if( bImpersonation == FALSE &&
714                 !BooleanFlagOn( pProcessCB->Flags, AFS_PROCESS_FLAG_ACE_SET) &&
715                 NT_SUCCESS( ntStatus))
716             {
717                 ntStatus = AFSProcessSetProcessDacl( pProcessCB);
718
719                 if( !NT_SUCCESS( ntStatus))
720                 {
721                     pAuthGroup = NULL;
722                 }
723                 else
724                 {
725                     SetFlag( pProcessCB->Flags, AFS_PROCESS_FLAG_ACE_SET);
726                 }
727             }
728
729             AFSReleaseResource( &pProcessCB->Lock);
730         }
731
732         if( pParentProcessCB != NULL)
733         {
734             AFSReleaseResource( &pParentProcessCB->Lock);
735         }
736
737         if( uniSIDString.Length > 0)
738         {
739             RtlFreeUnicodeString( &uniSIDString);
740         }
741     }
742
743     return pAuthGroup;
744 }
745
746 BOOLEAN
747 AFSIs64BitProcess( IN ULONGLONG ProcessId)
748 {
749
750     NTSTATUS ntStatus = STATUS_SUCCESS;
751     BOOLEAN bIs64Bit = FALSE;
752     AFSProcessCB *pProcessCB = NULL;
753     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
754
755     __Enter
756     {
757
758         AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
759                       AFS_TRACE_LEVEL_VERBOSE,
760                       "AFSIs64BitProcess Acquiring Control ProcessTree.TreeLock lock %08lX SHARED %08lX\n",
761                       pDeviceExt->Specific.Control.ProcessTree.TreeLock,
762                       PsGetCurrentThread());
763
764         AFSAcquireShared( pDeviceExt->Specific.Control.ProcessTree.TreeLock,
765                           TRUE);
766
767         ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.ProcessTree.TreeHead,
768                                        (ULONGLONG)ProcessId,
769                                        (AFSBTreeEntry **)&pProcessCB);
770
771         if( pProcessCB != NULL)
772         {
773             bIs64Bit = BooleanFlagOn( pProcessCB->Flags, AFS_PROCESS_FLAG_IS_64BIT);
774         }
775
776         AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock);
777     }
778
779     return bIs64Bit;
780 }
781
782 AFSProcessCB *
783 AFSInitializeProcessCB( IN ULONGLONG ParentProcessId,
784                         IN ULONGLONG ProcessId)
785 {
786
787     AFSProcessCB *pProcessCB = NULL;
788     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
789
790     __Enter
791     {
792
793         pProcessCB = (AFSProcessCB *)AFSExAllocatePoolWithTag( NonPagedPool,
794                                                                sizeof( AFSProcessCB),
795                                                                AFS_PROCESS_CB_TAG);
796
797         if( pProcessCB == NULL)
798         {
799             try_return( pProcessCB);
800         }
801
802         RtlZeroMemory( pProcessCB,
803                        sizeof( AFSProcessCB));
804
805         pProcessCB->TreeEntry.HashIndex = (ULONGLONG)ProcessId;
806
807         pProcessCB->ParentProcessId = (ULONGLONG)ParentProcessId;
808
809 #if defined(_WIN64)
810
811         if( !IoIs32bitProcess( NULL))
812         {
813             SetFlag( pProcessCB->Flags, AFS_PROCESS_FLAG_IS_64BIT);
814         }
815
816 #endif
817
818         if( pDeviceExt->Specific.Control.ProcessTree.TreeHead == NULL)
819         {
820             pDeviceExt->Specific.Control.ProcessTree.TreeHead = (AFSBTreeEntry *)pProcessCB;
821         }
822         else
823         {
824             AFSInsertHashEntry( pDeviceExt->Specific.Control.ProcessTree.TreeHead,
825                                 &pProcessCB->TreeEntry);
826         }
827
828         ExInitializeResourceLite( &pProcessCB->Lock);
829
830         pProcessCB->ActiveAuthGroup = &AFSNoPAGAuthGroup;
831
832 try_exit:
833
834         NOTHING;
835     }
836
837     return pProcessCB;
838 }
839
840 AFSThreadCB *
841 AFSInitializeThreadCB( IN AFSProcessCB *ProcessCB,
842                        IN ULONGLONG ThreadId)
843 {
844
845     AFSThreadCB *pThreadCB = NULL, *pCurrentThreadCB = NULL;
846
847     __Enter
848     {
849
850         pThreadCB = (AFSThreadCB *)AFSExAllocatePoolWithTag( NonPagedPool,
851                                                              sizeof( AFSThreadCB),
852                                                              AFS_PROCESS_CB_TAG);
853
854         if( pThreadCB == NULL)
855         {
856             try_return( pThreadCB);
857         }
858
859         RtlZeroMemory( pThreadCB,
860                        sizeof( AFSThreadCB));
861
862         pThreadCB->ThreadId = ThreadId;
863
864         if( ProcessCB->ThreadList == NULL)
865         {
866             ProcessCB->ThreadList = pThreadCB;
867         }
868         else
869         {
870
871             pCurrentThreadCB = ProcessCB->ThreadList;
872
873             while( pCurrentThreadCB != NULL)
874             {
875
876                 if( pCurrentThreadCB->Next == NULL)
877                 {
878                     pCurrentThreadCB->Next = pThreadCB;
879                     break;
880                 }
881
882                 pCurrentThreadCB = pCurrentThreadCB->Next;
883             }
884         }
885
886 try_exit:
887
888         NOTHING;
889     }
890
891     return pThreadCB;
892 }