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