ReactOS  0.4.13-dev-52-g0efcfec
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  CurrentEntry = &scm->CacheListHead;
341  while (CurrentEntry != &scm->CacheListHead)
342  {
343  CacheEntry = CONTAINING_RECORD(CurrentEntry,
345  ListEntry);
346 
347  if (EqualSid(pSid,
348  (PSID)(CacheEntry + 1)))
349  {
350  SIZE_T ReqResultSize;
351  ULONG AccountNameLen, DomainNameLen;
352 
353  Ret = TRUE;
354 
355  AccountNameLen = wcslen(CacheEntry->AccountName);
356  DomainNameLen = wcslen(CacheEntry->DomainName);
357 
358  ReqResultSize = sizeof(SIDREQRESULT) +
359  (((AccountNameLen + 1) +
360  (DomainNameLen + 1)) * sizeof(WCHAR));
361 
362  ReqRes = HeapAlloc(scm->Heap,
363  0,
364  ReqResultSize);
365  if (ReqRes != NULL)
366  {
367  PWSTR Buffer = (PWSTR)(ReqRes + 1);
368 
369  ReqRes->RefCount = 1;
370 
371  ReqRes->AccountName = Buffer;
372  wcscpy(ReqRes->AccountName,
373  CacheEntry->AccountName);
374  Buffer += AccountNameLen + 1;
375 
376  ReqRes->DomainName = Buffer;
377  wcscpy(ReqRes->DomainName,
378  CacheEntry->DomainName);
379  }
380 
381  /* return the result, even if we weren't unable to
382  allocate enough memory! */
383  *ReqResult = ReqRes;
384  break;
385  }
386 
387  CurrentEntry = CurrentEntry->Flink;
388  }
389 
390  return Ret;
391 }
392 
393 
394 static VOID
396  IN PSID pSid,
397  IN PSIDREQRESULT ReqResult)
398 {
399  PSIDCACHEENTRY CacheEntry;
400  DWORD SidLen;
401  SIZE_T AccountNameLen = 0;
402  SIZE_T DomainNameLen = 0;
403  SIZE_T CacheEntrySize = sizeof(SIDCACHEENTRY);
404 
405  /* NOTE: assumes the lists are locked! */
406 
407  SidLen = GetLengthSid(pSid);
408  CacheEntrySize += SidLen;
409 
410  AccountNameLen = wcslen(ReqResult->AccountName);
411  CacheEntrySize += (AccountNameLen + 1) * sizeof(WCHAR);
412 
413  DomainNameLen = wcslen(ReqResult->DomainName);
414  CacheEntrySize += (wcslen(ReqResult->DomainName) + 1) * sizeof(WCHAR);
415 
416  CacheEntry = HeapAlloc(scm->Heap,
417  0,
418  CacheEntrySize);
419  if (CacheEntry != NULL)
420  {
421  PWSTR lpBuf = (PWSTR)((ULONG_PTR)(CacheEntry + 1) + SidLen);
422 
423  CacheEntry->SidNameUse = ReqResult->SidNameUse;
424 
425  /* append the SID */
426  CopySid(SidLen,
427  (PSID)(CacheEntry + 1),
428  pSid);
429 
430  /* append the strings */
431  CacheEntry->AccountName = lpBuf;
432  wcscpy(lpBuf,
433  ReqResult->AccountName);
434  lpBuf += AccountNameLen + 1;
435 
436  CacheEntry->DomainName = lpBuf;
437  wcscpy(lpBuf,
438  ReqResult->DomainName);
439  lpBuf += DomainNameLen + 1;
440 
441  /* add the entry to the cache list */
442  InsertTailList(&scm->CacheListHead,
443  &CacheEntry->ListEntry);
444  }
445 }
446 
447 
448 static DWORD WINAPI
450 {
453 
454  /* Reference the dll to avoid problems in case of accidental
455  FreeLibrary calls... */
456  if (!GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
458  &hModule))
459  {
460  hModule = NULL;
461  }
462 
463  while (scm->RefCount != 0)
464  {
465  PSIDQUEUEENTRY QueueEntry = NULL;
466 
467  EnterCriticalSection(&scm->Lock);
468 
469  /* get the first item of the queue */
470  if (scm->QueueListHead.Flink != &scm->QueueListHead)
471  {
472  QueueEntry = CONTAINING_RECORD(scm->QueueListHead.Flink,
474  ListEntry);
475  RemoveEntryList(&QueueEntry->ListEntry);
476  QueueEntry->ListEntry.Flink = NULL;
477  }
478  else
479  {
480  LeaveCriticalSection(&scm->Lock);
481 
482  /* wait for the next asynchronous lookup queued */
484  INFINITE);
485  continue;
486  }
487 
488  scm->QueueLookingUp = QueueEntry;
489 
490  LeaveCriticalSection(&scm->Lock);
491 
492  if (QueueEntry != NULL)
493  {
494  PSIDREQRESULT ReqResult, FoundReqResult;
495  PSID pSid = (PSID)(QueueEntry + 1);
496 
497  /* lookup the SID information */
498  if (!LookupSidInformation(scm,
499  pSid,
500  &ReqResult))
501  {
502  ReqResult = NULL;
503  }
504 
505  EnterCriticalSection(&scm->Lock);
506 
507  /* see if the SID was added to the cache in the meanwhile */
508  if (!FindSidInCache(scm,
509  pSid,
510  &FoundReqResult))
511  {
512  if (ReqResult != NULL)
513  {
514  /* cache the results */
515  CacheLookupResults(scm,
516  pSid,
517  ReqResult);
518  }
519  }
520  else
521  {
522  if (ReqResult != NULL)
523  {
524  /* free the information of our lookup and use the cached
525  information*/
527  ReqResult);
528  }
529 
530  ReqResult = FoundReqResult;
531  }
532 
533  /* notify the callers unless the lookup was cancelled */
534  if (scm->QueueLookingUp != NULL)
535  {
536  ULONG i = 0;
537 
538  while (scm->QueueLookingUp != NULL &&
539  i < QueueEntry->CallbackCount)
540  {
541  PVOID Context;
542  PSIDREQCOMPLETIONPROC CompletionProc;
543 
544  Context = QueueEntry->Callbacks[i].Context;
545  CompletionProc = QueueEntry->Callbacks[i].CompletionProc;
546 
547  LeaveCriticalSection(&scm->Lock);
548 
549  /* call the completion proc without holding the lock! */
550  CompletionProc(ScmToHandle(scm),
551  pSid,
552  ReqResult,
553  Context);
554 
555  EnterCriticalSection(&scm->Lock);
556 
557  i++;
558  }
559 
560  scm->QueueLookingUp = NULL;
561  }
562 
563  LeaveCriticalSection(&scm->Lock);
564 
565  /* free the queue item */
566  FreeQueueEntry(scm,
567  QueueEntry);
568  }
569  }
570 
571  CleanupSidCacheMgr(scm);
572 
573  HeapFree(scm->Heap,
574  0,
575  scm);
576 
577  if (hModule != NULL)
578  {
579  /* dereference the library and exit */
581  0);
582  }
583 
584  return 0;
585 }
586 
587 
588 
589 HANDLE
591  IN LPCWSTR SystemName)
592 {
593  PSIDCACHEMGR scm;
594 
595  if (SystemName == NULL)
596  SystemName = L"";
597 
598  scm = HeapAlloc(Heap,
599  0,
601  SystemName[wcslen(SystemName) + 1]));
602  if (scm != NULL)
603  {
604  /* zero the static part of the structure */
605  ZeroMemory(scm,
607  SystemName));
608 
609  scm->RefCount = 1;
610  scm->Heap = Heap;
611 
612  wcscpy(scm->SystemName,
613  SystemName);
614 
618 
620  FALSE,
621  FALSE,
622  NULL);
623  if (scm->LookupEvent == NULL)
624  {
625  goto Cleanup;
626  }
627 
630  &scm->LsaHandle))
631  {
632  goto Cleanup;
633  }
634 
636  0,
638  scm,
639  0,
640  NULL);
641  if (scm->LookupThread == NULL)
642  {
643 Cleanup:
644  if (scm->LookupEvent != NULL)
645  {
646  CloseHandle(scm->LookupEvent);
647  }
648 
649  if (scm->LsaHandle != NULL)
650  {
651  LsaClose(scm->LsaHandle);
652  }
653 
654  HeapFree(Heap,
655  0,
656  scm);
657  scm = NULL;
658  }
659  }
660  else
661  {
663  }
664 
665  return (HANDLE)scm;
666 }
667 
668 
669 VOID
671 {
672  PSIDCACHEMGR scm = HandleToScm(SidCacheMgr);
673 
674  if (scm != NULL)
675  {
676  /* remove the keep-alive reference */
678  }
679 }
680 
681 
682 static BOOL
684  IN PSID pSid,
685  IN PSIDREQCOMPLETIONPROC CompletionProc,
686  IN PVOID Context)
687 {
688  PLIST_ENTRY CurrentEntry;
689  PSIDQUEUEENTRY QueueEntry, FoundEntry = NULL;
690  BOOL Ret = FALSE;
691 
692  /* NOTE: assumes the lists are locked! */
693 
694  if (scm->QueueLookingUp != NULL &&
695  EqualSid(pSid,
696  (PSID)(scm->QueueLookingUp + 1)))
697  {
698  FoundEntry = scm->QueueLookingUp;
699  }
700  else
701  {
702  CurrentEntry = &scm->QueueListHead;
703  while (CurrentEntry != &scm->QueueListHead)
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  CurrentEntry = CurrentEntry->Flink;
717  }
718  }
719 
720  if (FoundEntry == NULL)
721  {
722  DWORD SidLength = GetLengthSid(pSid);
723 
724  FoundEntry = HeapAlloc(scm->Heap,
725  0,
726  sizeof(SIDQUEUEENTRY) + SidLength);
727  if (FoundEntry != NULL)
728  {
729  CopySid(SidLength,
730  (PSID)(FoundEntry + 1),
731  pSid);
732 
733  FoundEntry->CallbackCount = 1;
734  FoundEntry->Callbacks = HeapAlloc(scm->Heap,
735  0,
736  sizeof(SIDCACHECALLBACKINFO));
737 
738  if (FoundEntry->Callbacks != NULL)
739  {
740  FoundEntry->Callbacks[0].CompletionProc = CompletionProc;
741  FoundEntry->Callbacks[0].Context = Context;
742 
743  /* append it to the queue */
744  InsertTailList(&scm->QueueListHead,
745  &FoundEntry->ListEntry);
746 
747  /* signal the lookup event */
748  SetEvent(scm->LookupEvent);
749 
750  Ret = TRUE;
751  }
752  else
753  {
754  /* unable to queue it because we couldn't allocate the callbacks
755  array, free the memory and return */
756  HeapFree(scm->Heap,
757  0,
758  FoundEntry);
759  }
760  }
761  }
762  else
763  {
764  PSIDCACHECALLBACKINFO Sidccb;
765 
766  /* add the callback */
767  Sidccb = HeapReAlloc(scm->Heap,
768  0,
769  FoundEntry->Callbacks,
770  (FoundEntry->CallbackCount + 1) * sizeof(SIDCACHECALLBACKINFO));
771  if (Sidccb != NULL)
772  {
773  FoundEntry->Callbacks = Sidccb;
774  FoundEntry->Callbacks[FoundEntry->CallbackCount].CompletionProc = CompletionProc;
775  FoundEntry->Callbacks[FoundEntry->CallbackCount++].Context = Context;
776 
777  Ret = TRUE;
778  }
779  }
780 
781  return Ret;
782 }
783 
784 
785 VOID
787  IN PSID pSid)
788 {
789  PLIST_ENTRY CurrentEntry;
790  PSIDQUEUEENTRY QueueEntry;
791  PSIDCACHEMGR scm;
792 
793  scm = ReferenceSidCacheMgr(SidCacheMgr);
794  if (scm != NULL)
795  {
796  EnterCriticalSection(&scm->Lock);
797 
798  if (scm->QueueLookingUp != NULL &&
799  EqualSid(pSid,
800  (PSID)(scm->QueueLookingUp + 1)))
801  {
802  /* don't free the queue lookup item! this will be
803  done in the lookup thread */
804  scm->QueueLookingUp = NULL;
805  }
806  else
807  {
808  CurrentEntry = &scm->QueueListHead;
809  while (CurrentEntry != &scm->QueueListHead)
810  {
811  QueueEntry = CONTAINING_RECORD(CurrentEntry,
813  ListEntry);
814 
815  if (EqualSid(pSid,
816  (PSID)(QueueEntry + 1)))
817  {
818  FreeQueueEntry(scm,
819  QueueEntry);
820  break;
821  }
822 
823  CurrentEntry = CurrentEntry->Flink;
824  }
825  }
826 
827  LeaveCriticalSection(&scm->Lock);
828 
830  }
831 }
832 
833 
834 VOID
836  IN PSIDREQRESULT ReqResult)
837 {
838  PSIDCACHEMGR scm;
839 
840  scm = ReferenceSidCacheMgr(SidCacheMgr);
841  if (scm != NULL)
842  {
843  InterlockedIncrement(&ReqResult->RefCount);
844 
846  }
847 }
848 
849 
850 VOID
852  IN PSIDREQRESULT ReqResult)
853 {
854  PSIDCACHEMGR scm;
855 
856  scm = ReferenceSidCacheMgr(SidCacheMgr);
857  if (scm != NULL)
858  {
859  if (InterlockedDecrement(&ReqResult->RefCount) == 0)
860  {
861  HeapFree(scm->Heap,
862  0,
863  ReqResult);
864  }
865 
867  }
868 }
869 
870 
871 BOOL
873  IN PSID pSid,
874  IN PSIDREQCOMPLETIONPROC CompletionProc,
875  IN PVOID Context)
876 {
877  BOOL Found = FALSE;
878  PSIDREQRESULT ReqResult = NULL;
879  PSIDCACHEMGR scm;
880 
881  scm = ReferenceSidCacheMgr(SidCacheMgr);
882  if (scm != NULL)
883  {
884  EnterCriticalSection(&scm->Lock);
885 
886  /* search the cache */
887  Found = FindSidInCache(scm,
888  pSid,
889  &ReqResult);
890 
891  if (!Found)
892  {
893  /* the sid is not in the cache, queue it if not already queued */
894  if (!QueueSidLookup(scm,
895  pSid,
896  CompletionProc,
897  Context))
898  {
899  PSIDREQRESULT FoundReqResult = NULL;
900 
901  /* unable to queue it, look it up now */
902 
903  LeaveCriticalSection(&scm->Lock);
904 
905  /* lookup everything we need */
906  if (!LookupSidInformation(scm,
907  pSid,
908  &ReqResult))
909  {
910  ReqResult = NULL;
911  }
912 
913  EnterCriticalSection(&scm->Lock);
914 
915  /* see if the SID was added to the cache in the meanwhile */
916  if (!FindSidInCache(scm,
917  pSid,
918  &FoundReqResult))
919  {
920  if (ReqResult != NULL)
921  {
922  /* cache the results */
923  CacheLookupResults(scm,
924  pSid,
925  ReqResult);
926  }
927  }
928  else
929  {
930  if (ReqResult != NULL)
931  {
932  /* free the information of our lookup and use the cached
933  information*/
935  ReqResult);
936  }
937 
938  ReqResult = FoundReqResult;
939  }
940 
941  Found = (ReqResult != NULL);
942  }
943  }
944 
945  LeaveCriticalSection(&scm->Lock);
946 
947  /* call the completion callback */
948  if (Found)
949  {
950  CompletionProc(SidCacheMgr,
951  pSid,
952  ReqResult,
953  Context);
954 
955  if (ReqResult != NULL)
956  {
957  HeapFree(scm->Heap,
958  0,
959  ReqResult);
960  }
961  }
962 
964  }
965 
966  return Found;
967 }
#define CreateEvent
Definition: winbase.h:3562
LIST_ENTRY QueueListHead
Definition: sidcache.c:44
PWSTR DomainName
Definition: sidcache.c:75
#define IN
Definition: typedefs.h:38
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:398
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:405
static VOID CacheLookupResults(IN PSIDCACHEMGR scm, IN PSID pSid, IN PSIDREQRESULT ReqResult)
Definition: sidcache.c:395
#define POLICY_VIEW_LOCAL_INFORMATION
Definition: ntsecapi.h:61
uint16_t * PWSTR
Definition: typedefs.h:54
BOOL WINAPI EqualSid(PSID pSid1, PSID pSid2)
Definition: security.c:708
static DWORD WINAPI LookupThreadProc(IN LPVOID lpParameter)
Definition: sidcache.c:449
struct _SIDCACHEENTRY SIDCACHEENTRY
LONG NTSTATUS
Definition: precomp.h:26
HANDLE CreateSidCacheMgr(IN HANDLE Heap, IN LPCWSTR SystemName)
Definition: sidcache.c:590
NTSTATUS WINAPI LsaClose(IN LSA_HANDLE ObjectHandle)
Definition: lsa.c:192
VOID DestroySidCacheMgr(IN HANDLE SidCacheMgr)
Definition: sidcache.c:670
#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:679
#define ZeroMemory
Definition: winbase.h:1635
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:872
#define STATUS_NONE_MAPPED
Definition: ntstatus.h:337
uint32_t ULONG_PTR
Definition: typedefs.h:63
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:514
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:851
static BOOL QueueSidLookup(IN PSIDCACHEMGR scm, IN PSID pSid, IN PSIDREQCOMPLETIONPROC CompletionProc, IN PVOID Context)
Definition: sidcache.c:683
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:112
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
Definition: synch.c:697
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:119
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:8
#define CopyMemory
Definition: winbase.h:1633
LSA_UNICODE_STRING Name
Definition: ntsecapi.h:400
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:409
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:234
Definition: typedefs.h:117
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:78
BOOL WINAPI GetModuleHandleExW(IN DWORD dwFlags, IN LPCWSTR lpwModuleName OPTIONAL, OUT HMODULE *phModule)
Definition: loader.c:873
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:786
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:393
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:835
static PSID pSid
Definition: security.c:74
LPWSTR AccountName
Definition: precomp.h:171
#define OUT
Definition: typedefs.h:39
struct tagContext Context
Definition: acpixf.h:1012
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:394
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