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