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