ReactOS  0.4.15-dev-2996-gf777e6b
sidcache.c
Go to the documentation of this file.
1 /*
2  * ReactOS Access Control List Editor
3  * Copyright (C) 2004-2005 ReactOS Team
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18  */
19 /*
20  * PROJECT: ReactOS Access Control List Editor
21  * FILE: lib/aclui/sidcache.c
22  * PURPOSE: Access Control List Editor
23  * PROGRAMMER: Thomas Weidenmueller <w3seek@reactos.com>
24  *
25  * UPDATE HISTORY:
26  * 12/10/2005 Created
27  */
28 
29 #include "precomp.h"
30 
31 #include <ntsecapi.h>
32 
33 #define NDEBUG
34 #include <debug.h>
35 
36 #define HandleToScm(Handle) (PSIDCACHEMGR)(Handle)
37 #define ScmToHandle(Scm) (HANDLE)(Scm)
38 
39 typedef struct _SIDCACHEMGR
40 {
41  volatile LONG RefCount;
52 
53 
54 typedef struct _SIDCACHECALLBACKINFO
55 {
59 
60 
61 typedef struct _SIDQUEUEENTRY
62 {
66  /* the SID is appended to this structure */
68 
69 
70 typedef struct _SIDCACHEENTRY
71 {
76  /* the SID and strings are appended to this structure */
78 
79 
80 static VOID
82  IN PSIDQUEUEENTRY QueueEntry)
83 {
84  if (QueueEntry->ListEntry.Flink != NULL)
85  {
86  RemoveEntryList(&QueueEntry->ListEntry);
87  }
88 
89  HeapFree(scm->Heap,
90  0,
91  QueueEntry->Callbacks);
92 
93  HeapFree(scm->Heap,
94  0,
95  QueueEntry);
96 }
97 
98 
99 static VOID
101  IN PSIDCACHEENTRY CacheEntry)
102 {
103  RemoveEntryList(&CacheEntry->ListEntry);
104 
105  HeapFree(scm->Heap,
106  0,
107  CacheEntry);
108 }
109 
110 
111 static VOID
113 {
114  LsaClose(scm->LsaHandle);
115  CloseHandle(scm->LookupEvent);
116  CloseHandle(scm->LookupThread);
117 
118  /* delete the queue */
119  while (!IsListEmpty(&scm->QueueListHead))
120  {
121  PSIDQUEUEENTRY QueueEntry;
122 
123  QueueEntry = CONTAINING_RECORD(scm->QueueListHead.Flink,
125  ListEntry);
126  FreeQueueEntry(scm,
127  QueueEntry);
128  }
129 
130  /* delete the cache */
131  while (!IsListEmpty(&scm->CacheListHead))
132  {
133  PSIDCACHEENTRY CacheEntry;
134 
135  CacheEntry = CONTAINING_RECORD(scm->CacheListHead.Flink,
137  ListEntry);
138  FreeCacheEntry(scm,
139  CacheEntry);
140  }
141 
142  DeleteCriticalSection(&scm->Lock);
143 }
144 
145 
146 static PSIDCACHEMGR
148 {
149  PSIDCACHEMGR scm = HandleToScm(SidCacheMgr);
150 
151  if (InterlockedIncrement(&scm->RefCount) != 1)
152  {
153  return scm;
154  }
155 
156  return NULL;
157 }
158 
159 
160 static VOID
162 {
163  if (InterlockedDecrement(&scm->RefCount) == 0)
164  {
165  /* Signal the lookup thread so it can terminate */
166  SetEvent(scm->LookupEvent);
167  }
168 }
169 
170 
171 static BOOL
174  OUT PLSA_HANDLE PolicyHandle)
175 {
176  LSA_OBJECT_ATTRIBUTES LsaObjectAttributes = {0};
177  LSA_UNICODE_STRING LsaSystemName, *psn;
179  SIZE_T NameLength;
180 
181  if (SystemName != NULL && SystemName[0] != L'\0')
182  {
183  NameLength = wcslen(SystemName);
184  if (NameLength > UNICODE_STRING_MAX_CHARS)
185  {
186  return FALSE;
187  }
188 
189  LsaSystemName.Buffer = SystemName;
190  LsaSystemName.Length = NameLength * sizeof(WCHAR);
191  LsaSystemName.MaximumLength = LsaSystemName.Length + sizeof(WCHAR);
192  psn = &LsaSystemName;
193  }
194  else
195  {
196  psn = NULL;
197  }
198 
199  Status = LsaOpenPolicy(psn,
200  &LsaObjectAttributes,
202  PolicyHandle);
203  if (!NT_SUCCESS(Status))
204  {
206  return FALSE;
207  }
208 
209  return TRUE;
210 }
211 
212 
213 static BOOL
215  IN PSID pSid,
216  OUT PSIDREQRESULT *ReqResult)
217 {
218  PLSA_REFERENCED_DOMAIN_LIST ReferencedDomain;
220  PLSA_TRUST_INFORMATION Domain;
221  PLSA_UNICODE_STRING DomainName;
222  SID_NAME_USE SidNameUse = SidTypeUnknown;
223  PPOLICY_ACCOUNT_DOMAIN_INFO PolicyAccountDomainInfo = NULL;
225  DWORD AccountNameSize, DomainNameSize = 0;
226  PSIDREQRESULT ReqRet = NULL;
227  BOOL Ret = FALSE;
228 
229  Status = LsaLookupSids(scm->LsaHandle,
230  1,
231  &pSid,
232  &ReferencedDomain,
233  &Names);
234  if (NT_SUCCESS(Status))
235  {
236  SidNameUse = Names->Use;
237 
238  if (ReferencedDomain != NULL &&
239  Names->DomainIndex >= 0)
240  {
241  Domain = &ReferencedDomain->Domains[Names->DomainIndex];
242  DomainName = &Domain->Name;
243  }
244  else
245  {
246  Domain = NULL;
247  DomainName = NULL;
248  }
249 
250  switch (SidNameUse)
251  {
252  case SidTypeAlias:
253  {
254  if (Domain != NULL)
255  {
256  /* query the domain name for BUILTIN accounts */
257  Status = LsaQueryInformationPolicy(scm->LsaHandle,
259  (PVOID*)&PolicyAccountDomainInfo);
260  if (NT_SUCCESS(Status))
261  {
262  DomainName = &PolicyAccountDomainInfo->DomainName;
263 
264  /* make the user believe this is a group */
265  SidNameUse = (PolicyAccountDomainInfo != NULL ? SidTypeGroup : SidTypeUser);
266  }
267  }
268  break;
269  }
270 
271  default:
272  {
273  DPRINT("Unhandled SID type: 0x%x\n", Names->Use);
274  break;
275  }
276  }
277 
278  AccountNameSize = Names->Name.Length;
279  if (DomainName != NULL)
280  {
281  DomainNameSize = DomainName->Length;
282  }
283 
284  ReqRet = HeapAlloc(scm->Heap,
285  0,
286  sizeof(SIDREQRESULT) +
287  (((AccountNameSize + DomainNameSize) + 2) * sizeof(WCHAR)));
288  if (ReqRet != NULL)
289  {
290  ReqRet->RefCount = 1;
291  ReqRet->AccountName = (LPWSTR)(ReqRet + 1);
292  ReqRet->DomainName = ReqRet->AccountName + (AccountNameSize / sizeof(WCHAR)) + 1;
293 
294  CopyMemory(ReqRet->AccountName,
295  Names->Name.Buffer,
296  Names->Name.Length);
297 
298  if (DomainName != NULL)
299  {
300  CopyMemory(ReqRet->DomainName,
301  DomainName->Buffer,
302  DomainName->Length);
303  }
304 
305  ReqRet->AccountName[AccountNameSize / sizeof(WCHAR)] = L'\0';
306  ReqRet->DomainName[DomainNameSize / sizeof(WCHAR)] = L'\0';
307 
308  ReqRet->SidNameUse = SidNameUse;
309  }
310 
311  if (PolicyAccountDomainInfo != NULL)
312  {
313  LsaFreeMemory(PolicyAccountDomainInfo);
314  }
315 
316  LsaFreeMemory(ReferencedDomain);
318 
319  Ret = TRUE;
320  }
321  else if (Status == STATUS_NONE_MAPPED)
322  {
323  Ret = TRUE;
324  }
325 
326  if (Ret)
327  {
328  *ReqResult = ReqRet;
329  }
330 
331  return Ret;
332 }
333 
334 
335 static BOOL
337  IN PSID pSid,
338  OUT PSIDREQRESULT *ReqResult)
339 {
340  PSIDCACHEENTRY CacheEntry;
341  PLIST_ENTRY CurrentEntry;
342  PSIDREQRESULT ReqRes;
343  BOOL Ret = FALSE;
344 
345  /* NOTE: assumes the lists are locked! */
346 
347  for (CurrentEntry = scm->CacheListHead.Flink;
348  CurrentEntry != &scm->CacheListHead;
349  CurrentEntry = CurrentEntry->Flink)
350  {
351  CacheEntry = CONTAINING_RECORD(CurrentEntry,
353  ListEntry);
354 
355  if (EqualSid(pSid,
356  (PSID)(CacheEntry + 1)))
357  {
358  SIZE_T ReqResultSize;
359  ULONG AccountNameLen, DomainNameLen;
360 
361  Ret = TRUE;
362 
363  AccountNameLen = wcslen(CacheEntry->AccountName);
364  DomainNameLen = wcslen(CacheEntry->DomainName);
365 
366  ReqResultSize = sizeof(SIDREQRESULT) +
367  (((AccountNameLen + 1) +
368  (DomainNameLen + 1)) * sizeof(WCHAR));
369 
370  ReqRes = HeapAlloc(scm->Heap,
371  0,
372  ReqResultSize);
373  if (ReqRes != NULL)
374  {
375  PWSTR Buffer = (PWSTR)(ReqRes + 1);
376 
377  ReqRes->RefCount = 1;
378 
379  ReqRes->AccountName = Buffer;
380  wcscpy(ReqRes->AccountName,
381  CacheEntry->AccountName);
382  Buffer += AccountNameLen + 1;
383 
384  ReqRes->DomainName = Buffer;
385  wcscpy(ReqRes->DomainName,
386  CacheEntry->DomainName);
387  }
388 
389  /* return the result, even if we weren't unable to
390  allocate enough memory! */
391  *ReqResult = ReqRes;
392  break;
393  }
394  }
395 
396  return Ret;
397 }
398 
399 
400 static VOID
402  IN PSID pSid,
403  IN PSIDREQRESULT ReqResult)
404 {
405  PSIDCACHEENTRY CacheEntry;
406  DWORD SidLen;
407  SIZE_T AccountNameLen = 0;
408  SIZE_T DomainNameLen = 0;
409  SIZE_T CacheEntrySize = sizeof(SIDCACHEENTRY);
410 
411  /* NOTE: assumes the lists are locked! */
412 
413  SidLen = GetLengthSid(pSid);
414  CacheEntrySize += SidLen;
415 
416  AccountNameLen = wcslen(ReqResult->AccountName);
417  CacheEntrySize += (AccountNameLen + 1) * sizeof(WCHAR);
418 
419  DomainNameLen = wcslen(ReqResult->DomainName);
420  CacheEntrySize += (wcslen(ReqResult->DomainName) + 1) * sizeof(WCHAR);
421 
422  CacheEntry = HeapAlloc(scm->Heap,
423  0,
424  CacheEntrySize);
425  if (CacheEntry != NULL)
426  {
427  PWSTR lpBuf = (PWSTR)((ULONG_PTR)(CacheEntry + 1) + SidLen);
428 
429  CacheEntry->SidNameUse = ReqResult->SidNameUse;
430 
431  /* append the SID */
432  CopySid(SidLen,
433  (PSID)(CacheEntry + 1),
434  pSid);
435 
436  /* append the strings */
437  CacheEntry->AccountName = lpBuf;
438  wcscpy(lpBuf,
439  ReqResult->AccountName);
440  lpBuf += AccountNameLen + 1;
441 
442  CacheEntry->DomainName = lpBuf;
443  wcscpy(lpBuf,
444  ReqResult->DomainName);
445  lpBuf += DomainNameLen + 1;
446 
447  /* add the entry to the cache list */
448  InsertTailList(&scm->CacheListHead,
449  &CacheEntry->ListEntry);
450  }
451 }
452 
453 
454 static DWORD WINAPI
456 {
459 
460  /* Reference the dll to avoid problems in case of accidental
461  FreeLibrary calls... */
462  if (!GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
464  &hModule))
465  {
466  hModule = NULL;
467  }
468 
469  while (scm->RefCount != 0)
470  {
471  PSIDQUEUEENTRY QueueEntry = NULL;
472 
473  EnterCriticalSection(&scm->Lock);
474 
475  /* get the first item of the queue */
476  if (scm->QueueListHead.Flink != &scm->QueueListHead)
477  {
478  QueueEntry = CONTAINING_RECORD(scm->QueueListHead.Flink,
480  ListEntry);
481  RemoveEntryList(&QueueEntry->ListEntry);
482  QueueEntry->ListEntry.Flink = NULL;
483  }
484  else
485  {
486  LeaveCriticalSection(&scm->Lock);
487 
488  /* wait for the next asynchronous lookup queued */
490  INFINITE);
491  continue;
492  }
493 
494  scm->QueueLookingUp = QueueEntry;
495 
496  LeaveCriticalSection(&scm->Lock);
497 
498  if (QueueEntry != NULL)
499  {
500  PSIDREQRESULT ReqResult, FoundReqResult;
501  PSID pSid = (PSID)(QueueEntry + 1);
502 
503  /* lookup the SID information */
504  if (!LookupSidInformation(scm,
505  pSid,
506  &ReqResult))
507  {
508  ReqResult = NULL;
509  }
510 
511  EnterCriticalSection(&scm->Lock);
512 
513  /* see if the SID was added to the cache in the meanwhile */
514  if (!FindSidInCache(scm,
515  pSid,
516  &FoundReqResult))
517  {
518  if (ReqResult != NULL)
519  {
520  /* cache the results */
521  CacheLookupResults(scm,
522  pSid,
523  ReqResult);
524  }
525  }
526  else
527  {
528  if (ReqResult != NULL)
529  {
530  /* free the information of our lookup and use the cached
531  information*/
533  ReqResult);
534  }
535 
536  ReqResult = FoundReqResult;
537  }
538 
539  /* notify the callers unless the lookup was cancelled */
540  if (scm->QueueLookingUp != NULL)
541  {
542  ULONG i = 0;
543 
544  while (scm->QueueLookingUp != NULL &&
545  i < QueueEntry->CallbackCount)
546  {
547  PVOID Context;
548  PSIDREQCOMPLETIONPROC CompletionProc;
549 
550  Context = QueueEntry->Callbacks[i].Context;
551  CompletionProc = QueueEntry->Callbacks[i].CompletionProc;
552 
553  LeaveCriticalSection(&scm->Lock);
554 
555  /* call the completion proc without holding the lock! */
556  CompletionProc(ScmToHandle(scm),
557  pSid,
558  ReqResult,
559  Context);
560 
561  EnterCriticalSection(&scm->Lock);
562 
563  i++;
564  }
565 
566  scm->QueueLookingUp = NULL;
567  }
568 
569  LeaveCriticalSection(&scm->Lock);
570 
571  /* free the queue item */
572  FreeQueueEntry(scm,
573  QueueEntry);
574  }
575  }
576 
577  CleanupSidCacheMgr(scm);
578 
579  HeapFree(scm->Heap,
580  0,
581  scm);
582 
583  if (hModule != NULL)
584  {
585  /* dereference the library and exit */
587  0);
588  }
589 
590  return 0;
591 }
592 
593 
594 
595 HANDLE
597  IN LPCWSTR SystemName)
598 {
599  PSIDCACHEMGR scm;
600 
601  if (SystemName == NULL)
602  SystemName = L"";
603 
604  scm = HeapAlloc(Heap,
605  0,
607  SystemName[wcslen(SystemName) + 1]));
608  if (scm != NULL)
609  {
610  /* zero the static part of the structure */
611  ZeroMemory(scm,
613  SystemName));
614 
615  scm->RefCount = 1;
616  scm->Heap = Heap;
617 
618  wcscpy(scm->SystemName,
619  SystemName);
620 
624 
626  FALSE,
627  FALSE,
628  NULL);
629  if (scm->LookupEvent == NULL)
630  {
631  goto Cleanup;
632  }
633 
636  &scm->LsaHandle))
637  {
638  goto Cleanup;
639  }
640 
642  0,
644  scm,
645  0,
646  NULL);
647  if (scm->LookupThread == NULL)
648  {
649 Cleanup:
650  if (scm->LookupEvent != NULL)
651  {
652  CloseHandle(scm->LookupEvent);
653  }
654 
655  if (scm->LsaHandle != NULL)
656  {
657  LsaClose(scm->LsaHandle);
658  }
659 
660  HeapFree(Heap,
661  0,
662  scm);
663  scm = NULL;
664  }
665  }
666  else
667  {
669  }
670 
671  return (HANDLE)scm;
672 }
673 
674 
675 VOID
677 {
678  PSIDCACHEMGR scm = HandleToScm(SidCacheMgr);
679 
680  if (scm != NULL)
681  {
682  /* remove the keep-alive reference */
684  }
685 }
686 
687 
688 static BOOL
690  IN PSID pSid,
691  IN PSIDREQCOMPLETIONPROC CompletionProc,
692  IN PVOID Context)
693 {
694  PLIST_ENTRY CurrentEntry;
695  PSIDQUEUEENTRY QueueEntry, FoundEntry = NULL;
696  BOOL Ret = FALSE;
697 
698  /* NOTE: assumes the lists are locked! */
699 
700  if (scm->QueueLookingUp != NULL &&
701  EqualSid(pSid,
702  (PSID)(scm->QueueLookingUp + 1)))
703  {
704  FoundEntry = scm->QueueLookingUp;
705  }
706  else
707  {
708  for (CurrentEntry = scm->QueueListHead.Flink;
709  CurrentEntry != &scm->QueueListHead;
710  CurrentEntry = CurrentEntry->Flink)
711  {
712  QueueEntry = CONTAINING_RECORD(CurrentEntry,
714  ListEntry);
715 
716  if (EqualSid(pSid,
717  (PSID)(QueueEntry + 1)))
718  {
719  FoundEntry = QueueEntry;
720  break;
721  }
722  }
723  }
724 
725  if (FoundEntry == NULL)
726  {
727  DWORD SidLength = GetLengthSid(pSid);
728 
729  FoundEntry = HeapAlloc(scm->Heap,
730  0,
731  sizeof(SIDQUEUEENTRY) + SidLength);
732  if (FoundEntry != NULL)
733  {
734  CopySid(SidLength,
735  (PSID)(FoundEntry + 1),
736  pSid);
737 
738  FoundEntry->CallbackCount = 1;
739  FoundEntry->Callbacks = HeapAlloc(scm->Heap,
740  0,
741  sizeof(SIDCACHECALLBACKINFO));
742 
743  if (FoundEntry->Callbacks != NULL)
744  {
745  FoundEntry->Callbacks[0].CompletionProc = CompletionProc;
746  FoundEntry->Callbacks[0].Context = Context;
747 
748  /* append it to the queue */
749  InsertTailList(&scm->QueueListHead,
750  &FoundEntry->ListEntry);
751 
752  /* signal the lookup event */
753  SetEvent(scm->LookupEvent);
754 
755  Ret = TRUE;
756  }
757  else
758  {
759  /* unable to queue it because we couldn't allocate the callbacks
760  array, free the memory and return */
761  HeapFree(scm->Heap,
762  0,
763  FoundEntry);
764  }
765  }
766  }
767  else
768  {
769  PSIDCACHECALLBACKINFO Sidccb;
770 
771  /* add the callback */
772  Sidccb = HeapReAlloc(scm->Heap,
773  0,
774  FoundEntry->Callbacks,
775  (FoundEntry->CallbackCount + 1) * sizeof(SIDCACHECALLBACKINFO));
776  if (Sidccb != NULL)
777  {
778  FoundEntry->Callbacks = Sidccb;
779  FoundEntry->Callbacks[FoundEntry->CallbackCount].CompletionProc = CompletionProc;
780  FoundEntry->Callbacks[FoundEntry->CallbackCount++].Context = Context;
781 
782  Ret = TRUE;
783  }
784  }
785 
786  return Ret;
787 }
788 
789 
790 VOID
792  IN PSID pSid)
793 {
794  PLIST_ENTRY CurrentEntry;
795  PSIDQUEUEENTRY QueueEntry;
796  PSIDCACHEMGR scm;
797 
798  scm = ReferenceSidCacheMgr(SidCacheMgr);
799  if (scm != NULL)
800  {
801  EnterCriticalSection(&scm->Lock);
802 
803  if (scm->QueueLookingUp != NULL &&
804  EqualSid(pSid,
805  (PSID)(scm->QueueLookingUp + 1)))
806  {
807  /* don't free the queue lookup item! this will be
808  done in the lookup thread */
809  scm->QueueLookingUp = NULL;
810  }
811  else
812  {
813  for (CurrentEntry = scm->QueueListHead.Flink;
814  CurrentEntry != &scm->QueueListHead;
815  CurrentEntry = CurrentEntry->Flink)
816  {
817  QueueEntry = CONTAINING_RECORD(CurrentEntry,
819  ListEntry);
820 
821  if (EqualSid(pSid,
822  (PSID)(QueueEntry + 1)))
823  {
824  FreeQueueEntry(scm,
825  QueueEntry);
826  break;
827  }
828  }
829  }
830 
831  LeaveCriticalSection(&scm->Lock);
832 
834  }
835 }
836 
837 
838 VOID
840  IN PSIDREQRESULT ReqResult)
841 {
842  PSIDCACHEMGR scm;
843 
844  scm = ReferenceSidCacheMgr(SidCacheMgr);
845  if (scm != NULL)
846  {
847  InterlockedIncrement(&ReqResult->RefCount);
848 
850  }
851 }
852 
853 
854 VOID
856  IN PSIDREQRESULT ReqResult)
857 {
858  PSIDCACHEMGR scm;
859 
860  scm = ReferenceSidCacheMgr(SidCacheMgr);
861  if (scm != NULL)
862  {
863  if (InterlockedDecrement(&ReqResult->RefCount) == 0)
864  {
865  HeapFree(scm->Heap,
866  0,
867  ReqResult);
868  }
869 
871  }
872 }
873 
874 
875 BOOL
877  IN PSID pSid,
878  IN PSIDREQCOMPLETIONPROC CompletionProc,
879  IN PVOID Context)
880 {
881  BOOL Found = FALSE;
882  PSIDREQRESULT ReqResult = NULL;
883  PSIDCACHEMGR scm;
884 
885  scm = ReferenceSidCacheMgr(SidCacheMgr);
886  if (scm != NULL)
887  {
888  EnterCriticalSection(&scm->Lock);
889 
890  /* search the cache */
891  Found = FindSidInCache(scm,
892  pSid,
893  &ReqResult);
894 
895  if (!Found)
896  {
897  /* the sid is not in the cache, queue it if not already queued */
898  if (!QueueSidLookup(scm,
899  pSid,
900  CompletionProc,
901  Context))
902  {
903  PSIDREQRESULT FoundReqResult = NULL;
904 
905  /* unable to queue it, look it up now */
906 
907  LeaveCriticalSection(&scm->Lock);
908 
909  /* lookup everything we need */
910  if (!LookupSidInformation(scm,
911  pSid,
912  &ReqResult))
913  {
914  ReqResult = NULL;
915  }
916 
917  EnterCriticalSection(&scm->Lock);
918 
919  /* see if the SID was added to the cache in the meanwhile */
920  if (!FindSidInCache(scm,
921  pSid,
922  &FoundReqResult))
923  {
924  if (ReqResult != NULL)
925  {
926  /* cache the results */
927  CacheLookupResults(scm,
928  pSid,
929  ReqResult);
930  }
931  }
932  else
933  {
934  if (ReqResult != NULL)
935  {
936  /* free the information of our lookup and use the cached
937  information*/
939  ReqResult);
940  }
941 
942  ReqResult = FoundReqResult;
943  }
944 
945  Found = (ReqResult != NULL);
946  }
947  }
948 
949  LeaveCriticalSection(&scm->Lock);
950 
951  /* call the completion callback */
952  if (Found)
953  {
954  CompletionProc(SidCacheMgr,
955  pSid,
956  ReqResult,
957  Context);
958 
959  if (ReqResult != NULL)
960  {
961  HeapFree(scm->Heap,
962  0,
963  ReqResult);
964  }
965  }
966 
968  }
969 
970  return Found;
971 }
#define CreateEvent
Definition: winbase.h:3604
LIST_ENTRY QueueListHead
Definition: sidcache.c:44
PWSTR DomainName
Definition: sidcache.c:75
#define IN
Definition: typedefs.h:39
static VOID DereferenceSidCacheMgr(IN PSIDCACHEMGR scm)
Definition: sidcache.c:161
HANDLE LookupThread
Definition: sidcache.c:49
struct _SIDCACHECALLBACKINFO * PSIDCACHECALLBACKINFO
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2654
#define CloseHandle
Definition: compat.h:598
VOID(* PSIDREQCOMPLETIONPROC)(IN HANDLE SidCacheMgr, IN PSID Sid, IN PSIDREQRESULT SidRequestResult, IN PVOID Context)
Definition: precomp.h:175
#define ScmToHandle(Scm)
Definition: sidcache.c:37
enum _SID_NAME_USE SID_NAME_USE
LONG RefCount
Definition: precomp.h:169
NTSTATUS WINAPI LsaQueryInformationPolicy(IN LSA_HANDLE PolicyHandle, IN POLICY_INFORMATION_CLASS InformationClass, OUT PVOID *Buffer)
Definition: lsa.c:1471
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
volatile LONG RefCount
Definition: sidcache.c:41
PLSA_TRUST_INFORMATION Domains
Definition: ntsecapi.h:408
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
static VOID CacheLookupResults(IN PSIDCACHEMGR scm, IN PSID pSid, IN PSIDREQRESULT ReqResult)
Definition: sidcache.c:401
PWSTR Names[]
#define TRUE
Definition: types.h:120
#define POLICY_VIEW_LOCAL_INFORMATION
Definition: ntsecapi.h:61
uint16_t * PWSTR
Definition: typedefs.h:56
BOOL WINAPI EqualSid(PSID pSid1, PSID pSid2)
Definition: security.c:708
static DWORD WINAPI LookupThreadProc(IN LPVOID lpParameter)
Definition: sidcache.c:455
struct _SIDCACHEENTRY SIDCACHEENTRY
LONG NTSTATUS
Definition: precomp.h:26
HANDLE CreateSidCacheMgr(IN HANDLE Heap, IN LPCWSTR SystemName)
Definition: sidcache.c:596
NTSTATUS WINAPI LsaClose(IN LSA_HANDLE ObjectHandle)
Definition: lsa.c:192
VOID DestroySidCacheMgr(IN HANDLE SidCacheMgr)
Definition: sidcache.c:676
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
static BOOL OpenLSAPolicyHandle(IN LPWSTR SystemName, IN ACCESS_MASK DesiredAccess, OUT PLSA_HANDLE PolicyHandle)
Definition: sidcache.c:172
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
#define ZeroMemory
Definition: winbase.h:1664
CRITICAL_SECTION Lock
Definition: sidcache.c:43
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
#define InsertTailList(ListHead, Entry)
NTSTATUS WINAPI LsaLookupSids(IN LSA_HANDLE PolicyHandle, IN ULONG Count, IN PSID *Sids, OUT PLSA_REFERENCED_DOMAIN_LIST *ReferencedDomains, OUT PLSA_TRANSLATED_NAME *Names)
Definition: lsa.c:1067
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
SID_NAME_USE SidNameUse
Definition: sidcache.c:73
BOOL LookupSidCache(IN HANDLE SidCacheMgr, IN PSID pSid, IN PSIDREQCOMPLETIONPROC CompletionProc, IN PVOID Context)
Definition: sidcache.c:876
#define STATUS_NONE_MAPPED
Definition: ntstatus.h:351
uint32_t ULONG_PTR
Definition: typedefs.h:65
static VOID CleanupSidCacheMgr(IN PSIDCACHEMGR scm)
Definition: sidcache.c:112
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
VOID WINAPI FreeLibraryAndExitThread(HMODULE hLibModule, DWORD dwExitCode)
Definition: loader.c:507
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
NTSTATUS WINAPI LsaOpenPolicy(IN PLSA_UNICODE_STRING SystemName OPTIONAL, IN PLSA_OBJECT_ATTRIBUTES ObjectAttributes, IN ACCESS_MASK DesiredAccess, OUT PLSA_HANDLE PolicyHandle)
Definition: lsa.c:1181
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
LPWSTR DomainName
Definition: precomp.h:172
VOID DereferenceSidReqResult(IN HANDLE SidCacheMgr, IN PSIDREQRESULT ReqResult)
Definition: sidcache.c:855
static BOOL QueueSidLookup(IN PSIDCACHEMGR scm, IN PSID pSid, IN PSIDREQCOMPLETIONPROC CompletionProc, IN PVOID Context)
Definition: sidcache.c:689
struct _SIDREQRESULT SIDREQRESULT
struct _SIDCACHEENTRY * PSIDCACHEENTRY
struct _SIDQUEUEENTRY * PSIDQUEUEENTRY
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:136
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
Definition: synch.c:751
static VOID FreeQueueEntry(IN PSIDCACHEMGR scm, IN PSIDQUEUEENTRY QueueEntry)
Definition: sidcache.c:81
struct _SIDQUEUEENTRY * QueueLookingUp
Definition: sidcache.c:45
Definition: bufpool.h:45
NTSTATUS WINAPI LsaFreeMemory(IN PVOID Buffer)
Definition: lsa.c:699
SID_NAME_USE SidNameUse
Definition: precomp.h:170
return Found
Definition: dirsup.c:1270
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
LIST_ENTRY ListEntry
Definition: sidcache.c:72
static HINSTANCE hDllInstance
Definition: clb.c:30
#define POLICY_LOOKUP_NAMES
Definition: ntsecapi.h:72
Status
Definition: gdiplustypes.h:24
static BOOL LookupSidInformation(IN PSIDCACHEMGR scm, IN PSID pSid, OUT PSIDREQRESULT *ReqResult)
Definition: sidcache.c:214
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
LSA_HANDLE LsaHandle
Definition: sidcache.c:42
#define UNICODE_STRING_MAX_CHARS
ULONG CallbackCount
Definition: sidcache.c:64
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
__wchar_t WCHAR
Definition: xmlstorage.h:180
ULONG WINAPI LsaNtStatusToWinError(IN NTSTATUS Status)
Definition: lsa.c:1129
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
DWORD WINAPI GetLengthSid(PSID pSid)
Definition: security.c:798
#define WINAPI
Definition: msvc.h:6
#define CopyMemory
Definition: winbase.h:1662
LSA_UNICODE_STRING Name
Definition: ntsecapi.h:403
unsigned long DWORD
Definition: ntddk_ex.h:95
static VOID FreeCacheEntry(IN PSIDCACHEMGR scm, IN PSIDCACHEENTRY CacheEntry)
Definition: sidcache.c:100
#define SetLastError(x)
Definition: compat.h:611
struct _SIDCACHEMGR SIDCACHEMGR
PWSTR AccountName
Definition: sidcache.c:74
struct _SID * PSID
Definition: eventlog.c:35
static PSIDCACHEMGR ReferenceSidCacheMgr(IN HANDLE SidCacheMgr)
Definition: sidcache.c:147
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
static const WCHAR L[]
Definition: oid.c:1250
#define InterlockedDecrement
Definition: armddk.h:52
LPVOID lpParameter
Definition: kernel32.h:241
Definition: typedefs.h:119
struct _SIDQUEUEENTRY SIDQUEUEENTRY
static const WCHAR Cleanup[]
Definition: register.c:80
struct _SIDCACHEMGR * PSIDCACHEMGR
ULONG_PTR SIZE_T
Definition: typedefs.h:80
BOOL WINAPI GetModuleHandleExW(IN DWORD dwFlags, IN LPCWSTR lpwModuleName OPTIONAL, OUT HMODULE *phModule)
Definition: loader.c:866
HANDLE Heap
Definition: sidcache.c:47
#define InterlockedIncrement
Definition: armddk.h:53
LIST_ENTRY CacheListHead
Definition: sidcache.c:46
VOID DequeueSidLookup(IN HANDLE SidCacheMgr, IN PSID pSid)
Definition: sidcache.c:791
PSIDCACHECALLBACKINFO Callbacks
Definition: sidcache.c:65
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
USHORT MaximumLength
Definition: ntsecapi.h:164
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define HeapReAlloc
Definition: compat.h:593
PSIDREQCOMPLETIONPROC CompletionProc
Definition: sidcache.c:56
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
WCHAR SystemName[1]
Definition: sidcache.c:50
#define NULL
Definition: types.h:112
VOID ReferenceSidReqResult(IN HANDLE SidCacheMgr, IN PSIDREQRESULT ReqResult)
Definition: sidcache.c:839
static PSID pSid
Definition: security.c:74
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
LPWSTR AccountName
Definition: precomp.h:171
struct tagContext Context
Definition: acpixf.h:1034
#define OUT
Definition: typedefs.h:40
unsigned int ULONG
Definition: retypes.h:1
LIST_ENTRY ListEntry
Definition: sidcache.c:63
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
#define DPRINT
Definition: sndvol32.h:71
WCHAR * LPWSTR
Definition: xmlstorage.h:184
BOOL WINAPI CopySid(DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid)
Definition: security.c:591
#define INFINITE
Definition: serial.h:102
struct _SIDCACHECALLBACKINFO SIDCACHECALLBACKINFO
static BOOL FindSidInCache(IN PSIDCACHEMGR scm, IN PSID pSid, OUT PSIDREQRESULT *ReqResult)
Definition: sidcache.c:336
#define HeapFree(x, y, z)
Definition: compat.h:594
ULONG ACCESS_MASK
Definition: nt_native.h:40
HANDLE LookupEvent
Definition: sidcache.c:48
#define HandleToScm(Handle)
Definition: sidcache.c:36
HMODULE hModule
Definition: animate.c:44