ReactOS  0.4.15-dev-313-g8fde48b
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 
180  if (SystemName != NULL && SystemName[0] != L'\0')
181  {
182  LsaSystemName.Buffer = SystemName;
183  LsaSystemName.Length = wcslen(SystemName) * sizeof(WCHAR);
184  LsaSystemName.MaximumLength = LsaSystemName.Length + sizeof(WCHAR);
185  psn = &LsaSystemName;
186  }
187  else
188  {
189  psn = NULL;
190  }
191 
192  Status = LsaOpenPolicy(psn,
193  &LsaObjectAttributes,
195  PolicyHandle);
196  if (!NT_SUCCESS(Status))
197  {
199  return FALSE;
200  }
201 
202  return TRUE;
203 }
204 
205 
206 static BOOL
208  IN PSID pSid,
209  OUT PSIDREQRESULT *ReqResult)
210 {
211  PLSA_REFERENCED_DOMAIN_LIST ReferencedDomain;
213  PLSA_TRUST_INFORMATION Domain;
214  PLSA_UNICODE_STRING DomainName;
215  SID_NAME_USE SidNameUse = SidTypeUnknown;
216  PPOLICY_ACCOUNT_DOMAIN_INFO PolicyAccountDomainInfo = NULL;
218  DWORD AccountNameSize, DomainNameSize = 0;
219  PSIDREQRESULT ReqRet = NULL;
220  BOOL Ret = FALSE;
221 
222  Status = LsaLookupSids(scm->LsaHandle,
223  1,
224  &pSid,
225  &ReferencedDomain,
226  &Names);
227  if (NT_SUCCESS(Status))
228  {
229  SidNameUse = Names->Use;
230 
231  if (ReferencedDomain != NULL &&
232  Names->DomainIndex >= 0)
233  {
234  Domain = &ReferencedDomain->Domains[Names->DomainIndex];
235  DomainName = &Domain->Name;
236  }
237  else
238  {
239  Domain = NULL;
240  DomainName = NULL;
241  }
242 
243  switch (SidNameUse)
244  {
245  case SidTypeAlias:
246  {
247  if (Domain != NULL)
248  {
249  /* query the domain name for BUILTIN accounts */
250  Status = LsaQueryInformationPolicy(scm->LsaHandle,
252  (PVOID*)&PolicyAccountDomainInfo);
253  if (NT_SUCCESS(Status))
254  {
255  DomainName = &PolicyAccountDomainInfo->DomainName;
256 
257  /* make the user believe this is a group */
258  SidNameUse = (PolicyAccountDomainInfo != NULL ? SidTypeGroup : SidTypeUser);
259  }
260  }
261  break;
262  }
263 
264  default:
265  {
266  DPRINT("Unhandled SID type: 0x%x\n", Names->Use);
267  break;
268  }
269  }
270 
271  AccountNameSize = Names->Name.Length;
272  if (DomainName != NULL)
273  {
274  DomainNameSize = DomainName->Length;
275  }
276 
277  ReqRet = HeapAlloc(scm->Heap,
278  0,
279  sizeof(SIDREQRESULT) +
280  (((AccountNameSize + DomainNameSize) + 2) * sizeof(WCHAR)));
281  if (ReqRet != NULL)
282  {
283  ReqRet->RefCount = 1;
284  ReqRet->AccountName = (LPWSTR)(ReqRet + 1);
285  ReqRet->DomainName = ReqRet->AccountName + (AccountNameSize / sizeof(WCHAR)) + 1;
286 
287  CopyMemory(ReqRet->AccountName,
288  Names->Name.Buffer,
289  Names->Name.Length);
290 
291  if (DomainName != NULL)
292  {
293  CopyMemory(ReqRet->DomainName,
294  DomainName->Buffer,
295  DomainName->Length);
296  }
297 
298  ReqRet->AccountName[AccountNameSize / sizeof(WCHAR)] = L'\0';
299  ReqRet->DomainName[DomainNameSize / sizeof(WCHAR)] = L'\0';
300 
301  ReqRet->SidNameUse = SidNameUse;
302  }
303 
304  if (PolicyAccountDomainInfo != NULL)
305  {
306  LsaFreeMemory(PolicyAccountDomainInfo);
307  }
308 
309  LsaFreeMemory(ReferencedDomain);
311 
312  Ret = TRUE;
313  }
314  else if (Status == STATUS_NONE_MAPPED)
315  {
316  Ret = TRUE;
317  }
318 
319  if (Ret)
320  {
321  *ReqResult = ReqRet;
322  }
323 
324  return Ret;
325 }
326 
327 
328 static BOOL
330  IN PSID pSid,
331  OUT PSIDREQRESULT *ReqResult)
332 {
333  PSIDCACHEENTRY CacheEntry;
334  PLIST_ENTRY CurrentEntry;
335  PSIDREQRESULT ReqRes;
336  BOOL Ret = FALSE;
337 
338  /* NOTE: assumes the lists are locked! */
339 
340  for (CurrentEntry = scm->CacheListHead.Flink;
341  CurrentEntry != &scm->CacheListHead;
342  CurrentEntry = CurrentEntry->Flink)
343  {
344  CacheEntry = CONTAINING_RECORD(CurrentEntry,
346  ListEntry);
347 
348  if (EqualSid(pSid,
349  (PSID)(CacheEntry + 1)))
350  {
351  SIZE_T ReqResultSize;
352  ULONG AccountNameLen, DomainNameLen;
353 
354  Ret = TRUE;
355 
356  AccountNameLen = wcslen(CacheEntry->AccountName);
357  DomainNameLen = wcslen(CacheEntry->DomainName);
358 
359  ReqResultSize = sizeof(SIDREQRESULT) +
360  (((AccountNameLen + 1) +
361  (DomainNameLen + 1)) * sizeof(WCHAR));
362 
363  ReqRes = HeapAlloc(scm->Heap,
364  0,
365  ReqResultSize);
366  if (ReqRes != NULL)
367  {
368  PWSTR Buffer = (PWSTR)(ReqRes + 1);
369 
370  ReqRes->RefCount = 1;
371 
372  ReqRes->AccountName = Buffer;
373  wcscpy(ReqRes->AccountName,
374  CacheEntry->AccountName);
375  Buffer += AccountNameLen + 1;
376 
377  ReqRes->DomainName = Buffer;
378  wcscpy(ReqRes->DomainName,
379  CacheEntry->DomainName);
380  }
381 
382  /* return the result, even if we weren't unable to
383  allocate enough memory! */
384  *ReqResult = ReqRes;
385  break;
386  }
387  }
388 
389  return Ret;
390 }
391 
392 
393 static VOID
395  IN PSID pSid,
396  IN PSIDREQRESULT ReqResult)
397 {
398  PSIDCACHEENTRY CacheEntry;
399  DWORD SidLen;
400  SIZE_T AccountNameLen = 0;
401  SIZE_T DomainNameLen = 0;
402  SIZE_T CacheEntrySize = sizeof(SIDCACHEENTRY);
403 
404  /* NOTE: assumes the lists are locked! */
405 
406  SidLen = GetLengthSid(pSid);
407  CacheEntrySize += SidLen;
408 
409  AccountNameLen = wcslen(ReqResult->AccountName);
410  CacheEntrySize += (AccountNameLen + 1) * sizeof(WCHAR);
411 
412  DomainNameLen = wcslen(ReqResult->DomainName);
413  CacheEntrySize += (wcslen(ReqResult->DomainName) + 1) * sizeof(WCHAR);
414 
415  CacheEntry = HeapAlloc(scm->Heap,
416  0,
417  CacheEntrySize);
418  if (CacheEntry != NULL)
419  {
420  PWSTR lpBuf = (PWSTR)((ULONG_PTR)(CacheEntry + 1) + SidLen);
421 
422  CacheEntry->SidNameUse = ReqResult->SidNameUse;
423 
424  /* append the SID */
425  CopySid(SidLen,
426  (PSID)(CacheEntry + 1),
427  pSid);
428 
429  /* append the strings */
430  CacheEntry->AccountName = lpBuf;
431  wcscpy(lpBuf,
432  ReqResult->AccountName);
433  lpBuf += AccountNameLen + 1;
434 
435  CacheEntry->DomainName = lpBuf;
436  wcscpy(lpBuf,
437  ReqResult->DomainName);
438  lpBuf += DomainNameLen + 1;
439 
440  /* add the entry to the cache list */
441  InsertTailList(&scm->CacheListHead,
442  &CacheEntry->ListEntry);
443  }
444 }
445 
446 
447 static DWORD WINAPI
449 {
452 
453  /* Reference the dll to avoid problems in case of accidental
454  FreeLibrary calls... */
455  if (!GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
457  &hModule))
458  {
459  hModule = NULL;
460  }
461 
462  while (scm->RefCount != 0)
463  {
464  PSIDQUEUEENTRY QueueEntry = NULL;
465 
466  EnterCriticalSection(&scm->Lock);
467 
468  /* get the first item of the queue */
469  if (scm->QueueListHead.Flink != &scm->QueueListHead)
470  {
471  QueueEntry = CONTAINING_RECORD(scm->QueueListHead.Flink,
473  ListEntry);
474  RemoveEntryList(&QueueEntry->ListEntry);
475  QueueEntry->ListEntry.Flink = NULL;
476  }
477  else
478  {
479  LeaveCriticalSection(&scm->Lock);
480 
481  /* wait for the next asynchronous lookup queued */
483  INFINITE);
484  continue;
485  }
486 
487  scm->QueueLookingUp = QueueEntry;
488 
489  LeaveCriticalSection(&scm->Lock);
490 
491  if (QueueEntry != NULL)
492  {
493  PSIDREQRESULT ReqResult, FoundReqResult;
494  PSID pSid = (PSID)(QueueEntry + 1);
495 
496  /* lookup the SID information */
497  if (!LookupSidInformation(scm,
498  pSid,
499  &ReqResult))
500  {
501  ReqResult = NULL;
502  }
503 
504  EnterCriticalSection(&scm->Lock);
505 
506  /* see if the SID was added to the cache in the meanwhile */
507  if (!FindSidInCache(scm,
508  pSid,
509  &FoundReqResult))
510  {
511  if (ReqResult != NULL)
512  {
513  /* cache the results */
514  CacheLookupResults(scm,
515  pSid,
516  ReqResult);
517  }
518  }
519  else
520  {
521  if (ReqResult != NULL)
522  {
523  /* free the information of our lookup and use the cached
524  information*/
526  ReqResult);
527  }
528 
529  ReqResult = FoundReqResult;
530  }
531 
532  /* notify the callers unless the lookup was cancelled */
533  if (scm->QueueLookingUp != NULL)
534  {
535  ULONG i = 0;
536 
537  while (scm->QueueLookingUp != NULL &&
538  i < QueueEntry->CallbackCount)
539  {
540  PVOID Context;
541  PSIDREQCOMPLETIONPROC CompletionProc;
542 
543  Context = QueueEntry->Callbacks[i].Context;
544  CompletionProc = QueueEntry->Callbacks[i].CompletionProc;
545 
546  LeaveCriticalSection(&scm->Lock);
547 
548  /* call the completion proc without holding the lock! */
549  CompletionProc(ScmToHandle(scm),
550  pSid,
551  ReqResult,
552  Context);
553 
554  EnterCriticalSection(&scm->Lock);
555 
556  i++;
557  }
558 
559  scm->QueueLookingUp = NULL;
560  }
561 
562  LeaveCriticalSection(&scm->Lock);
563 
564  /* free the queue item */
565  FreeQueueEntry(scm,
566  QueueEntry);
567  }
568  }
569 
570  CleanupSidCacheMgr(scm);
571 
572  HeapFree(scm->Heap,
573  0,
574  scm);
575 
576  if (hModule != NULL)
577  {
578  /* dereference the library and exit */
580  0);
581  }
582 
583  return 0;
584 }
585 
586 
587 
588 HANDLE
590  IN LPCWSTR SystemName)
591 {
592  PSIDCACHEMGR scm;
593 
594  if (SystemName == NULL)
595  SystemName = L"";
596 
597  scm = HeapAlloc(Heap,
598  0,
600  SystemName[wcslen(SystemName) + 1]));
601  if (scm != NULL)
602  {
603  /* zero the static part of the structure */
604  ZeroMemory(scm,
606  SystemName));
607 
608  scm->RefCount = 1;
609  scm->Heap = Heap;
610 
611  wcscpy(scm->SystemName,
612  SystemName);
613 
617 
619  FALSE,
620  FALSE,
621  NULL);
622  if (scm->LookupEvent == NULL)
623  {
624  goto Cleanup;
625  }
626 
629  &scm->LsaHandle))
630  {
631  goto Cleanup;
632  }
633 
635  0,
637  scm,
638  0,
639  NULL);
640  if (scm->LookupThread == NULL)
641  {
642 Cleanup:
643  if (scm->LookupEvent != NULL)
644  {
645  CloseHandle(scm->LookupEvent);
646  }
647 
648  if (scm->LsaHandle != NULL)
649  {
650  LsaClose(scm->LsaHandle);
651  }
652 
653  HeapFree(Heap,
654  0,
655  scm);
656  scm = NULL;
657  }
658  }
659  else
660  {
662  }
663 
664  return (HANDLE)scm;
665 }
666 
667 
668 VOID
670 {
671  PSIDCACHEMGR scm = HandleToScm(SidCacheMgr);
672 
673  if (scm != NULL)
674  {
675  /* remove the keep-alive reference */
677  }
678 }
679 
680 
681 static BOOL
683  IN PSID pSid,
684  IN PSIDREQCOMPLETIONPROC CompletionProc,
685  IN PVOID Context)
686 {
687  PLIST_ENTRY CurrentEntry;
688  PSIDQUEUEENTRY QueueEntry, FoundEntry = NULL;
689  BOOL Ret = FALSE;
690 
691  /* NOTE: assumes the lists are locked! */
692 
693  if (scm->QueueLookingUp != NULL &&
694  EqualSid(pSid,
695  (PSID)(scm->QueueLookingUp + 1)))
696  {
697  FoundEntry = scm->QueueLookingUp;
698  }
699  else
700  {
701  for (CurrentEntry = scm->QueueListHead.Flink;
702  CurrentEntry != &scm->QueueListHead;
703  CurrentEntry = CurrentEntry->Flink)
704  {
705  QueueEntry = CONTAINING_RECORD(CurrentEntry,
707  ListEntry);
708 
709  if (EqualSid(pSid,
710  (PSID)(QueueEntry + 1)))
711  {
712  FoundEntry = QueueEntry;
713  break;
714  }
715  }
716  }
717 
718  if (FoundEntry == NULL)
719  {
720  DWORD SidLength = GetLengthSid(pSid);
721 
722  FoundEntry = HeapAlloc(scm->Heap,
723  0,
724  sizeof(SIDQUEUEENTRY) + SidLength);
725  if (FoundEntry != NULL)
726  {
727  CopySid(SidLength,
728  (PSID)(FoundEntry + 1),
729  pSid);
730 
731  FoundEntry->CallbackCount = 1;
732  FoundEntry->Callbacks = HeapAlloc(scm->Heap,
733  0,
734  sizeof(SIDCACHECALLBACKINFO));
735 
736  if (FoundEntry->Callbacks != NULL)
737  {
738  FoundEntry->Callbacks[0].CompletionProc = CompletionProc;
739  FoundEntry->Callbacks[0].Context = Context;
740 
741  /* append it to the queue */
742  InsertTailList(&scm->QueueListHead,
743  &FoundEntry->ListEntry);
744 
745  /* signal the lookup event */
746  SetEvent(scm->LookupEvent);
747 
748  Ret = TRUE;
749  }
750  else
751  {
752  /* unable to queue it because we couldn't allocate the callbacks
753  array, free the memory and return */
754  HeapFree(scm->Heap,
755  0,
756  FoundEntry);
757  }
758  }
759  }
760  else
761  {
762  PSIDCACHECALLBACKINFO Sidccb;
763 
764  /* add the callback */
765  Sidccb = HeapReAlloc(scm->Heap,
766  0,
767  FoundEntry->Callbacks,
768  (FoundEntry->CallbackCount + 1) * sizeof(SIDCACHECALLBACKINFO));
769  if (Sidccb != NULL)
770  {
771  FoundEntry->Callbacks = Sidccb;
772  FoundEntry->Callbacks[FoundEntry->CallbackCount].CompletionProc = CompletionProc;
773  FoundEntry->Callbacks[FoundEntry->CallbackCount++].Context = Context;
774 
775  Ret = TRUE;
776  }
777  }
778 
779  return Ret;
780 }
781 
782 
783 VOID
785  IN PSID pSid)
786 {
787  PLIST_ENTRY CurrentEntry;
788  PSIDQUEUEENTRY QueueEntry;
789  PSIDCACHEMGR scm;
790 
791  scm = ReferenceSidCacheMgr(SidCacheMgr);
792  if (scm != NULL)
793  {
794  EnterCriticalSection(&scm->Lock);
795 
796  if (scm->QueueLookingUp != NULL &&
797  EqualSid(pSid,
798  (PSID)(scm->QueueLookingUp + 1)))
799  {
800  /* don't free the queue lookup item! this will be
801  done in the lookup thread */
802  scm->QueueLookingUp = NULL;
803  }
804  else
805  {
806  for (CurrentEntry = scm->QueueListHead.Flink;
807  CurrentEntry != &scm->QueueListHead;
808  CurrentEntry = CurrentEntry->Flink)
809  {
810  QueueEntry = CONTAINING_RECORD(CurrentEntry,
812  ListEntry);
813 
814  if (EqualSid(pSid,
815  (PSID)(QueueEntry + 1)))
816  {
817  FreeQueueEntry(scm,
818  QueueEntry);
819  break;
820  }
821  }
822  }
823 
824  LeaveCriticalSection(&scm->Lock);
825 
827  }
828 }
829 
830 
831 VOID
833  IN PSIDREQRESULT ReqResult)
834 {
835  PSIDCACHEMGR scm;
836 
837  scm = ReferenceSidCacheMgr(SidCacheMgr);
838  if (scm != NULL)
839  {
840  InterlockedIncrement(&ReqResult->RefCount);
841 
843  }
844 }
845 
846 
847 VOID
849  IN PSIDREQRESULT ReqResult)
850 {
851  PSIDCACHEMGR scm;
852 
853  scm = ReferenceSidCacheMgr(SidCacheMgr);
854  if (scm != NULL)
855  {
856  if (InterlockedDecrement(&ReqResult->RefCount) == 0)
857  {
858  HeapFree(scm->Heap,
859  0,
860  ReqResult);
861  }
862 
864  }
865 }
866 
867 
868 BOOL
870  IN PSID pSid,
871  IN PSIDREQCOMPLETIONPROC CompletionProc,
872  IN PVOID Context)
873 {
874  BOOL Found = FALSE;
875  PSIDREQRESULT ReqResult = NULL;
876  PSIDCACHEMGR scm;
877 
878  scm = ReferenceSidCacheMgr(SidCacheMgr);
879  if (scm != NULL)
880  {
881  EnterCriticalSection(&scm->Lock);
882 
883  /* search the cache */
884  Found = FindSidInCache(scm,
885  pSid,
886  &ReqResult);
887 
888  if (!Found)
889  {
890  /* the sid is not in the cache, queue it if not already queued */
891  if (!QueueSidLookup(scm,
892  pSid,
893  CompletionProc,
894  Context))
895  {
896  PSIDREQRESULT FoundReqResult = NULL;
897 
898  /* unable to queue it, look it up now */
899 
900  LeaveCriticalSection(&scm->Lock);
901 
902  /* lookup everything we need */
903  if (!LookupSidInformation(scm,
904  pSid,
905  &ReqResult))
906  {
907  ReqResult = NULL;
908  }
909 
910  EnterCriticalSection(&scm->Lock);
911 
912  /* see if the SID was added to the cache in the meanwhile */
913  if (!FindSidInCache(scm,
914  pSid,
915  &FoundReqResult))
916  {
917  if (ReqResult != NULL)
918  {
919  /* cache the results */
920  CacheLookupResults(scm,
921  pSid,
922  ReqResult);
923  }
924  }
925  else
926  {
927  if (ReqResult != NULL)
928  {
929  /* free the information of our lookup and use the cached
930  information*/
932  ReqResult);
933  }
934 
935  ReqResult = FoundReqResult;
936  }
937 
938  Found = (ReqResult != NULL);
939  }
940  }
941 
942  LeaveCriticalSection(&scm->Lock);
943 
944  /* call the completion callback */
945  if (Found)
946  {
947  CompletionProc(SidCacheMgr,
948  pSid,
949  ReqResult,
950  Context);
951 
952  if (ReqResult != NULL)
953  {
954  HeapFree(scm->Heap,
955  0,
956  ReqResult);
957  }
958  }
959 
961  }
962 
963  return Found;
964 }
#define CreateEvent
Definition: winbase.h:3588
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
PWSTR Names[NAMES_COUNT]
HANDLE LookupThread
Definition: sidcache.c:49
struct _SIDCACHECALLBACKINFO * PSIDCACHECALLBACKINFO
#define TRUE
Definition: types.h:120
#define CloseHandle
Definition: compat.h:407
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
static VOID CacheLookupResults(IN PSIDCACHEMGR scm, IN PSID pSid, IN PSIDREQRESULT ReqResult)
Definition: sidcache.c:394
#define POLICY_VIEW_LOCAL_INFORMATION
Definition: ntsecapi.h:61
uint16_t * PWSTR
Definition: typedefs.h:55
BOOL WINAPI EqualSid(PSID pSid1, PSID pSid2)
Definition: security.c:708
static DWORD WINAPI LookupThreadProc(IN LPVOID lpParameter)
Definition: sidcache.c:448
struct _SIDCACHEENTRY SIDCACHEENTRY
LONG NTSTATUS
Definition: precomp.h:26
HANDLE CreateSidCacheMgr(IN HANDLE Heap, IN LPCWSTR SystemName)
Definition: sidcache.c:589
NTSTATUS WINAPI LsaClose(IN LSA_HANDLE ObjectHandle)
Definition: lsa.c:192
VOID DestroySidCacheMgr(IN HANDLE SidCacheMgr)
Definition: sidcache.c:669
#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:1648
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:869
#define STATUS_NONE_MAPPED
Definition: ntstatus.h:337
uint32_t ULONG_PTR
Definition: typedefs.h:64
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
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
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:848
static BOOL QueueSidLookup(IN PSIDCACHEMGR scm, IN PSID pSid, IN PSIDREQCOMPLETIONPROC CompletionProc, IN PVOID Context)
Definition: sidcache.c:682
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
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
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
static BOOL LookupSidInformation(IN PSIDCACHEMGR scm, IN PSID pSid, OUT PSIDREQRESULT *ReqResult)
Definition: sidcache.c:207
struct _LIST_ENTRY * Flink
Definition: typedefs.h:120
LSA_HANDLE LsaHandle
Definition: sidcache.c:42
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:1646
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:418
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:118
struct _SIDQUEUEENTRY SIDQUEUEENTRY
static const WCHAR Cleanup[]
Definition: register.c:80
Status
Definition: gdiplustypes.h:24
struct _SIDCACHEMGR * PSIDCACHEMGR
ULONG_PTR SIZE_T
Definition: typedefs.h:79
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:784
PSIDCACHECALLBACKINFO Callbacks
Definition: sidcache.c:65
USHORT MaximumLength
Definition: ntsecapi.h:164
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define HeapReAlloc
Definition: compat.h:402
PSIDREQCOMPLETIONPROC CompletionProc
Definition: sidcache.c:56
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB _Outptr_result_maybenull_ PDCB _In_ PDCB _In_ PDIRENT _In_ ULONG _In_ ULONG _In_ PUNICODE_STRING _In_ PACCESS_MASK DesiredAccess
Definition: create.c:4157
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
WCHAR SystemName[1]
Definition: sidcache.c:50
VOID ReferenceSidReqResult(IN HANDLE SidCacheMgr, IN PSIDREQRESULT ReqResult)
Definition: sidcache.c:832
static PSID pSid
Definition: security.c:74
LPWSTR AccountName
Definition: precomp.h:171
#define OUT
Definition: typedefs.h:40
struct tagContext Context
Definition: acpixf.h:1034
unsigned int ULONG
Definition: retypes.h:1
LIST_ENTRY ListEntry
Definition: sidcache.c:63
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
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
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
struct _SIDCACHECALLBACKINFO SIDCACHECALLBACKINFO
static BOOL FindSidInCache(IN PSIDCACHEMGR scm, IN PSID pSid, OUT PSIDREQRESULT *ReqResult)
Definition: sidcache.c:329
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define HeapFree(x, y, z)
Definition: compat.h:403
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