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