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