Windows: non-release only worker threads can release
[openafs.git] / src / WINNT / afsrdr / kernel / fs / AFSAuthGroupSupport.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: AFSAuthGroupSupport.cpp
37 //
38
39 #include "AFSCommon.h"
40
41 void
42 AFSRetrieveAuthGroup( IN ULONGLONG ProcessId,
43                       IN ULONGLONG ThreadId,
44                       OUT GUID *AuthGroup)
45 {
46
47     NTSTATUS ntStatus = STATUS_SUCCESS;
48     AFSProcessCB *pProcessCB = NULL;
49     AFSThreadCB *pThreadCB = NULL;
50     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
51     GUID *pAuthGroup = NULL;
52     UNICODE_STRING uniGUIDString;
53     ULONG ulSessionId = 0;
54     BOOLEAN bImpersonation = FALSE;
55
56     __Enter
57     {
58
59         ulSessionId = AFSGetSessionId( (HANDLE)ProcessId, &bImpersonation);
60
61         if( ulSessionId == (ULONG)-1)
62         {
63
64             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
65                           AFS_TRACE_LEVEL_ERROR,
66                           "%s Failed to retrieve session ID for PID %I64X\n",
67                           __FUNCTION__,
68                           ProcessId);
69
70             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
71         }
72
73         AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
74                       AFS_TRACE_LEVEL_VERBOSE,
75                       "%s Entry for Session %08lX PID %I64X TID %I64X\n",
76                       __FUNCTION__,
77                       ulSessionId,
78                       ProcessId,
79                       ThreadId);
80
81         ntStatus = AFSCheckThreadDacl( AuthGroup);
82
83         if( NT_SUCCESS( ntStatus))
84         {
85
86             uniGUIDString.Buffer = NULL;
87             uniGUIDString.Length = 0;
88             uniGUIDString.MaximumLength = 0;
89
90             RtlStringFromGUID( *AuthGroup,
91                                &uniGUIDString);
92
93             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
94                           AFS_TRACE_LEVEL_VERBOSE,
95                           "%s Located AuthGroup %wZ via DACL for Session %08lX PID %I64X TID %I64X\n",
96                           __FUNCTION__,
97                           &uniGUIDString,
98                           ulSessionId,
99                           ProcessId,
100                           ThreadId);
101
102             if( uniGUIDString.Buffer != NULL)
103             {
104                 RtlFreeUnicodeString( &uniGUIDString);
105             }
106
107             try_return( ntStatus = STATUS_SUCCESS);
108         }
109
110         AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
111                       AFS_TRACE_LEVEL_VERBOSE,
112                       "AFSRetrieveAuthGroup Acquiring Control ProcessTree.TreeLock lock %08lX SHARED %08lX\n",
113                       pDeviceExt->Specific.Control.ProcessTree.TreeLock,
114                       PsGetCurrentThread());
115
116         ntStatus = STATUS_SUCCESS;
117
118         AFSAcquireShared( pDeviceExt->Specific.Control.ProcessTree.TreeLock,
119                           TRUE);
120
121         ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.ProcessTree.TreeHead,
122                                        (ULONGLONG)ProcessId,
123                                        (AFSBTreeEntry **)&pProcessCB);
124
125         if( !NT_SUCCESS( ntStatus) ||
126             pProcessCB == NULL)
127         {
128
129             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
130                           AFS_TRACE_LEVEL_ERROR,
131                           "%s Failed to locate process entry for Session %08lX PID %I64X TID %I64X\n",
132                           __FUNCTION__,
133                           ulSessionId,
134                           ProcessId,
135                           ThreadId);
136
137             AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock);
138             try_return( ntStatus);
139         }
140
141         for ( pThreadCB = pProcessCB->ThreadList;
142               pThreadCB != NULL;
143               pThreadCB = pThreadCB->Next)
144         {
145
146             if( pThreadCB->ThreadId == ThreadId)
147             {
148                 break;
149             }
150         }
151
152         if( pThreadCB != NULL &&
153             pThreadCB->ActiveAuthGroup != NULL)
154         {
155             pAuthGroup = pThreadCB->ActiveAuthGroup;
156
157             RtlCopyMemory( AuthGroup,
158                            pAuthGroup,
159                            sizeof( GUID));
160
161             uniGUIDString.Buffer = NULL;
162             uniGUIDString.Length = 0;
163             uniGUIDString.MaximumLength = 0;
164
165             RtlStringFromGUID( *AuthGroup,
166                                &uniGUIDString);
167
168             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
169                           AFS_TRACE_LEVEL_VERBOSE,
170                           "%s Located AuthGroup %wZ in thread Session %08lX PID %I64X TID %I64X\n",
171                           __FUNCTION__,
172                           &uniGUIDString,
173                           ulSessionId,
174                           ProcessId,
175                           ThreadId);
176
177             if( uniGUIDString.Buffer != NULL)
178             {
179                 RtlFreeUnicodeString( &uniGUIDString);
180             }
181         }
182         else if( pProcessCB->ActiveAuthGroup != NULL)
183         {
184
185             pAuthGroup = pProcessCB->ActiveAuthGroup;
186
187             RtlCopyMemory( AuthGroup,
188                            pAuthGroup,
189                            sizeof( GUID));
190
191             uniGUIDString.Buffer = NULL;
192             uniGUIDString.Length = 0;
193             uniGUIDString.MaximumLength = 0;
194
195             RtlStringFromGUID( *AuthGroup,
196                                &uniGUIDString);
197
198             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
199                           AFS_TRACE_LEVEL_VERBOSE,
200                           "%s Located AuthGroup %wZ in process Session %08lX PID %I64X TID %I64X\n",
201                           __FUNCTION__,
202                           &uniGUIDString,
203                           ulSessionId,
204                           ProcessId,
205                           ThreadId);
206
207             if( uniGUIDString.Buffer != NULL)
208             {
209                 RtlFreeUnicodeString( &uniGUIDString);
210             }
211         }
212
213         AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock);
214
215         if( pAuthGroup == NULL ||
216             AFSIsNoPAGAuthGroup( pAuthGroup))
217         {
218
219             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
220                           AFS_TRACE_LEVEL_VERBOSE,
221                           "%s No AuthGroup located, validating process for Session %08lX PID %I64X TID %I64X\n",
222                           __FUNCTION__,
223                           ulSessionId,
224                           ProcessId,
225                           ThreadId);
226
227             pAuthGroup = AFSValidateProcessEntry();
228
229             if( pAuthGroup != NULL)
230             {
231                 RtlCopyMemory( AuthGroup,
232                                pAuthGroup,
233                                sizeof( GUID));
234
235                 uniGUIDString.Buffer = NULL;
236                 uniGUIDString.Length = 0;
237                 uniGUIDString.MaximumLength = 0;
238
239                 RtlStringFromGUID( *AuthGroup,
240                                    &uniGUIDString);
241
242                 AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
243                               AFS_TRACE_LEVEL_VERBOSE,
244                               "%s Located AuthGroup %wZ after validation Session %08lX PID %I64X TID %I64X\n",
245                               __FUNCTION__,
246                               &uniGUIDString,
247                               ulSessionId,
248                               ProcessId,
249                               ThreadId);
250
251                 if( uniGUIDString.Buffer != NULL)
252                 {
253                     RtlFreeUnicodeString( &uniGUIDString);
254                 }
255             }
256             else
257             {
258                 AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
259                               AFS_TRACE_LEVEL_ERROR,
260                               "%s Failed to locate AuthGroup for Session %08lX PID %I64X TID %I64X\n",
261                               __FUNCTION__,
262                               ulSessionId,
263                               ProcessId,
264                               ThreadId);
265             }
266         }
267
268 try_exit:
269
270         NOTHING;
271     }
272
273     return;
274 }
275
276 //
277 // AFSIsLocalSystemAuthGroup returns TRUE if the AuthGroup matches
278 // the AuthGroup associated with the first process that communicates
279 // with the redirector which will always be "System" (PID 4).
280 //
281
282 BOOLEAN
283 AFSIsLocalSystemAuthGroup( IN GUID *AuthGroup)
284 {
285
286     BOOLEAN bIsLocalSys = FALSE;
287     AFSProcessCB *pProcessCB = NULL;
288     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
289     UNICODE_STRING uniGUIDString;
290
291     __Enter
292     {
293
294         uniGUIDString.Length = 0;
295         uniGUIDString.MaximumLength = 0;
296         uniGUIDString.Buffer = NULL;
297
298         RtlStringFromGUID( *AuthGroup,
299                            &uniGUIDString);
300
301         AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
302                       AFS_TRACE_LEVEL_VERBOSE_2,
303                       "%s Checking AuthGroup %wZ\n",
304                       __FUNCTION__,
305                       &uniGUIDString);
306
307         AFSAcquireShared( pDeviceExt->Specific.Control.ProcessTree.TreeLock,
308                           TRUE);
309
310         pProcessCB = (AFSProcessCB *)pDeviceExt->Specific.Control.ProcessTree.TreeHead;
311
312         if( pProcessCB->ActiveAuthGroup != NULL &&
313             RtlCompareMemory( pProcessCB->ActiveAuthGroup,
314                               AuthGroup,
315                               sizeof( GUID)) == sizeof( GUID))
316         {
317             bIsLocalSys = TRUE;
318
319             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
320                           AFS_TRACE_LEVEL_VERBOSE,
321                           "%s AuthGroup %wZ is LOCAL SYSTEM\n",
322                           __FUNCTION__,
323                           &uniGUIDString);
324         }
325
326         AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock);
327
328         if( uniGUIDString.Buffer != NULL)
329         {
330             RtlFreeUnicodeString( &uniGUIDString);
331         }
332     }
333
334     return bIsLocalSys;
335 }
336
337 BOOLEAN
338 AFSIsLocalSystemSID( IN UNICODE_STRING *SIDString)
339 {
340
341     BOOLEAN bIsLocalSys = FALSE;
342     UNICODE_STRING uniSysLocal;
343
344     __Enter
345     {
346
347         RtlInitUnicodeString( &uniSysLocal,
348                               L"S-1-5-18");
349
350         if( RtlCompareUnicodeString( &uniSysLocal,
351                                      SIDString,
352                                      TRUE) == 0)
353         {
354             bIsLocalSys = TRUE;
355         }
356
357         AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
358                       AFS_TRACE_LEVEL_VERBOSE_2,
359                       "%s AuthGroup SID %wZ is %sLOCAL SYSTEM\n",
360                       __FUNCTION__,
361                       SIDString,
362                       bIsLocalSys ? "" : "not ");
363     }
364
365     return bIsLocalSys;
366 }
367
368 BOOLEAN
369 AFSIsNoPAGAuthGroup( IN GUID *AuthGroup)
370 {
371
372     BOOLEAN bIsNoPAG = FALSE;
373     UNICODE_STRING uniGUIDString;
374
375     __Enter
376     {
377
378         uniGUIDString.Length = 0;
379         uniGUIDString.MaximumLength = 0;
380         uniGUIDString.Buffer = NULL;
381
382         RtlStringFromGUID( *AuthGroup,
383                            &uniGUIDString);
384
385         if( RtlCompareMemory( AuthGroup,
386                               &AFSNoPAGAuthGroup,
387                               sizeof( GUID)) == sizeof( GUID))
388         {
389             bIsNoPAG = TRUE;
390         }
391
392         AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
393                       AFS_TRACE_LEVEL_VERBOSE_2,
394                       "%s AuthGroup %wZ is %sNoPAG\n",
395                       __FUNCTION__,
396                       &uniGUIDString,
397                       bIsNoPAG ? "" : "not ");
398
399         if( uniGUIDString.Buffer != NULL)
400         {
401             RtlFreeUnicodeString( &uniGUIDString);
402         }
403     }
404
405     return bIsNoPAG;
406 }
407
408 //
409 // Creates a new AuthGroup and either activates it for
410 // the process or the current thread.  If set as the
411 // new process AuthGroup, the prior AuthGroup list is
412 // cleared.
413 //
414
415 NTSTATUS
416 AFSCreateSetProcessAuthGroup( AFSAuthGroupRequestCB *CreateSetAuthGroup)
417 {
418
419     NTSTATUS ntStatus = STATUS_SUCCESS;
420     AFSProcessCB *pProcessCB = NULL;
421     AFSThreadCB *pThreadCB = NULL;
422     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
423     ULONGLONG ullProcessID = (ULONGLONG)PsGetCurrentProcessId();
424     ULONGLONG ullThreadId = (ULONGLONG)PsGetCurrentThreadId();
425     UNICODE_STRING uniSIDString, uniPassedSIDString;
426     ULONG ulSIDHash = 0;
427     AFSProcessAuthGroupCB *pAuthGroup = NULL, *pLastAuthGroup = NULL;
428     ULONG ulSessionId = 0;
429     ULONGLONG ullTableHash = 0;
430     GUID stAuthGroup;
431     UNICODE_STRING uniCallerSID;
432     BOOLEAN bImpersonation = FALSE;
433
434     __Enter
435     {
436
437         uniCallerSID.Length = 0;
438         uniCallerSID.MaximumLength = 0;
439         uniCallerSID.Buffer = NULL;
440
441         AFSAcquireShared( pDeviceExt->Specific.Control.ProcessTree.TreeLock,
442                           TRUE);
443
444         ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.ProcessTree.TreeHead,
445                                        (ULONGLONG)ullProcessID,
446                                        (AFSBTreeEntry **)&pProcessCB);
447
448         if( !NT_SUCCESS( ntStatus) ||
449             pProcessCB == NULL)
450         {
451
452             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
453                           AFS_TRACE_LEVEL_ERROR,
454                           "%s Failed to locate process CB for PID %I64X\n",
455                           __FUNCTION__,
456                           ullProcessID);
457
458             AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock);
459             try_return( ntStatus = STATUS_UNSUCCESSFUL);
460         }
461
462         AFSAcquireExcl( &pProcessCB->Lock,
463                         TRUE);
464
465         AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock);
466
467         ntStatus = AFSGetCallerSID( &uniCallerSID, &bImpersonation);
468
469         if( !NT_SUCCESS( ntStatus))
470         {
471
472             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
473                           AFS_TRACE_LEVEL_ERROR,
474                           "%s Failed to locate caller SID for PID %I64X Status %08lX\n",
475                           __FUNCTION__,
476                           ullProcessID,
477                           ntStatus);
478
479             try_return( ntStatus);
480         }
481
482         AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
483                       AFS_TRACE_LEVEL_VERBOSE,
484                       "%s Retrieved caller SID %wZ for PID %I64X\n",
485                       __FUNCTION__,
486                       &uniCallerSID,
487                       ullProcessID);
488
489
490         if( CreateSetAuthGroup->SIDLength != 0)
491         {
492
493             uniPassedSIDString.Length = CreateSetAuthGroup->SIDLength;
494             uniPassedSIDString.MaximumLength = uniPassedSIDString.Length;
495
496             uniPassedSIDString.Buffer = CreateSetAuthGroup->SIDString;
497
498             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
499                           AFS_TRACE_LEVEL_VERBOSE,
500                           "%s Validating passed SID %wZ for PID %I64X\n",
501                           __FUNCTION__,
502                           &uniPassedSIDString,
503                           ullProcessID);
504
505             if( RtlCompareUnicodeString( &uniCallerSID,
506                                          &uniPassedSIDString,
507                                          TRUE) != 0)
508             {
509
510                 if( !BooleanFlagOn( pProcessCB->Flags, AFS_PROCESS_LOCAL_SYSTEM_AUTH))
511                 {
512
513                     AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
514                                   AFS_TRACE_LEVEL_ERROR,
515                                   "%s Caller specified SID %wZ for PID %I64X but caller is not LOCAL SYSTEM AUTHORITY\n",
516                                   __FUNCTION__,
517                                   &uniPassedSIDString,
518                                   ullProcessID);
519
520                     try_return( ntStatus = STATUS_ACCESS_DENIED);
521                 }
522
523                 uniSIDString = uniPassedSIDString;
524
525                 AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
526                               AFS_TRACE_LEVEL_VERBOSE,
527                               "%s Using passed SID %wZ for PID %I64X\n",
528                               __FUNCTION__,
529                               &uniSIDString,
530                               ullProcessID);
531             }
532             else
533             {
534                 uniSIDString = uniCallerSID;
535
536                 AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
537                               AFS_TRACE_LEVEL_VERBOSE,
538                               "%s Caller and passed SID are equal SID %wZ for PID %I64X\n",
539                               __FUNCTION__,
540                               &uniSIDString,
541                               ullProcessID);
542             }
543         }
544         else
545         {
546             uniSIDString = uniCallerSID;
547
548             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
549                           AFS_TRACE_LEVEL_VERBOSE,
550                           "%s No SID passed, using callers SID %wZ for PID %I64X\n",
551                           __FUNCTION__,
552                           &uniSIDString,
553                           ullProcessID);
554         }
555
556         ntStatus = RtlHashUnicodeString( &uniSIDString,
557                                          TRUE,
558                                          HASH_STRING_ALGORITHM_DEFAULT,
559                                          &ulSIDHash);
560
561         if( !NT_SUCCESS( ntStatus))
562         {
563
564             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
565                           AFS_TRACE_LEVEL_ERROR,
566                           "%s Failed to hash SID %wZ for PID %I64X Status %08lX\n",
567                           __FUNCTION__,
568                           &uniSIDString,
569                           ullProcessID,
570                           ntStatus);
571
572             try_return( ntStatus);
573         }
574
575         ulSessionId = AFSGetSessionId( (HANDLE)ullProcessID, &bImpersonation);
576
577         if( ulSessionId == (ULONG)-1)
578         {
579
580             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
581                           AFS_TRACE_LEVEL_ERROR,
582                           "%s Failed to retrieve SessionID PID %I64X Status %08lX\n",
583                           __FUNCTION__,
584                           ullProcessID,
585                           ntStatus);
586
587             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
588         }
589
590         if( CreateSetAuthGroup->SessionId != (ULONG)-1)
591         {
592
593             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
594                           AFS_TRACE_LEVEL_VERBOSE,
595                           "%s Checking passed SessionID %08lX for PID %I64X\n",
596                           __FUNCTION__,
597                           CreateSetAuthGroup->SessionId,
598                           ullProcessID);
599
600             if( ulSessionId != CreateSetAuthGroup->SessionId)
601             {
602
603                 if( !BooleanFlagOn( pProcessCB->Flags, AFS_PROCESS_LOCAL_SYSTEM_AUTH))
604                 {
605
606                     AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
607                                   AFS_TRACE_LEVEL_ERROR,
608                                   "%s Passed SessionID %08lX for PID %I64X, failed because caller is not LOCAL SYSTEM AUTHORITY\n",
609                                   __FUNCTION__,
610                                   CreateSetAuthGroup->SessionId,
611                                   ullProcessID);
612
613                     try_return( ntStatus = STATUS_ACCESS_DENIED);
614                 }
615
616                 ulSessionId = CreateSetAuthGroup->SessionId;
617
618                 AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
619                               AFS_TRACE_LEVEL_VERBOSE,
620                               "%s Using passed SessionID %08lX for PID %I64X\n",
621                               __FUNCTION__,
622                               ulSessionId,
623                               ullProcessID);
624             }
625         }
626         else
627         {
628             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
629                           AFS_TRACE_LEVEL_VERBOSE,
630                           "%s Using callers SessionID %08lX for PID %I64X\n",
631                           __FUNCTION__,
632                           ulSessionId,
633                           ullProcessID);
634         }
635
636         ullTableHash = ( ((ULONGLONG)ulSessionId << 32) | ulSIDHash);
637
638         pAuthGroup = pProcessCB->AuthGroupList;
639
640         while( pAuthGroup != NULL)
641         {
642
643             if( pAuthGroup->AuthGroupHash == ullTableHash)
644             {
645                 break;
646             }
647
648             pLastAuthGroup = pAuthGroup;
649
650             pAuthGroup = pAuthGroup->Next;
651         }
652
653         if( pAuthGroup != NULL)
654         {
655
656             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
657                           AFS_TRACE_LEVEL_ERROR,
658                           "%s Located AuthGroup for SID %wZ SessionID %08lX for PID %I64X, failing request\n",
659                           __FUNCTION__,
660                           &uniSIDString,
661                           ulSessionId,
662                           ullProcessID);
663
664             try_return( ntStatus = STATUS_INVALID_PARAMETER);
665         }
666
667         pAuthGroup = (AFSProcessAuthGroupCB *)AFSExAllocatePoolWithTag( NonPagedPool,
668                                                                         sizeof( AFSProcessAuthGroupCB),
669                                                                         AFS_AG_ENTRY_CB_TAG);
670
671         if( pAuthGroup == NULL)
672         {
673             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
674         }
675
676         RtlZeroMemory( pAuthGroup,
677                        sizeof( AFSProcessAuthGroupCB));
678
679         pAuthGroup->AuthGroupHash = (ULONGLONG)ullTableHash;
680
681         while( ExUuidCreate( &pAuthGroup->AuthGroup) == STATUS_RETRY);
682
683         if( pLastAuthGroup == NULL)
684         {
685             pProcessCB->AuthGroupList = pAuthGroup;
686         }
687         else
688         {
689             pLastAuthGroup->Next = pAuthGroup;
690         }
691
692         AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
693                       AFS_TRACE_LEVEL_VERBOSE,
694                       "%s Allocated new AuthGroup for SID %wZ SessionID %08lX for PID %I64X\n",
695                       __FUNCTION__,
696                       &uniSIDString,
697                       ulSessionId,
698                       ullProcessID);
699
700         if( BooleanFlagOn( CreateSetAuthGroup->Flags, AFS_PAG_FLAGS_THREAD_AUTH_GROUP))
701         {
702
703             pThreadCB = pProcessCB->ThreadList;
704
705             while( pThreadCB != NULL)
706             {
707
708                 if( pThreadCB->ThreadId == ullThreadId)
709                 {
710                     pThreadCB->ActiveAuthGroup = &pAuthGroup->AuthGroup;
711                     break;
712                 }
713
714                 pThreadCB = pThreadCB->Next;
715             }
716
717             if( pThreadCB == NULL)
718             {
719
720                 pThreadCB = AFSInitializeThreadCB( pProcessCB,
721                                                    ullThreadId);
722
723                 if( pThreadCB == NULL)
724                 {
725                     try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
726                 }
727
728                 pThreadCB->ActiveAuthGroup = &pAuthGroup->AuthGroup;
729             }
730
731             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
732                           AFS_TRACE_LEVEL_VERBOSE,
733                           "%s Set new AuthGroup for SID %wZ SessionID %08lX for PID %I64X on thread ID %I64X\n",
734                           __FUNCTION__,
735                           &uniSIDString,
736                           ulSessionId,
737                           ullProcessID,
738                           ullThreadId);
739         }
740         else if( BooleanFlagOn( CreateSetAuthGroup->Flags, AFS_PAG_FLAGS_SET_AS_ACTIVE))
741         {
742             pProcessCB->ActiveAuthGroup = &pAuthGroup->AuthGroup;
743
744             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
745                           AFS_TRACE_LEVEL_VERBOSE,
746                           "%s Set new AuthGroup for SID %wZ SessionID %08lX for PID %I64X on process\n",
747                           __FUNCTION__,
748                           &uniSIDString,
749                           ulSessionId,
750                           ullProcessID);
751         }
752
753 try_exit:
754
755         if( pProcessCB != NULL)
756         {
757             AFSReleaseResource( &pProcessCB->Lock);
758         }
759
760         if( uniCallerSID.Length > 0)
761         {
762             RtlFreeUnicodeString( &uniCallerSID);
763         }
764     }
765
766     return ntStatus;
767 }
768
769 //
770 // Returns a list of the AuthGroup GUIDS associated
771 // with the current process, the current process GUID,
772 // and the current thread GUID.
773 //
774
775 NTSTATUS
776 AFSQueryProcessAuthGroupList( IN GUID *GUIDList,
777                               IN ULONG BufferLength,
778                               OUT ULONG_PTR *ReturnLength)
779 {
780
781     NTSTATUS ntStatus = STATUS_SUCCESS;
782     AFSProcessCB *pProcessCB = NULL;
783     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
784     ULONGLONG ullProcessID = (ULONGLONG)PsGetCurrentProcessId();
785     ULONG ulRequiredLength = 0;
786     AFSProcessAuthGroupCB *pAuthGroup = NULL;
787     GUID *pCurrentGUID = GUIDList;
788     UNICODE_STRING uniGUIDString;
789
790     __Enter
791     {
792
793         AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
794                       AFS_TRACE_LEVEL_VERBOSE,
795                       "%s Entry for PID %I64X\n",
796                       __FUNCTION__,
797                       ullProcessID);
798
799         AFSAcquireShared( pDeviceExt->Specific.Control.ProcessTree.TreeLock,
800                           TRUE);
801
802         ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.ProcessTree.TreeHead,
803                                        (ULONGLONG)ullProcessID,
804                                        (AFSBTreeEntry **)&pProcessCB);
805
806         if( !NT_SUCCESS( ntStatus) ||
807             pProcessCB == NULL)
808         {
809
810             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
811                           AFS_TRACE_LEVEL_ERROR,
812                           "%s Failed to locate process entry PID %I64X\n",
813                           __FUNCTION__,
814                           ullProcessID);
815
816             AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock);
817             try_return( ntStatus = STATUS_UNSUCCESSFUL);
818         }
819
820         AFSAcquireShared( &pProcessCB->Lock,
821                           TRUE);
822
823         AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock);
824
825         pAuthGroup = pProcessCB->AuthGroupList;
826
827         ulRequiredLength = 0;
828
829         while( pAuthGroup != NULL)
830         {
831             ulRequiredLength += sizeof( GUID);
832             pAuthGroup = pAuthGroup->Next;
833         }
834
835         if( BufferLength == 0 ||
836             BufferLength < ulRequiredLength ||
837             GUIDList == NULL)
838         {
839
840             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
841                           AFS_TRACE_LEVEL_VERBOSE,
842                           "%s Buffer too small for query, required %08lX for PID %I64X\n",
843                           __FUNCTION__,
844                           ulRequiredLength,
845                           ullProcessID);
846
847             *ReturnLength = ulRequiredLength;
848             try_return( ntStatus = STATUS_BUFFER_OVERFLOW);
849         }
850
851         pAuthGroup = pProcessCB->AuthGroupList;
852
853         *ReturnLength = 0;
854
855         while( pAuthGroup != NULL)
856         {
857             RtlCopyMemory( pCurrentGUID,
858                            &pAuthGroup->AuthGroup,
859                            sizeof( GUID));
860
861             uniGUIDString.Buffer = NULL;
862             uniGUIDString.Length = 0;
863             uniGUIDString.MaximumLength = 0;
864
865             RtlStringFromGUID( pAuthGroup->AuthGroup,
866                                &uniGUIDString);
867
868             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
869                           AFS_TRACE_LEVEL_VERBOSE,
870                           "%s Adding AuthGroup %wZ for PID %I64X\n",
871                           __FUNCTION__,
872                           &uniGUIDString,
873                           ullProcessID);
874
875             if( uniGUIDString.Buffer != NULL)
876             {
877                 RtlFreeUnicodeString( &uniGUIDString);
878             }
879
880             pCurrentGUID = (GUID *)((char *)pCurrentGUID + sizeof( GUID));
881
882             *ReturnLength += sizeof( GUID);
883
884             pAuthGroup = pAuthGroup->Next;
885         }
886
887 try_exit:
888
889         if( pProcessCB != NULL)
890         {
891             AFSReleaseResource( &pProcessCB->Lock);
892         }
893     }
894
895     return ntStatus;
896 }
897
898 //
899 // Permits the current AuthGroup for the process or
900 // thread to be set to the specified GUID.  The GUID
901 // must be in the list of current values for the process.
902 //
903
904 NTSTATUS
905 AFSSetActiveProcessAuthGroup( IN AFSAuthGroupRequestCB *ActiveAuthGroup)
906 {
907
908     NTSTATUS ntStatus = STATUS_SUCCESS;
909     AFSProcessCB *pProcessCB = NULL;
910     AFSThreadCB *pThreadCB = NULL;
911     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
912     ULONGLONG ullProcessID = (ULONGLONG)PsGetCurrentProcessId();
913     ULONGLONG ullThreadId = (ULONGLONG)PsGetCurrentThreadId();
914     AFSProcessAuthGroupCB *pAuthGroup = NULL;
915     UNICODE_STRING uniGUIDString;
916
917     __Enter
918     {
919
920         uniGUIDString.Length = 0;
921         uniGUIDString.MaximumLength = 0;
922         uniGUIDString.Buffer = NULL;
923
924         RtlStringFromGUID( ActiveAuthGroup->AuthGroup,
925                            &uniGUIDString);
926
927         AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
928                       AFS_TRACE_LEVEL_VERBOSE,
929                       "%s Entry for ProcessID %I64X AuthGroup GUID %wZ\n",
930                       __FUNCTION__,
931                       ullProcessID,
932                       &uniGUIDString);
933
934         AFSAcquireShared( pDeviceExt->Specific.Control.ProcessTree.TreeLock,
935                           TRUE);
936
937         ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.ProcessTree.TreeHead,
938                                        (ULONGLONG)ullProcessID,
939                                        (AFSBTreeEntry **)&pProcessCB);
940
941         if( !NT_SUCCESS( ntStatus) ||
942             pProcessCB == NULL)
943         {
944
945             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
946                           AFS_TRACE_LEVEL_ERROR,
947                           "%s Failed to locate process entry for ProcessID %I64X\n",
948                           __FUNCTION__,
949                           ullProcessID);
950
951             AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock);
952             try_return( ntStatus = STATUS_UNSUCCESSFUL);
953         }
954
955
956         AFSAcquireExcl( &pProcessCB->Lock,
957                         TRUE);
958
959         AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock);
960
961         pAuthGroup = pProcessCB->AuthGroupList;
962
963         while( pAuthGroup != NULL)
964         {
965
966             if( RtlCompareMemory( &ActiveAuthGroup->AuthGroup,
967                                   &pAuthGroup->AuthGroup,
968                                   sizeof( GUID)) == sizeof( GUID))
969             {
970                 break;
971             }
972             pAuthGroup = pAuthGroup->Next;
973         }
974
975         if( pAuthGroup == NULL)
976         {
977
978             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
979                           AFS_TRACE_LEVEL_VERBOSE,
980                           "%s Failed to locate AuthGroup for ProcessID %I64X AuthGroup GUID %wZ\n",
981                           __FUNCTION__,
982                           ullProcessID,
983                           &uniGUIDString);
984
985             try_return( ntStatus = STATUS_INVALID_PARAMETER);
986         }
987
988         if( BooleanFlagOn( ActiveAuthGroup->Flags, AFS_PAG_FLAGS_THREAD_AUTH_GROUP))
989         {
990
991             pThreadCB = pProcessCB->ThreadList;
992
993             while( pThreadCB != NULL)
994             {
995
996                 if( pThreadCB->ThreadId == ullThreadId)
997                 {
998                     pThreadCB->ActiveAuthGroup = &pAuthGroup->AuthGroup;
999                     break;
1000                 }
1001
1002                 pThreadCB = pThreadCB->Next;
1003             }
1004
1005             if( pThreadCB == NULL)
1006             {
1007
1008                 pThreadCB = AFSInitializeThreadCB( pProcessCB,
1009                                                    ullThreadId);
1010
1011                 if( pThreadCB == NULL)
1012                 {
1013                     try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1014                 }
1015
1016                 pThreadCB->ActiveAuthGroup = &pAuthGroup->AuthGroup;
1017             }
1018
1019             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1020                           AFS_TRACE_LEVEL_VERBOSE,
1021                           "%s Set active AuthGroup for ProcessID %I64X AuthGroup GUID %wZ on thread %I64X\n",
1022                           __FUNCTION__,
1023                           ullProcessID,
1024                           &uniGUIDString,
1025                           ullThreadId);
1026         }
1027         else
1028         {
1029             pProcessCB->ActiveAuthGroup = &pAuthGroup->AuthGroup;
1030
1031             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1032                           AFS_TRACE_LEVEL_VERBOSE,
1033                           "%s Set active AuthGroup for ProcessID %I64X AuthGroup GUID %wZ on process\n",
1034                           __FUNCTION__,
1035                           ullProcessID,
1036                           &uniGUIDString);
1037         }
1038
1039 try_exit:
1040
1041         if( pProcessCB != NULL)
1042         {
1043             AFSReleaseResource( &pProcessCB->Lock);
1044         }
1045
1046         if( uniGUIDString.Buffer != NULL)
1047         {
1048             RtlFreeUnicodeString( &uniGUIDString);
1049         }
1050     }
1051
1052     return ntStatus;
1053 }
1054
1055 //
1056 // Resets the current AuthGroup for the process or
1057 // thread to the SID-AuthGroup
1058 //
1059
1060 NTSTATUS
1061 AFSResetActiveProcessAuthGroup( IN IN AFSAuthGroupRequestCB *AuthGroup)
1062 {
1063
1064     NTSTATUS ntStatus = STATUS_SUCCESS;
1065     GUID *pAuthGroup = NULL;
1066     AFSProcessCB *pProcessCB = NULL;
1067     AFSThreadCB *pThreadCB = NULL;
1068     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
1069     ULONGLONG ullProcessID = (ULONGLONG)PsGetCurrentProcessId();
1070     ULONGLONG ullThreadId = (ULONGLONG)PsGetCurrentThreadId();
1071
1072     __Enter
1073     {
1074
1075         AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1076                       AFS_TRACE_LEVEL_VERBOSE,
1077                       "%s Entry for ProcessID %I64X\n",
1078                       __FUNCTION__,
1079                       ullProcessID);
1080
1081         AFSAcquireShared( pDeviceExt->Specific.Control.ProcessTree.TreeLock,
1082                           TRUE);
1083
1084         ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.ProcessTree.TreeHead,
1085                                        (ULONGLONG)ullProcessID,
1086                                        (AFSBTreeEntry **)&pProcessCB);
1087
1088         if( !NT_SUCCESS( ntStatus) ||
1089             pProcessCB == NULL)
1090         {
1091
1092             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1093                           AFS_TRACE_LEVEL_ERROR,
1094                           "%s Failed to locate AuthGroup for ProcessID %I64X\n",
1095                           __FUNCTION__,
1096                           ullProcessID);
1097
1098             AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock);
1099             try_return( ntStatus = STATUS_UNSUCCESSFUL);
1100         }
1101
1102         AFSAcquireExcl( &pProcessCB->Lock,
1103                         TRUE);
1104
1105         AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock);
1106
1107         if( BooleanFlagOn( AuthGroup->Flags, AFS_PAG_FLAGS_THREAD_AUTH_GROUP))
1108         {
1109
1110             pThreadCB = pProcessCB->ThreadList;
1111
1112             while( pThreadCB != NULL)
1113             {
1114
1115                 if( pThreadCB->ThreadId == ullThreadId)
1116                 {
1117                     pThreadCB->ActiveAuthGroup = NULL;
1118                     break;
1119                 }
1120
1121                 pThreadCB = pThreadCB->Next;
1122             }
1123
1124             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1125                           AFS_TRACE_LEVEL_VERBOSE,
1126                           "%s Reset AuthGroup list on thread %I64X for ProcessID %I64X\n",
1127                           __FUNCTION__,
1128                           ullThreadId,
1129                           ullProcessID);
1130         }
1131         else
1132         {
1133             pProcessCB->ActiveAuthGroup = NULL;
1134
1135             pThreadCB = pProcessCB->ThreadList;
1136
1137             while( pThreadCB != NULL)
1138             {
1139                 pThreadCB->ActiveAuthGroup = NULL;
1140                 pThreadCB = pThreadCB->Next;
1141             }
1142
1143             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1144                           AFS_TRACE_LEVEL_VERBOSE,
1145                           "%s Reset AuthGroup list on process for ProcessID %I64X\n",
1146                           __FUNCTION__,
1147                           ullProcessID);
1148         }
1149
1150         AFSReleaseResource( &pProcessCB->Lock);
1151
1152 try_exit:
1153
1154         NOTHING;
1155     }
1156
1157     return ntStatus;
1158 }
1159
1160 //
1161 // When bLogonSession == FALSE, the SID must not be specified
1162 // and the SessionId must be -1.  A new AuthGroup GUID is
1163 // assigned to the SID and SessionId of the calling Process.
1164 //
1165 // When bLogonSession == TRUE, the SID must be specified and
1166 // the SessionId must not be -1.  The SID of the calling process
1167 // must be LOCAL_SYSTEM and a new AuthGroup GUID is assigned to
1168 // the specified SID and logon session.
1169 //
1170
1171 NTSTATUS
1172 AFSCreateAuthGroupForSIDorLogonSession( IN AFSAuthGroupRequestCB *AuthGroupRequestCB,
1173                                         IN BOOLEAN bLogonSession)
1174 {
1175
1176     NTSTATUS ntStatus = STATUS_SUCCESS;
1177     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
1178     ULONGLONG ullProcessID = (ULONGLONG)PsGetCurrentProcessId();
1179     ULONGLONG ullThreadId = (ULONGLONG)PsGetCurrentThreadId();
1180     UNICODE_STRING uniSIDString, uniPassedSIDString;
1181     ULONG ulSIDHash = 0;
1182     AFSSIDEntryCB *pSIDEntryCB = NULL;
1183     ULONG ulSessionId = 0;
1184     ULONGLONG ullTableHash = 0;
1185     GUID stAuthGroup;
1186     UNICODE_STRING uniCallerSID;
1187     UNICODE_STRING uniGUID;
1188     BOOLEAN bLocalSystem = FALSE;
1189     BOOLEAN bImpersonation = FALSE;
1190
1191     __Enter
1192     {
1193
1194         AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1195                       AFS_TRACE_LEVEL_VERBOSE,
1196                       "%s Entry for ProcessID %I64X ThreadID %I64X\n",
1197                       __FUNCTION__,
1198                       ullProcessID,
1199                       ullThreadId);
1200
1201         ntStatus = AFSGetCallerSID( &uniCallerSID, &bImpersonation);
1202
1203         if( !NT_SUCCESS( ntStatus))
1204         {
1205
1206             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1207                           AFS_TRACE_LEVEL_ERROR,
1208                           "%s Failed to retrieve callers SID for ProcessID %I64X ThreadID %I64X Status %08lX\n",
1209                           __FUNCTION__,
1210                           ullProcessID,
1211                           ullThreadId,
1212                           ntStatus);
1213
1214             try_return( ntStatus);
1215         }
1216
1217         bLocalSystem = AFSIsLocalSystemSID( &uniCallerSID);
1218
1219         if( bLogonSession == TRUE &&
1220             bLocalSystem == FALSE)
1221         {
1222
1223             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1224                           AFS_TRACE_LEVEL_ERROR,
1225                           "%s caller is %wZ and LOCAL SYSTEM AUTHORITY required\n",
1226                           __FUNCTION__,
1227                           uniCallerSID);
1228
1229             try_return( ntStatus = STATUS_ACCESS_DENIED);
1230         }
1231
1232         if ( bLogonSession == TRUE &&
1233              ( AuthGroupRequestCB == NULL ||
1234                AuthGroupRequestCB->SIDLength == 0 ||
1235                AuthGroupRequestCB->SessionId == (ULONG)-1))
1236         {
1237
1238             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1239                           AFS_TRACE_LEVEL_ERROR,
1240                           "%s SID and SessionId are mandatory\n",
1241                           __FUNCTION__);
1242
1243             try_return( ntStatus = STATUS_INVALID_PARAMETER);
1244         }
1245
1246         if ( bLogonSession == FALSE &&
1247              AuthGroupRequestCB != NULL &&
1248              ( AuthGroupRequestCB->SIDLength > 0 ||
1249                AuthGroupRequestCB->SessionId != (ULONG)-1))
1250         {
1251
1252             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1253                           AFS_TRACE_LEVEL_ERROR,
1254                           "%s SID and SessionId must not be specified\n",
1255                           __FUNCTION__);
1256
1257             try_return( ntStatus = STATUS_INVALID_PARAMETER);
1258         }
1259
1260
1261         AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1262                       AFS_TRACE_LEVEL_VERBOSE,
1263                       "%s Retrieved callers SID %wZ for ProcessID %I64X ThreadID %I64X\n",
1264                       __FUNCTION__,
1265                       &uniCallerSID,
1266                       ullProcessID,
1267                       ullThreadId);
1268
1269         if( AuthGroupRequestCB != NULL &&
1270             AuthGroupRequestCB->SIDLength != 0)
1271         {
1272
1273             uniPassedSIDString.Length = AuthGroupRequestCB->SIDLength;
1274             uniPassedSIDString.MaximumLength = uniPassedSIDString.Length;
1275
1276             uniPassedSIDString.Buffer = AuthGroupRequestCB->SIDString;
1277
1278             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1279                           AFS_TRACE_LEVEL_VERBOSE,
1280                           "%s Checking passed SID %wZ for ProcessID %I64X ThreadID %I64X\n",
1281                           __FUNCTION__,
1282                           &uniPassedSIDString,
1283                           ullProcessID,
1284                           ullThreadId);
1285
1286             if( RtlCompareUnicodeString( &uniCallerSID,
1287                                          &uniPassedSIDString,
1288                                          TRUE) != 0)
1289             {
1290
1291                 if( !bLocalSystem)
1292                 {
1293
1294                     AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1295                                   AFS_TRACE_LEVEL_ERROR,
1296                                   "%s Not using passed SID %wZ for ProcessID %I64X ThreadID %I64X caller is not LOCAL SYSTEM AUTHORITY\n",
1297                                   __FUNCTION__,
1298                                   &uniPassedSIDString,
1299                                   ullProcessID,
1300                                   ullThreadId);
1301
1302                     try_return( ntStatus = STATUS_ACCESS_DENIED);
1303                 }
1304
1305                 uniSIDString = uniPassedSIDString;
1306
1307                 AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1308                               AFS_TRACE_LEVEL_VERBOSE,
1309                               "%s Using passed SID %wZ for ProcessID %I64X ThreadID %I64X\n",
1310                               __FUNCTION__,
1311                               &uniSIDString,
1312                               ullProcessID,
1313                               ullThreadId);
1314             }
1315             else
1316             {
1317                 uniSIDString = uniCallerSID;
1318
1319                 AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1320                               AFS_TRACE_LEVEL_VERBOSE,
1321                               "%s Both SIDs are equal, using callers SID %wZ for ProcessID %I64X ThreadID %I64X\n",
1322                               __FUNCTION__,
1323                               &uniSIDString,
1324                               ullProcessID,
1325                               ullThreadId);
1326             }
1327         }
1328         else
1329         {
1330             uniSIDString = uniCallerSID;
1331
1332             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1333                           AFS_TRACE_LEVEL_VERBOSE,
1334                           "%s Using callers SID %wZ for ProcessID %I64X ThreadID %I64X\n",
1335                           __FUNCTION__,
1336                           &uniSIDString,
1337                           ullProcessID,
1338                           ullThreadId);
1339         }
1340
1341         ntStatus = RtlHashUnicodeString( &uniSIDString,
1342                                          TRUE,
1343                                          HASH_STRING_ALGORITHM_DEFAULT,
1344                                          &ulSIDHash);
1345
1346         if( !NT_SUCCESS( ntStatus))
1347         {
1348
1349             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1350                           AFS_TRACE_LEVEL_ERROR,
1351                           "%s Failed to hash SID %wZ for ProcessID %I64X ThreadID %I64X Status %08lX\n",
1352                           __FUNCTION__,
1353                           &uniSIDString,
1354                           ullProcessID,
1355                           ullThreadId,
1356                           ntStatus);
1357
1358             try_return( ntStatus);
1359         }
1360
1361         ulSessionId = AFSGetSessionId( (HANDLE)ullProcessID, &bImpersonation);
1362
1363         if( ulSessionId == (ULONG)-1)
1364         {
1365
1366             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1367                           AFS_TRACE_LEVEL_ERROR,
1368                           "%s Failed to retrieve session ID for ProcessID %I64X ThreadID %I64X\n",
1369                           __FUNCTION__,
1370                           ullProcessID,
1371                           ullThreadId);
1372
1373             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1374         }
1375
1376         if( bLogonSession == TRUE &&
1377             AuthGroupRequestCB != NULL &&
1378             AuthGroupRequestCB->SessionId != (ULONG)-1)
1379         {
1380
1381             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1382                           AFS_TRACE_LEVEL_VERBOSE,
1383                           "%s Checking passed SessionID %08lX for ProcessID %I64X ThreadID %I64X\n",
1384                           __FUNCTION__,
1385                           AuthGroupRequestCB->SessionId,
1386                           ullProcessID,
1387                           ullThreadId);
1388
1389             if( ulSessionId != AuthGroupRequestCB->SessionId)
1390             {
1391
1392                 ulSessionId = AuthGroupRequestCB->SessionId;
1393
1394                 AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1395                               AFS_TRACE_LEVEL_VERBOSE,
1396                               "%s Using passed SessionID %08lX for ProcessID %I64X ThreadID %I64X\n",
1397                               __FUNCTION__,
1398                               AuthGroupRequestCB->SessionId,
1399                               ullProcessID,
1400                               ullThreadId);
1401             }
1402         }
1403         else
1404         {
1405
1406             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1407                           AFS_TRACE_LEVEL_VERBOSE,
1408                           "%s Using callers SessionID %08lX for ProcessID %I64X ThreadID %I64X\n",
1409                           __FUNCTION__,
1410                           ulSessionId,
1411                           ullProcessID,
1412                           ullThreadId);
1413         }
1414
1415         ullTableHash = ( ((ULONGLONG)ulSessionId << 32) | ulSIDHash);
1416
1417         AFSAcquireExcl( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock,
1418                         TRUE);
1419
1420         ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.AuthGroupTree.TreeHead,
1421                                        (ULONGLONG)ullTableHash,
1422                                        (AFSBTreeEntry **)&pSIDEntryCB);
1423
1424         if( NT_SUCCESS( ntStatus) &&
1425             pSIDEntryCB != NULL)
1426         {
1427
1428             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1429                           AFS_TRACE_LEVEL_VERBOSE,
1430                           "%s Located SID entry for SID %wZ SessionID %08lX ProcessID %I64X ThreadID %I64X, updating GUID\n",
1431                           __FUNCTION__,
1432                           &uniSIDString,
1433                           ulSessionId,
1434                           ullProcessID,
1435                           ullThreadId);
1436
1437             uniGUID.Buffer = NULL;
1438
1439             RtlStringFromGUID( pSIDEntryCB->AuthGroup,
1440                                &uniGUID);
1441
1442             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1443                           AFS_TRACE_LEVEL_VERBOSE,
1444                           "%s Updating existing AuthGroup GUID %wZ\n",
1445                           __FUNCTION__,
1446                           &uniGUID);
1447
1448             if( uniGUID.Buffer != NULL)
1449             {
1450                 RtlFreeUnicodeString( &uniGUID);
1451             }
1452
1453             while( ExUuidCreate( &pSIDEntryCB->AuthGroup) == STATUS_RETRY);
1454
1455             uniGUID.Buffer = NULL;
1456
1457             RtlStringFromGUID( pSIDEntryCB->AuthGroup,
1458                                &uniGUID);
1459
1460             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1461                           AFS_TRACE_LEVEL_VERBOSE,
1462                           "%s Updated existing AuthGroup GUID %wZ\n",
1463                           __FUNCTION__,
1464                           &uniGUID);
1465
1466             if( uniGUID.Buffer != NULL)
1467             {
1468                 RtlFreeUnicodeString( &uniGUID);
1469             }
1470
1471             AFSReleaseResource( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock);
1472             try_return( ntStatus);
1473         }
1474
1475         pSIDEntryCB = (AFSSIDEntryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
1476                                                                  sizeof( AFSSIDEntryCB),
1477                                                                  AFS_AG_ENTRY_CB_TAG);
1478
1479         if( pSIDEntryCB == NULL)
1480         {
1481             AFSReleaseResource( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock);
1482             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1483         }
1484
1485         RtlZeroMemory( pSIDEntryCB,
1486                        sizeof( AFSSIDEntryCB));
1487
1488         pSIDEntryCB->TreeEntry.HashIndex = (ULONGLONG)ullTableHash;
1489
1490         while( ExUuidCreate( &pSIDEntryCB->AuthGroup) == STATUS_RETRY);
1491
1492         if( pDeviceExt->Specific.Control.AuthGroupTree.TreeHead == NULL)
1493         {
1494             pDeviceExt->Specific.Control.AuthGroupTree.TreeHead = (AFSBTreeEntry *)pSIDEntryCB;
1495         }
1496         else
1497         {
1498             AFSInsertHashEntry( pDeviceExt->Specific.Control.AuthGroupTree.TreeHead,
1499                                 &pSIDEntryCB->TreeEntry);
1500         }
1501
1502         AFSReleaseResource( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock);
1503
1504         uniGUID.Buffer = NULL;
1505
1506         RtlStringFromGUID( pSIDEntryCB->AuthGroup,
1507                            &uniGUID);
1508
1509         AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1510                       AFS_TRACE_LEVEL_VERBOSE,
1511                       "%s Created new AuthGroup GUID %wZ SID %wZ Session %08lX\n",
1512                       __FUNCTION__,
1513                       &uniGUID,
1514                       &uniSIDString,
1515                       ulSessionId);
1516
1517         if( uniGUID.Buffer != NULL)
1518         {
1519             RtlFreeUnicodeString( &uniGUID);
1520         }
1521
1522 try_exit:
1523
1524         if( uniCallerSID.Length > 0)
1525         {
1526             RtlFreeUnicodeString( &uniCallerSID);
1527         }
1528     }
1529
1530     return ntStatus;
1531 }
1532
1533 //
1534 // Given a SID and SessionId as input, returns the associated AuthGroup GUID.
1535 // If SID or SessionId are not specified, the current process values are used.
1536 //
1537
1538 NTSTATUS
1539 AFSQueryAuthGroup( IN AFSAuthGroupRequestCB *AuthGroup,
1540                    OUT GUID *AuthGroupGUID,
1541                    OUT ULONG_PTR *ReturnLength)
1542 {
1543
1544     NTSTATUS ntStatus = STATUS_SUCCESS;
1545     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
1546     ULONGLONG ullProcessID = (ULONGLONG)PsGetCurrentProcessId();
1547     UNICODE_STRING uniSIDString;
1548     ULONG ulSIDHash = 0;
1549     AFSSIDEntryCB *pSIDEntryCB = NULL;
1550     ULONG ulSessionId = 0;
1551     ULONGLONG ullTableHash = 0;
1552     BOOLEAN bReleaseSID = FALSE;
1553     UNICODE_STRING uniGUID;
1554     BOOLEAN bImpersonation = FALSE;
1555
1556     __Enter
1557     {
1558
1559         AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1560                       AFS_TRACE_LEVEL_VERBOSE,
1561                       "%s Entry for ProcessID %I64X\n",
1562                       __FUNCTION__,
1563                       ullProcessID);
1564
1565         if( AuthGroup == NULL ||
1566             AuthGroup->SIDLength == 0)
1567         {
1568
1569             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1570                           AFS_TRACE_LEVEL_VERBOSE,
1571                           "%s No SID specified, retrieving callers SID for ProcessID %I64X\n",
1572                           __FUNCTION__,
1573                           ullProcessID);
1574
1575             ntStatus = AFSGetCallerSID( &uniSIDString, &bImpersonation);
1576
1577             if( !NT_SUCCESS( ntStatus))
1578             {
1579
1580                 AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1581                               AFS_TRACE_LEVEL_ERROR,
1582                               "%s Failed to retrieve callers SID for ProcessID %I64X Status %08lX\n",
1583                               __FUNCTION__,
1584                               ullProcessID,
1585                               ntStatus);
1586
1587                 try_return( ntStatus);
1588             }
1589
1590             bReleaseSID = TRUE;
1591
1592             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1593                           AFS_TRACE_LEVEL_VERBOSE,
1594                           "%s Retrieved callers SID %wZ for ProcessID %I64X\n",
1595                           __FUNCTION__,
1596                           &uniSIDString,
1597                           ullProcessID);
1598         }
1599         else
1600         {
1601
1602             uniSIDString.Length = AuthGroup->SIDLength;
1603             uniSIDString.MaximumLength = uniSIDString.Length;
1604
1605             uniSIDString.Buffer = AuthGroup->SIDString;
1606
1607             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1608                           AFS_TRACE_LEVEL_VERBOSE,
1609                           "%s Using passed SID %wZ for ProcessID %I64X\n",
1610                           __FUNCTION__,
1611                           &uniSIDString,
1612                           ullProcessID);
1613         }
1614
1615         ntStatus = RtlHashUnicodeString( &uniSIDString,
1616                                          TRUE,
1617                                          HASH_STRING_ALGORITHM_DEFAULT,
1618                                          &ulSIDHash);
1619
1620         if( !NT_SUCCESS( ntStatus))
1621         {
1622
1623             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1624                           AFS_TRACE_LEVEL_ERROR,
1625                           "%s Failed to hash SID %wZ for ProcessID %I64X Status %08lX\n",
1626                           __FUNCTION__,
1627                           &uniSIDString,
1628                           ullProcessID,
1629                           ntStatus);
1630
1631             try_return( ntStatus);
1632         }
1633
1634         if( AuthGroup == NULL ||
1635             AuthGroup->SessionId == -1)
1636         {
1637
1638             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1639                           AFS_TRACE_LEVEL_VERBOSE,
1640                           "%s No SessionID specified, retrieving callers for ProcessID %I64X\n",
1641                           __FUNCTION__,
1642                           ullProcessID);
1643
1644             ulSessionId = AFSGetSessionId( (HANDLE)ullProcessID, &bImpersonation);
1645
1646             if( ulSessionId == (ULONG)-1)
1647             {
1648
1649                 AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1650                               AFS_TRACE_LEVEL_ERROR,
1651                               "%s Failed to retrieve callers Session ID for ProcessID %I64X\n",
1652                               __FUNCTION__,
1653                               ullProcessID);
1654
1655                 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1656             }
1657
1658             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1659                           AFS_TRACE_LEVEL_VERBOSE,
1660                           "%s Retrieved callers SessionID %08lX for ProcessID %I64X\n",
1661                           __FUNCTION__,
1662                           ulSessionId,
1663                           ullProcessID);
1664         }
1665         else
1666         {
1667             ulSessionId = AuthGroup->SessionId;
1668
1669             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1670                           AFS_TRACE_LEVEL_VERBOSE,
1671                           "%s Using passed SessionID %08lX for ProcessID %I64X\n",
1672                           __FUNCTION__,
1673                           ulSessionId,
1674                           ullProcessID);
1675         }
1676
1677         ullTableHash = ( ((ULONGLONG)ulSessionId << 32) | ulSIDHash);
1678
1679         AFSAcquireShared( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock,
1680                           TRUE);
1681
1682         ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.AuthGroupTree.TreeHead,
1683                                        (ULONGLONG)ullTableHash,
1684                                        (AFSBTreeEntry **)&pSIDEntryCB);
1685
1686         if( pSIDEntryCB == NULL)
1687         {
1688
1689             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1690                           AFS_TRACE_LEVEL_ERROR,
1691                           "%s Failed to locate SID entry for SID %wZ SessionID %08lX ProcessID %I64X\n",
1692                           __FUNCTION__,
1693                           &uniSIDString,
1694                           ulSessionId,
1695                           ullProcessID);
1696
1697             AFSReleaseResource( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock);
1698             try_return( ntStatus = STATUS_NOT_FOUND);
1699         }
1700
1701         RtlCopyMemory( AuthGroupGUID,
1702                        &pSIDEntryCB->AuthGroup,
1703                        sizeof( GUID));
1704
1705         *ReturnLength = sizeof( GUID);
1706
1707         uniGUID.Buffer = NULL;
1708
1709         RtlStringFromGUID( pSIDEntryCB->AuthGroup,
1710                            &uniGUID);
1711
1712         AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1713                       AFS_TRACE_LEVEL_VERBOSE,
1714                       "%s Retrieved AuthGroup GUID %wZ for ProcessID %I64X\n",
1715                       __FUNCTION__,
1716                       &uniGUID,
1717                       ullProcessID);
1718
1719         if( uniGUID.Buffer != NULL)
1720         {
1721             RtlFreeUnicodeString( &uniGUID);
1722         }
1723
1724         AFSReleaseResource( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock);
1725
1726 try_exit:
1727
1728         if( bReleaseSID &&
1729             uniSIDString.Length > 0)
1730         {
1731             RtlFreeUnicodeString( &uniSIDString);
1732         }
1733     }
1734
1735     return ntStatus;
1736 }