5656ad775ebadc0108f5e281be4054f313e15a2f
[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     GUID stAuthGroup;
433     UNICODE_STRING uniCallerSID;
434     BOOLEAN bImpersonation = FALSE;
435
436     __Enter
437     {
438
439         uniCallerSID.Length = 0;
440         uniCallerSID.MaximumLength = 0;
441         uniCallerSID.Buffer = NULL;
442
443         AFSAcquireShared( pDeviceExt->Specific.Control.ProcessTree.TreeLock,
444                           TRUE);
445
446         ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.ProcessTree.TreeHead,
447                                        (ULONGLONG)ullProcessID,
448                                        (AFSBTreeEntry **)&pProcessCB);
449
450         if( !NT_SUCCESS( ntStatus) ||
451             pProcessCB == NULL)
452         {
453
454             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
455                           AFS_TRACE_LEVEL_ERROR,
456                           "%s Failed to locate process CB for PID %I64X\n",
457                           __FUNCTION__,
458                           ullProcessID);
459
460             AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock);
461             try_return( ntStatus = STATUS_UNSUCCESSFUL);
462         }
463
464         AFSAcquireExcl( &pProcessCB->Lock,
465                         TRUE);
466
467         AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock);
468
469         ntStatus = AFSGetCallerSID( &uniCallerSID, &bImpersonation);
470
471         if( !NT_SUCCESS( ntStatus))
472         {
473
474             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
475                           AFS_TRACE_LEVEL_ERROR,
476                           "%s Failed to locate caller SID for PID %I64X Status %08lX\n",
477                           __FUNCTION__,
478                           ullProcessID,
479                           ntStatus);
480
481             try_return( ntStatus);
482         }
483
484         AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
485                       AFS_TRACE_LEVEL_VERBOSE,
486                       "%s Retrieved caller SID %wZ for PID %I64X\n",
487                       __FUNCTION__,
488                       &uniCallerSID,
489                       ullProcessID);
490
491
492         if( CreateSetAuthGroup->SIDLength != 0)
493         {
494
495             uniPassedSIDString.Length = CreateSetAuthGroup->SIDLength;
496             uniPassedSIDString.MaximumLength = uniPassedSIDString.Length;
497
498             uniPassedSIDString.Buffer = CreateSetAuthGroup->SIDString;
499
500             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
501                           AFS_TRACE_LEVEL_VERBOSE,
502                           "%s Validating passed SID %wZ for PID %I64X\n",
503                           __FUNCTION__,
504                           &uniPassedSIDString,
505                           ullProcessID);
506
507             if( RtlCompareUnicodeString( &uniCallerSID,
508                                          &uniPassedSIDString,
509                                          TRUE) != 0)
510             {
511
512                 if( !BooleanFlagOn( pProcessCB->Flags, AFS_PROCESS_LOCAL_SYSTEM_AUTH))
513                 {
514
515                     AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
516                                   AFS_TRACE_LEVEL_ERROR,
517                                   "%s Caller specified SID %wZ for PID %I64X but caller is not LOCAL SYSTEM AUTHORITY\n",
518                                   __FUNCTION__,
519                                   &uniPassedSIDString,
520                                   ullProcessID);
521
522                     try_return( ntStatus = STATUS_ACCESS_DENIED);
523                 }
524
525                 uniSIDString = uniPassedSIDString;
526
527                 AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
528                               AFS_TRACE_LEVEL_VERBOSE,
529                               "%s Using passed SID %wZ for PID %I64X\n",
530                               __FUNCTION__,
531                               &uniSIDString,
532                               ullProcessID);
533             }
534             else
535             {
536                 uniSIDString = uniCallerSID;
537
538                 AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
539                               AFS_TRACE_LEVEL_VERBOSE,
540                               "%s Caller and passed SID are equal SID %wZ for PID %I64X\n",
541                               __FUNCTION__,
542                               &uniSIDString,
543                               ullProcessID);
544             }
545         }
546         else
547         {
548             uniSIDString = uniCallerSID;
549
550             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
551                           AFS_TRACE_LEVEL_VERBOSE,
552                           "%s No SID passed, using callers SID %wZ for PID %I64X\n",
553                           __FUNCTION__,
554                           &uniSIDString,
555                           ullProcessID);
556         }
557
558         ntStatus = RtlHashUnicodeString( &uniSIDString,
559                                          TRUE,
560                                          HASH_STRING_ALGORITHM_DEFAULT,
561                                          &ulSIDHash);
562
563         if( !NT_SUCCESS( ntStatus))
564         {
565
566             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
567                           AFS_TRACE_LEVEL_ERROR,
568                           "%s Failed to hash SID %wZ for PID %I64X Status %08lX\n",
569                           __FUNCTION__,
570                           &uniSIDString,
571                           ullProcessID,
572                           ntStatus);
573
574             try_return( ntStatus);
575         }
576
577         ulSessionId = AFSGetSessionId( (HANDLE)ullProcessID, &bImpersonation);
578
579         if( ulSessionId == (ULONG)-1)
580         {
581
582             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
583                           AFS_TRACE_LEVEL_ERROR,
584                           "%s Failed to retrieve SessionID PID %I64X Status %08lX\n",
585                           __FUNCTION__,
586                           ullProcessID,
587                           ntStatus);
588
589             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
590         }
591
592         if( CreateSetAuthGroup->SessionId != (ULONG)-1)
593         {
594
595             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
596                           AFS_TRACE_LEVEL_VERBOSE,
597                           "%s Checking passed SessionID %08lX for PID %I64X\n",
598                           __FUNCTION__,
599                           CreateSetAuthGroup->SessionId,
600                           ullProcessID);
601
602             if( ulSessionId != CreateSetAuthGroup->SessionId)
603             {
604
605                 if( !BooleanFlagOn( pProcessCB->Flags, AFS_PROCESS_LOCAL_SYSTEM_AUTH))
606                 {
607
608                     AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
609                                   AFS_TRACE_LEVEL_ERROR,
610                                   "%s Passed SessionID %08lX for PID %I64X, failed because caller is not LOCAL SYSTEM AUTHORITY\n",
611                                   __FUNCTION__,
612                                   CreateSetAuthGroup->SessionId,
613                                   ullProcessID);
614
615                     try_return( ntStatus = STATUS_ACCESS_DENIED);
616                 }
617
618                 ulSessionId = CreateSetAuthGroup->SessionId;
619
620                 AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
621                               AFS_TRACE_LEVEL_VERBOSE,
622                               "%s Using passed SessionID %08lX for PID %I64X\n",
623                               __FUNCTION__,
624                               ulSessionId,
625                               ullProcessID);
626             }
627         }
628         else
629         {
630             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
631                           AFS_TRACE_LEVEL_VERBOSE,
632                           "%s Using callers SessionID %08lX for PID %I64X\n",
633                           __FUNCTION__,
634                           ulSessionId,
635                           ullProcessID);
636         }
637
638         ullTableHash = ( ((ULONGLONG)ulSessionId << 32) | ulSIDHash);
639
640         pAuthGroup = pProcessCB->AuthGroupList;
641
642         while( pAuthGroup != NULL)
643         {
644
645             if( pAuthGroup->AuthGroupHash == ullTableHash)
646             {
647                 break;
648             }
649
650             pLastAuthGroup = pAuthGroup;
651
652             pAuthGroup = pAuthGroup->Next;
653         }
654
655         if( pAuthGroup != NULL)
656         {
657
658             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
659                           AFS_TRACE_LEVEL_ERROR,
660                           "%s Located AuthGroup for SID %wZ SessionID %08lX for PID %I64X, failing request\n",
661                           __FUNCTION__,
662                           &uniSIDString,
663                           ulSessionId,
664                           ullProcessID);
665
666             try_return( ntStatus = STATUS_INVALID_PARAMETER);
667         }
668
669         pAuthGroup = (AFSProcessAuthGroupCB *)AFSExAllocatePoolWithTag( NonPagedPool,
670                                                                         sizeof( AFSProcessAuthGroupCB),
671                                                                         AFS_AG_ENTRY_CB_TAG);
672
673         if( pAuthGroup == NULL)
674         {
675             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
676         }
677
678         RtlZeroMemory( pAuthGroup,
679                        sizeof( AFSProcessAuthGroupCB));
680
681         pAuthGroup->AuthGroupHash = (ULONGLONG)ullTableHash;
682
683         while( ExUuidCreate( &pAuthGroup->AuthGroup) == STATUS_RETRY);
684
685         if( pLastAuthGroup == NULL)
686         {
687             pProcessCB->AuthGroupList = pAuthGroup;
688         }
689         else
690         {
691             pLastAuthGroup->Next = pAuthGroup;
692         }
693
694         AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
695                       AFS_TRACE_LEVEL_VERBOSE,
696                       "%s Allocated new AuthGroup for SID %wZ SessionID %08lX for PID %I64X\n",
697                       __FUNCTION__,
698                       &uniSIDString,
699                       ulSessionId,
700                       ullProcessID);
701
702         if( BooleanFlagOn( CreateSetAuthGroup->Flags, AFS_PAG_FLAGS_THREAD_AUTH_GROUP))
703         {
704
705             pThreadCB = pProcessCB->ThreadList;
706
707             while( pThreadCB != NULL)
708             {
709
710                 if( pThreadCB->ThreadId == ullThreadId)
711                 {
712                     pThreadCB->ActiveAuthGroup = &pAuthGroup->AuthGroup;
713                     break;
714                 }
715
716                 pThreadCB = pThreadCB->Next;
717             }
718
719             if( pThreadCB == NULL)
720             {
721
722                 pThreadCB = AFSInitializeThreadCB( pProcessCB,
723                                                    ullThreadId);
724
725                 if( pThreadCB == NULL)
726                 {
727                     try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
728                 }
729
730                 pThreadCB->ActiveAuthGroup = &pAuthGroup->AuthGroup;
731             }
732
733             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
734                           AFS_TRACE_LEVEL_VERBOSE,
735                           "%s Set new AuthGroup for SID %wZ SessionID %08lX for PID %I64X on thread ID %I64X\n",
736                           __FUNCTION__,
737                           &uniSIDString,
738                           ulSessionId,
739                           ullProcessID,
740                           ullThreadId);
741         }
742         else if( BooleanFlagOn( CreateSetAuthGroup->Flags, AFS_PAG_FLAGS_SET_AS_ACTIVE))
743         {
744             pProcessCB->ActiveAuthGroup = &pAuthGroup->AuthGroup;
745
746             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
747                           AFS_TRACE_LEVEL_VERBOSE,
748                           "%s Set new AuthGroup for SID %wZ SessionID %08lX for PID %I64X on process\n",
749                           __FUNCTION__,
750                           &uniSIDString,
751                           ulSessionId,
752                           ullProcessID);
753         }
754
755 try_exit:
756
757         if( pProcessCB != NULL)
758         {
759             AFSReleaseResource( &pProcessCB->Lock);
760         }
761
762         if( uniCallerSID.Length > 0)
763         {
764             RtlFreeUnicodeString( &uniCallerSID);
765         }
766     }
767
768     return ntStatus;
769 }
770
771 //
772 // Returns a list of the AuthGroup GUIDS associated
773 // with the current process, the current process GUID,
774 // and the current thread GUID.
775 //
776
777 NTSTATUS
778 AFSQueryProcessAuthGroupList( IN GUID *GUIDList,
779                               IN ULONG BufferLength,
780                               OUT ULONG_PTR *ReturnLength)
781 {
782
783     NTSTATUS ntStatus = STATUS_SUCCESS;
784     AFSProcessCB *pProcessCB = NULL;
785     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
786     ULONGLONG ullProcessID = (ULONGLONG)PsGetCurrentProcessId();
787     ULONG ulRequiredLength = 0;
788     AFSProcessAuthGroupCB *pAuthGroup = NULL;
789     GUID *pCurrentGUID = GUIDList;
790     UNICODE_STRING uniGUIDString;
791
792     __Enter
793     {
794
795         AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
796                       AFS_TRACE_LEVEL_VERBOSE,
797                       "%s Entry for PID %I64X\n",
798                       __FUNCTION__,
799                       ullProcessID);
800
801         AFSAcquireShared( pDeviceExt->Specific.Control.ProcessTree.TreeLock,
802                           TRUE);
803
804         ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.ProcessTree.TreeHead,
805                                        (ULONGLONG)ullProcessID,
806                                        (AFSBTreeEntry **)&pProcessCB);
807
808         if( !NT_SUCCESS( ntStatus) ||
809             pProcessCB == NULL)
810         {
811
812             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
813                           AFS_TRACE_LEVEL_ERROR,
814                           "%s Failed to locate process entry PID %I64X\n",
815                           __FUNCTION__,
816                           ullProcessID);
817
818             AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock);
819             try_return( ntStatus = STATUS_UNSUCCESSFUL);
820         }
821
822         AFSAcquireShared( &pProcessCB->Lock,
823                           TRUE);
824
825         AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock);
826
827         pAuthGroup = pProcessCB->AuthGroupList;
828
829         ulRequiredLength = 0;
830
831         while( pAuthGroup != NULL)
832         {
833             ulRequiredLength += sizeof( GUID);
834             pAuthGroup = pAuthGroup->Next;
835         }
836
837         if( BufferLength == 0 ||
838             BufferLength < ulRequiredLength ||
839             GUIDList == NULL)
840         {
841
842             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
843                           AFS_TRACE_LEVEL_VERBOSE,
844                           "%s Buffer too small for query, required %08lX for PID %I64X\n",
845                           __FUNCTION__,
846                           ulRequiredLength,
847                           ullProcessID);
848
849             *ReturnLength = ulRequiredLength;
850             try_return( ntStatus = STATUS_BUFFER_OVERFLOW);
851         }
852
853         pAuthGroup = pProcessCB->AuthGroupList;
854
855         *ReturnLength = 0;
856
857         while( pAuthGroup != NULL)
858         {
859             RtlCopyMemory( pCurrentGUID,
860                            &pAuthGroup->AuthGroup,
861                            sizeof( GUID));
862
863             uniGUIDString.Buffer = NULL;
864             uniGUIDString.Length = 0;
865             uniGUIDString.MaximumLength = 0;
866
867             RtlStringFromGUID( pAuthGroup->AuthGroup,
868                                &uniGUIDString);
869
870             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
871                           AFS_TRACE_LEVEL_VERBOSE,
872                           "%s Adding AuthGroup %wZ for PID %I64X\n",
873                           __FUNCTION__,
874                           &uniGUIDString,
875                           ullProcessID);
876
877             if( uniGUIDString.Buffer != NULL)
878             {
879                 RtlFreeUnicodeString( &uniGUIDString);
880             }
881
882             pCurrentGUID = (GUID *)((char *)pCurrentGUID + sizeof( GUID));
883
884             *ReturnLength += sizeof( GUID);
885
886             pAuthGroup = pAuthGroup->Next;
887         }
888
889 try_exit:
890
891         if( pProcessCB != NULL)
892         {
893             AFSReleaseResource( &pProcessCB->Lock);
894         }
895     }
896
897     return ntStatus;
898 }
899
900 //
901 // Permits the current AuthGroup for the process or
902 // thread to be set to the specified GUID.  The GUID
903 // must be in the list of current values for the process.
904 //
905
906 NTSTATUS
907 AFSSetActiveProcessAuthGroup( IN AFSAuthGroupRequestCB *ActiveAuthGroup)
908 {
909
910     NTSTATUS ntStatus = STATUS_SUCCESS;
911     AFSProcessCB *pProcessCB = NULL;
912     AFSThreadCB *pThreadCB = NULL;
913     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
914     ULONGLONG ullProcessID = (ULONGLONG)PsGetCurrentProcessId();
915     ULONGLONG ullThreadId = (ULONGLONG)PsGetCurrentThreadId();
916     AFSProcessAuthGroupCB *pAuthGroup = NULL;
917     UNICODE_STRING uniGUIDString;
918
919     __Enter
920     {
921
922         uniGUIDString.Length = 0;
923         uniGUIDString.MaximumLength = 0;
924         uniGUIDString.Buffer = NULL;
925
926         RtlStringFromGUID( ActiveAuthGroup->AuthGroup,
927                            &uniGUIDString);
928
929         AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
930                       AFS_TRACE_LEVEL_VERBOSE,
931                       "%s Entry for ProcessID %I64X AuthGroup GUID %wZ\n",
932                       __FUNCTION__,
933                       ullProcessID,
934                       &uniGUIDString);
935
936         AFSAcquireShared( pDeviceExt->Specific.Control.ProcessTree.TreeLock,
937                           TRUE);
938
939         ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.ProcessTree.TreeHead,
940                                        (ULONGLONG)ullProcessID,
941                                        (AFSBTreeEntry **)&pProcessCB);
942
943         if( !NT_SUCCESS( ntStatus) ||
944             pProcessCB == NULL)
945         {
946
947             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
948                           AFS_TRACE_LEVEL_ERROR,
949                           "%s Failed to locate process entry for ProcessID %I64X\n",
950                           __FUNCTION__,
951                           ullProcessID);
952
953             AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock);
954             try_return( ntStatus = STATUS_UNSUCCESSFUL);
955         }
956
957
958         AFSAcquireExcl( &pProcessCB->Lock,
959                         TRUE);
960
961         AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock);
962
963         pAuthGroup = pProcessCB->AuthGroupList;
964
965         while( pAuthGroup != NULL)
966         {
967
968             if( RtlCompareMemory( &ActiveAuthGroup->AuthGroup,
969                                   &pAuthGroup->AuthGroup,
970                                   sizeof( GUID)) == sizeof( GUID))
971             {
972                 break;
973             }
974             pAuthGroup = pAuthGroup->Next;
975         }
976
977         if( pAuthGroup == NULL)
978         {
979
980             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
981                           AFS_TRACE_LEVEL_VERBOSE,
982                           "%s Failed to locate AuthGroup for ProcessID %I64X AuthGroup GUID %wZ\n",
983                           __FUNCTION__,
984                           ullProcessID,
985                           &uniGUIDString);
986
987             try_return( ntStatus = STATUS_INVALID_PARAMETER);
988         }
989
990         if( BooleanFlagOn( ActiveAuthGroup->Flags, AFS_PAG_FLAGS_THREAD_AUTH_GROUP))
991         {
992
993             pThreadCB = pProcessCB->ThreadList;
994
995             while( pThreadCB != NULL)
996             {
997
998                 if( pThreadCB->ThreadId == ullThreadId)
999                 {
1000                     pThreadCB->ActiveAuthGroup = &pAuthGroup->AuthGroup;
1001                     break;
1002                 }
1003
1004                 pThreadCB = pThreadCB->Next;
1005             }
1006
1007             if( pThreadCB == NULL)
1008             {
1009
1010                 pThreadCB = AFSInitializeThreadCB( pProcessCB,
1011                                                    ullThreadId);
1012
1013                 if( pThreadCB == NULL)
1014                 {
1015                     try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1016                 }
1017
1018                 pThreadCB->ActiveAuthGroup = &pAuthGroup->AuthGroup;
1019             }
1020
1021             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1022                           AFS_TRACE_LEVEL_VERBOSE,
1023                           "%s Set active AuthGroup for ProcessID %I64X AuthGroup GUID %wZ on thread %I64X\n",
1024                           __FUNCTION__,
1025                           ullProcessID,
1026                           &uniGUIDString,
1027                           ullThreadId);
1028         }
1029         else
1030         {
1031             pProcessCB->ActiveAuthGroup = &pAuthGroup->AuthGroup;
1032
1033             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1034                           AFS_TRACE_LEVEL_VERBOSE,
1035                           "%s Set active AuthGroup for ProcessID %I64X AuthGroup GUID %wZ on process\n",
1036                           __FUNCTION__,
1037                           ullProcessID,
1038                           &uniGUIDString);
1039         }
1040
1041 try_exit:
1042
1043         if( pProcessCB != NULL)
1044         {
1045             AFSReleaseResource( &pProcessCB->Lock);
1046         }
1047
1048         if( uniGUIDString.Buffer != NULL)
1049         {
1050             RtlFreeUnicodeString( &uniGUIDString);
1051         }
1052     }
1053
1054     return ntStatus;
1055 }
1056
1057 //
1058 // Resets the current AuthGroup for the process or
1059 // thread to the SID-AuthGroup
1060 //
1061
1062 NTSTATUS
1063 AFSResetActiveProcessAuthGroup( IN IN AFSAuthGroupRequestCB *AuthGroup)
1064 {
1065
1066     NTSTATUS ntStatus = STATUS_SUCCESS;
1067     GUID *pAuthGroup = NULL;
1068     AFSProcessCB *pProcessCB = NULL;
1069     AFSThreadCB *pThreadCB = NULL;
1070     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
1071     ULONGLONG ullProcessID = (ULONGLONG)PsGetCurrentProcessId();
1072     ULONGLONG ullThreadId = (ULONGLONG)PsGetCurrentThreadId();
1073
1074     __Enter
1075     {
1076
1077         AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1078                       AFS_TRACE_LEVEL_VERBOSE,
1079                       "%s Entry for ProcessID %I64X\n",
1080                       __FUNCTION__,
1081                       ullProcessID);
1082
1083         AFSAcquireShared( pDeviceExt->Specific.Control.ProcessTree.TreeLock,
1084                           TRUE);
1085
1086         ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.ProcessTree.TreeHead,
1087                                        (ULONGLONG)ullProcessID,
1088                                        (AFSBTreeEntry **)&pProcessCB);
1089
1090         if( !NT_SUCCESS( ntStatus) ||
1091             pProcessCB == NULL)
1092         {
1093
1094             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1095                           AFS_TRACE_LEVEL_ERROR,
1096                           "%s Failed to locate AuthGroup for ProcessID %I64X\n",
1097                           __FUNCTION__,
1098                           ullProcessID);
1099
1100             AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock);
1101             try_return( ntStatus = STATUS_UNSUCCESSFUL);
1102         }
1103
1104         AFSAcquireExcl( &pProcessCB->Lock,
1105                         TRUE);
1106
1107         AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock);
1108
1109         if( BooleanFlagOn( AuthGroup->Flags, AFS_PAG_FLAGS_THREAD_AUTH_GROUP))
1110         {
1111
1112             pThreadCB = pProcessCB->ThreadList;
1113
1114             while( pThreadCB != NULL)
1115             {
1116
1117                 if( pThreadCB->ThreadId == ullThreadId)
1118                 {
1119                     pThreadCB->ActiveAuthGroup = NULL;
1120                     break;
1121                 }
1122
1123                 pThreadCB = pThreadCB->Next;
1124             }
1125
1126             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1127                           AFS_TRACE_LEVEL_VERBOSE,
1128                           "%s Reset AuthGroup list on thread %I64X for ProcessID %I64X\n",
1129                           __FUNCTION__,
1130                           ullThreadId,
1131                           ullProcessID);
1132         }
1133         else
1134         {
1135             pProcessCB->ActiveAuthGroup = NULL;
1136
1137             pThreadCB = pProcessCB->ThreadList;
1138
1139             while( pThreadCB != NULL)
1140             {
1141                 pThreadCB->ActiveAuthGroup = NULL;
1142                 pThreadCB = pThreadCB->Next;
1143             }
1144
1145             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1146                           AFS_TRACE_LEVEL_VERBOSE,
1147                           "%s Reset AuthGroup list on process for ProcessID %I64X\n",
1148                           __FUNCTION__,
1149                           ullProcessID);
1150         }
1151
1152         AFSReleaseResource( &pProcessCB->Lock);
1153
1154 try_exit:
1155
1156         NOTHING;
1157     }
1158
1159     return ntStatus;
1160 }
1161
1162 //
1163 // When bLogonSession == FALSE, the SID must not be specified
1164 // and the SessionId must be -1.  A new AuthGroup GUID is
1165 // assigned to the SID and SessionId of the calling Process.
1166 //
1167 // When bLogonSession == TRUE, the SID must be specified and
1168 // the SessionId must not be -1.  The SID of the calling process
1169 // must be LOCAL_SYSTEM and a new AuthGroup GUID is assigned to
1170 // the specified SID and logon session.
1171 //
1172
1173 NTSTATUS
1174 AFSCreateAuthGroupForSIDorLogonSession( IN AFSAuthGroupRequestCB *AuthGroupRequestCB,
1175                                         IN BOOLEAN bLogonSession)
1176 {
1177
1178     NTSTATUS ntStatus = STATUS_SUCCESS;
1179     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
1180     ULONGLONG ullProcessID = (ULONGLONG)PsGetCurrentProcessId();
1181     ULONGLONG ullThreadId = (ULONGLONG)PsGetCurrentThreadId();
1182     UNICODE_STRING uniSIDString, uniPassedSIDString;
1183     ULONG ulSIDHash = 0;
1184     AFSSIDEntryCB *pSIDEntryCB = NULL;
1185     ULONG ulSessionId = 0;
1186     ULONGLONG ullTableHash = 0;
1187     GUID stAuthGroup;
1188     UNICODE_STRING uniCallerSID;
1189     UNICODE_STRING uniGUID;
1190     BOOLEAN bLocalSystem = FALSE;
1191     BOOLEAN bImpersonation = FALSE;
1192
1193     __Enter
1194     {
1195
1196         AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1197                       AFS_TRACE_LEVEL_VERBOSE,
1198                       "%s Entry for ProcessID %I64X ThreadID %I64X\n",
1199                       __FUNCTION__,
1200                       ullProcessID,
1201                       ullThreadId);
1202
1203         ntStatus = AFSGetCallerSID( &uniCallerSID, &bImpersonation);
1204
1205         if( !NT_SUCCESS( ntStatus))
1206         {
1207
1208             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1209                           AFS_TRACE_LEVEL_ERROR,
1210                           "%s Failed to retrieve callers SID for ProcessID %I64X ThreadID %I64X Status %08lX\n",
1211                           __FUNCTION__,
1212                           ullProcessID,
1213                           ullThreadId,
1214                           ntStatus);
1215
1216             try_return( ntStatus);
1217         }
1218
1219         bLocalSystem = AFSIsLocalSystemSID( &uniCallerSID);
1220
1221         if( bLogonSession == TRUE &&
1222             bLocalSystem == FALSE)
1223         {
1224
1225             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1226                           AFS_TRACE_LEVEL_ERROR,
1227                           "%s caller is %wZ and LOCAL SYSTEM AUTHORITY required\n",
1228                           __FUNCTION__,
1229                           uniCallerSID);
1230
1231             try_return( ntStatus = STATUS_ACCESS_DENIED);
1232         }
1233
1234         if ( bLogonSession == TRUE &&
1235              ( AuthGroupRequestCB == NULL ||
1236                AuthGroupRequestCB->SIDLength == 0 ||
1237                AuthGroupRequestCB->SessionId == (ULONG)-1))
1238         {
1239
1240             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1241                           AFS_TRACE_LEVEL_ERROR,
1242                           "%s SID and SessionId are mandatory\n",
1243                           __FUNCTION__);
1244
1245             try_return( ntStatus = STATUS_INVALID_PARAMETER);
1246         }
1247
1248         if ( bLogonSession == FALSE &&
1249              AuthGroupRequestCB != NULL &&
1250              ( AuthGroupRequestCB->SIDLength > 0 ||
1251                AuthGroupRequestCB->SessionId != (ULONG)-1))
1252         {
1253
1254             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1255                           AFS_TRACE_LEVEL_ERROR,
1256                           "%s SID and SessionId must not be specified\n",
1257                           __FUNCTION__);
1258
1259             try_return( ntStatus = STATUS_INVALID_PARAMETER);
1260         }
1261
1262
1263         AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1264                       AFS_TRACE_LEVEL_VERBOSE,
1265                       "%s Retrieved callers SID %wZ for ProcessID %I64X ThreadID %I64X\n",
1266                       __FUNCTION__,
1267                       &uniCallerSID,
1268                       ullProcessID,
1269                       ullThreadId);
1270
1271         if( AuthGroupRequestCB != NULL &&
1272             AuthGroupRequestCB->SIDLength != 0)
1273         {
1274
1275             uniPassedSIDString.Length = AuthGroupRequestCB->SIDLength;
1276             uniPassedSIDString.MaximumLength = uniPassedSIDString.Length;
1277
1278             uniPassedSIDString.Buffer = AuthGroupRequestCB->SIDString;
1279
1280             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1281                           AFS_TRACE_LEVEL_VERBOSE,
1282                           "%s Checking passed SID %wZ for ProcessID %I64X ThreadID %I64X\n",
1283                           __FUNCTION__,
1284                           &uniPassedSIDString,
1285                           ullProcessID,
1286                           ullThreadId);
1287
1288             if( RtlCompareUnicodeString( &uniCallerSID,
1289                                          &uniPassedSIDString,
1290                                          TRUE) != 0)
1291             {
1292
1293                 if( !bLocalSystem)
1294                 {
1295
1296                     AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1297                                   AFS_TRACE_LEVEL_ERROR,
1298                                   "%s Not using passed SID %wZ for ProcessID %I64X ThreadID %I64X caller is not LOCAL SYSTEM AUTHORITY\n",
1299                                   __FUNCTION__,
1300                                   &uniPassedSIDString,
1301                                   ullProcessID,
1302                                   ullThreadId);
1303
1304                     try_return( ntStatus = STATUS_ACCESS_DENIED);
1305                 }
1306
1307                 uniSIDString = uniPassedSIDString;
1308
1309                 AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1310                               AFS_TRACE_LEVEL_VERBOSE,
1311                               "%s Using passed SID %wZ for ProcessID %I64X ThreadID %I64X\n",
1312                               __FUNCTION__,
1313                               &uniSIDString,
1314                               ullProcessID,
1315                               ullThreadId);
1316             }
1317             else
1318             {
1319                 uniSIDString = uniCallerSID;
1320
1321                 AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1322                               AFS_TRACE_LEVEL_VERBOSE,
1323                               "%s Both SIDs are equal, using callers SID %wZ for ProcessID %I64X ThreadID %I64X\n",
1324                               __FUNCTION__,
1325                               &uniSIDString,
1326                               ullProcessID,
1327                               ullThreadId);
1328             }
1329         }
1330         else
1331         {
1332             uniSIDString = uniCallerSID;
1333
1334             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1335                           AFS_TRACE_LEVEL_VERBOSE,
1336                           "%s Using callers SID %wZ for ProcessID %I64X ThreadID %I64X\n",
1337                           __FUNCTION__,
1338                           &uniSIDString,
1339                           ullProcessID,
1340                           ullThreadId);
1341         }
1342
1343         ntStatus = RtlHashUnicodeString( &uniSIDString,
1344                                          TRUE,
1345                                          HASH_STRING_ALGORITHM_DEFAULT,
1346                                          &ulSIDHash);
1347
1348         if( !NT_SUCCESS( ntStatus))
1349         {
1350
1351             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1352                           AFS_TRACE_LEVEL_ERROR,
1353                           "%s Failed to hash SID %wZ for ProcessID %I64X ThreadID %I64X Status %08lX\n",
1354                           __FUNCTION__,
1355                           &uniSIDString,
1356                           ullProcessID,
1357                           ullThreadId,
1358                           ntStatus);
1359
1360             try_return( ntStatus);
1361         }
1362
1363         ulSessionId = AFSGetSessionId( (HANDLE)ullProcessID, &bImpersonation);
1364
1365         if( ulSessionId == (ULONG)-1)
1366         {
1367
1368             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1369                           AFS_TRACE_LEVEL_ERROR,
1370                           "%s Failed to retrieve session ID for ProcessID %I64X ThreadID %I64X\n",
1371                           __FUNCTION__,
1372                           ullProcessID,
1373                           ullThreadId);
1374
1375             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1376         }
1377
1378         if( bLogonSession == TRUE &&
1379             AuthGroupRequestCB != NULL &&
1380             AuthGroupRequestCB->SessionId != (ULONG)-1)
1381         {
1382
1383             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1384                           AFS_TRACE_LEVEL_VERBOSE,
1385                           "%s Checking passed SessionID %08lX for ProcessID %I64X ThreadID %I64X\n",
1386                           __FUNCTION__,
1387                           AuthGroupRequestCB->SessionId,
1388                           ullProcessID,
1389                           ullThreadId);
1390
1391             if( ulSessionId != AuthGroupRequestCB->SessionId)
1392             {
1393
1394                 ulSessionId = AuthGroupRequestCB->SessionId;
1395
1396                 AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1397                               AFS_TRACE_LEVEL_VERBOSE,
1398                               "%s Using passed SessionID %08lX for ProcessID %I64X ThreadID %I64X\n",
1399                               __FUNCTION__,
1400                               AuthGroupRequestCB->SessionId,
1401                               ullProcessID,
1402                               ullThreadId);
1403             }
1404         }
1405         else
1406         {
1407
1408             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1409                           AFS_TRACE_LEVEL_VERBOSE,
1410                           "%s Using callers SessionID %08lX for ProcessID %I64X ThreadID %I64X\n",
1411                           __FUNCTION__,
1412                           ulSessionId,
1413                           ullProcessID,
1414                           ullThreadId);
1415         }
1416
1417         ullTableHash = ( ((ULONGLONG)ulSessionId << 32) | ulSIDHash);
1418
1419         AFSAcquireExcl( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock,
1420                         TRUE);
1421
1422         ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.AuthGroupTree.TreeHead,
1423                                        (ULONGLONG)ullTableHash,
1424                                        (AFSBTreeEntry **)&pSIDEntryCB);
1425
1426         if( NT_SUCCESS( ntStatus) &&
1427             pSIDEntryCB != NULL)
1428         {
1429
1430             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1431                           AFS_TRACE_LEVEL_VERBOSE,
1432                           "%s Located SID entry for SID %wZ SessionID %08lX ProcessID %I64X ThreadID %I64X, updating GUID\n",
1433                           __FUNCTION__,
1434                           &uniSIDString,
1435                           ulSessionId,
1436                           ullProcessID,
1437                           ullThreadId);
1438
1439             uniGUID.Buffer = NULL;
1440
1441             RtlStringFromGUID( pSIDEntryCB->AuthGroup,
1442                                &uniGUID);
1443
1444             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1445                           AFS_TRACE_LEVEL_VERBOSE,
1446                           "%s Updating existing AuthGroup GUID %wZ\n",
1447                           __FUNCTION__,
1448                           &uniGUID);
1449
1450             if( uniGUID.Buffer != NULL)
1451             {
1452                 RtlFreeUnicodeString( &uniGUID);
1453             }
1454
1455             while( ExUuidCreate( &pSIDEntryCB->AuthGroup) == STATUS_RETRY);
1456
1457             uniGUID.Buffer = NULL;
1458
1459             RtlStringFromGUID( pSIDEntryCB->AuthGroup,
1460                                &uniGUID);
1461
1462             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1463                           AFS_TRACE_LEVEL_VERBOSE,
1464                           "%s Updated existing AuthGroup GUID %wZ\n",
1465                           __FUNCTION__,
1466                           &uniGUID);
1467
1468             if( uniGUID.Buffer != NULL)
1469             {
1470                 RtlFreeUnicodeString( &uniGUID);
1471             }
1472
1473             AFSReleaseResource( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock);
1474             try_return( ntStatus);
1475         }
1476
1477         pSIDEntryCB = (AFSSIDEntryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
1478                                                                  sizeof( AFSSIDEntryCB),
1479                                                                  AFS_AG_ENTRY_CB_TAG);
1480
1481         if( pSIDEntryCB == NULL)
1482         {
1483             AFSReleaseResource( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock);
1484             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1485         }
1486
1487         RtlZeroMemory( pSIDEntryCB,
1488                        sizeof( AFSSIDEntryCB));
1489
1490         pSIDEntryCB->TreeEntry.HashIndex = (ULONGLONG)ullTableHash;
1491
1492         while( ExUuidCreate( &pSIDEntryCB->AuthGroup) == STATUS_RETRY);
1493
1494         if( pDeviceExt->Specific.Control.AuthGroupTree.TreeHead == NULL)
1495         {
1496             pDeviceExt->Specific.Control.AuthGroupTree.TreeHead = (AFSBTreeEntry *)pSIDEntryCB;
1497         }
1498         else
1499         {
1500             AFSInsertHashEntry( pDeviceExt->Specific.Control.AuthGroupTree.TreeHead,
1501                                 &pSIDEntryCB->TreeEntry);
1502         }
1503
1504         AFSReleaseResource( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock);
1505
1506         uniGUID.Buffer = NULL;
1507
1508         RtlStringFromGUID( pSIDEntryCB->AuthGroup,
1509                            &uniGUID);
1510
1511         AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1512                       AFS_TRACE_LEVEL_VERBOSE,
1513                       "%s Created new AuthGroup GUID %wZ SID %wZ Session %08lX\n",
1514                       __FUNCTION__,
1515                       &uniGUID,
1516                       &uniSIDString,
1517                       ulSessionId);
1518
1519         if( uniGUID.Buffer != NULL)
1520         {
1521             RtlFreeUnicodeString( &uniGUID);
1522         }
1523
1524 try_exit:
1525
1526         if( uniCallerSID.Length > 0)
1527         {
1528             RtlFreeUnicodeString( &uniCallerSID);
1529         }
1530     }
1531
1532     return ntStatus;
1533 }
1534
1535 //
1536 // Given a SID and SessionId as input, returns the associated AuthGroup GUID.
1537 // If SID or SessionId are not specified, the current process values are used.
1538 //
1539
1540 NTSTATUS
1541 AFSQueryAuthGroup( IN AFSAuthGroupRequestCB *AuthGroup,
1542                    OUT GUID *AuthGroupGUID,
1543                    OUT ULONG_PTR *ReturnLength)
1544 {
1545
1546     NTSTATUS ntStatus = STATUS_SUCCESS;
1547     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
1548     ULONGLONG ullProcessID = (ULONGLONG)PsGetCurrentProcessId();
1549     UNICODE_STRING uniSIDString;
1550     ULONG ulSIDHash = 0;
1551     AFSSIDEntryCB *pSIDEntryCB = NULL;
1552     ULONG ulSessionId = 0;
1553     ULONGLONG ullTableHash = 0;
1554     BOOLEAN bReleaseSID = FALSE;
1555     UNICODE_STRING uniGUID;
1556     BOOLEAN bImpersonation = FALSE;
1557
1558     __Enter
1559     {
1560
1561         AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1562                       AFS_TRACE_LEVEL_VERBOSE,
1563                       "%s Entry for ProcessID %I64X\n",
1564                       __FUNCTION__,
1565                       ullProcessID);
1566
1567         if( AuthGroup == NULL ||
1568             AuthGroup->SIDLength == 0)
1569         {
1570
1571             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1572                           AFS_TRACE_LEVEL_VERBOSE,
1573                           "%s No SID specified, retrieving callers SID for ProcessID %I64X\n",
1574                           __FUNCTION__,
1575                           ullProcessID);
1576
1577             ntStatus = AFSGetCallerSID( &uniSIDString, &bImpersonation);
1578
1579             if( !NT_SUCCESS( ntStatus))
1580             {
1581
1582                 AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1583                               AFS_TRACE_LEVEL_ERROR,
1584                               "%s Failed to retrieve callers SID for ProcessID %I64X Status %08lX\n",
1585                               __FUNCTION__,
1586                               ullProcessID,
1587                               ntStatus);
1588
1589                 try_return( ntStatus);
1590             }
1591
1592             bReleaseSID = TRUE;
1593
1594             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1595                           AFS_TRACE_LEVEL_VERBOSE,
1596                           "%s Retrieved callers SID %wZ for ProcessID %I64X\n",
1597                           __FUNCTION__,
1598                           &uniSIDString,
1599                           ullProcessID);
1600         }
1601         else
1602         {
1603
1604             uniSIDString.Length = AuthGroup->SIDLength;
1605             uniSIDString.MaximumLength = uniSIDString.Length;
1606
1607             uniSIDString.Buffer = AuthGroup->SIDString;
1608
1609             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1610                           AFS_TRACE_LEVEL_VERBOSE,
1611                           "%s Using passed SID %wZ for ProcessID %I64X\n",
1612                           __FUNCTION__,
1613                           &uniSIDString,
1614                           ullProcessID);
1615         }
1616
1617         ntStatus = RtlHashUnicodeString( &uniSIDString,
1618                                          TRUE,
1619                                          HASH_STRING_ALGORITHM_DEFAULT,
1620                                          &ulSIDHash);
1621
1622         if( !NT_SUCCESS( ntStatus))
1623         {
1624
1625             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1626                           AFS_TRACE_LEVEL_ERROR,
1627                           "%s Failed to hash SID %wZ for ProcessID %I64X Status %08lX\n",
1628                           __FUNCTION__,
1629                           &uniSIDString,
1630                           ullProcessID,
1631                           ntStatus);
1632
1633             try_return( ntStatus);
1634         }
1635
1636         if( AuthGroup == NULL ||
1637             AuthGroup->SessionId == -1)
1638         {
1639
1640             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1641                           AFS_TRACE_LEVEL_VERBOSE,
1642                           "%s No SessionID specified, retrieving callers for ProcessID %I64X\n",
1643                           __FUNCTION__,
1644                           ullProcessID);
1645
1646             ulSessionId = AFSGetSessionId( (HANDLE)ullProcessID, &bImpersonation);
1647
1648             if( ulSessionId == (ULONG)-1)
1649             {
1650
1651                 AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1652                               AFS_TRACE_LEVEL_ERROR,
1653                               "%s Failed to retrieve callers Session ID for ProcessID %I64X\n",
1654                               __FUNCTION__,
1655                               ullProcessID);
1656
1657                 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1658             }
1659
1660             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1661                           AFS_TRACE_LEVEL_VERBOSE,
1662                           "%s Retrieved callers SessionID %08lX for ProcessID %I64X\n",
1663                           __FUNCTION__,
1664                           ulSessionId,
1665                           ullProcessID);
1666         }
1667         else
1668         {
1669             ulSessionId = AuthGroup->SessionId;
1670
1671             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1672                           AFS_TRACE_LEVEL_VERBOSE,
1673                           "%s Using passed SessionID %08lX for ProcessID %I64X\n",
1674                           __FUNCTION__,
1675                           ulSessionId,
1676                           ullProcessID);
1677         }
1678
1679         ullTableHash = ( ((ULONGLONG)ulSessionId << 32) | ulSIDHash);
1680
1681         AFSAcquireShared( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock,
1682                           TRUE);
1683
1684         ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.AuthGroupTree.TreeHead,
1685                                        (ULONGLONG)ullTableHash,
1686                                        (AFSBTreeEntry **)&pSIDEntryCB);
1687
1688         if( pSIDEntryCB == NULL)
1689         {
1690
1691             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1692                           AFS_TRACE_LEVEL_ERROR,
1693                           "%s Failed to locate SID entry for SID %wZ SessionID %08lX ProcessID %I64X\n",
1694                           __FUNCTION__,
1695                           &uniSIDString,
1696                           ulSessionId,
1697                           ullProcessID);
1698
1699             AFSReleaseResource( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock);
1700             try_return( ntStatus = STATUS_NOT_FOUND);
1701         }
1702
1703         RtlCopyMemory( AuthGroupGUID,
1704                        &pSIDEntryCB->AuthGroup,
1705                        sizeof( GUID));
1706
1707         *ReturnLength = sizeof( GUID);
1708
1709         uniGUID.Buffer = NULL;
1710
1711         RtlStringFromGUID( pSIDEntryCB->AuthGroup,
1712                            &uniGUID);
1713
1714         AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1715                       AFS_TRACE_LEVEL_VERBOSE,
1716                       "%s Retrieved AuthGroup GUID %wZ for ProcessID %I64X\n",
1717                       __FUNCTION__,
1718                       &uniGUID,
1719                       ullProcessID);
1720
1721         if( uniGUID.Buffer != NULL)
1722         {
1723             RtlFreeUnicodeString( &uniGUID);
1724         }
1725
1726         AFSReleaseResource( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock);
1727
1728 try_exit:
1729
1730         if( bReleaseSID &&
1731             uniSIDString.Length > 0)
1732         {
1733             RtlFreeUnicodeString( &uniSIDString);
1734         }
1735     }
1736
1737     return ntStatus;
1738 }