3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/ob/sdcache.c
6 * PURPOSE: No purpose listed.
8 * PROGRAMMERS: David Welch (welch@cwcom.net)
11 /* INCLUDES *****************************************************************/
15 #include <internal/debug.h>
18 /* TYPES ********************************************************************/
20 typedef struct _SD_CACHE_ENTRY
26 } SD_CACHE_ENTRY
, *PSD_CACHE_ENTRY
;
29 /* GLOBALS ******************************************************************/
31 PLIST_ENTRY ObpSdCache
;
32 KSPIN_LOCK ObpSdCacheSpinLock
;
36 #define SD_CACHE_ENTRIES 0x100
38 /* FUNCTIONS ****************************************************************/
45 ObpSdCache
= ExAllocatePool(NonPagedPool
,
46 SD_CACHE_ENTRIES
* sizeof(LIST_ENTRY
));
47 if (ObpSdCache
== NULL
)
49 return STATUS_INSUFFICIENT_RESOURCES
;
52 for (i
= 0; i
< SD_CACHE_ENTRIES
; i
++)
54 InitializeListHead(&ObpSdCache
[i
]);
57 KeInitializeSpinLock(&ObpSdCacheSpinLock
);
59 return STATUS_SUCCESS
;
66 KeAcquireSpinLock(&ObpSdCacheSpinLock
,
72 ObpSdCacheUnlock(VOID
)
74 KeReleaseSpinLock(&ObpSdCacheSpinLock
,
89 for (i
= 0; i
< Length
; i
++)
100 ObpHashSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor
)
111 RtlGetOwnerSecurityDescriptor(SecurityDescriptor
,
115 RtlGetGroupSecurityDescriptor(SecurityDescriptor
,
119 RtlGetDaclSecurityDescriptor(SecurityDescriptor
,
124 RtlGetSaclSecurityDescriptor(SecurityDescriptor
,
132 Value
+= ObpHash(Owner
, RtlLengthSid(Owner
));
137 Value
+= ObpHash(Group
, RtlLengthSid(Group
));
140 if (DaclPresent
== TRUE
&& Dacl
!= NULL
)
142 Value
+= ObpHash(Dacl
, Dacl
->AclSize
);
145 if (SaclPresent
== TRUE
&& Sacl
!= NULL
)
147 Value
+= ObpHash(Sacl
, Sacl
->AclSize
);
154 static PSD_CACHE_ENTRY
155 ObpCreateCacheEntry(IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
158 OUT PSECURITY_DESCRIPTOR
*NewSD
)
160 PSECURITY_DESCRIPTOR Sd
;
161 PSD_CACHE_ENTRY CacheEntry
;
164 DPRINT("ObpCreateCacheEntry() called\n");
166 Length
= RtlLengthSecurityDescriptor(SecurityDescriptor
);
168 CacheEntry
= ExAllocatePool(NonPagedPool
,
169 sizeof(SD_CACHE_ENTRY
) + Length
);
170 if (CacheEntry
== NULL
)
172 DPRINT1("ExAllocatePool() failed\n");
176 CacheEntry
->HashValue
= HashValue
;
177 CacheEntry
->Index
= Index
;
178 CacheEntry
->RefCount
= 1;
180 Sd
= (PSECURITY_DESCRIPTOR
)(CacheEntry
+ 1);
187 DPRINT("ObpCreateCacheEntry() done\n");
194 ObpCompareSecurityDescriptors(IN PSECURITY_DESCRIPTOR Sd1
,
195 IN PSECURITY_DESCRIPTOR Sd2
)
200 Length1
= RtlLengthSecurityDescriptor(Sd1
);
201 Length2
= RtlLengthSecurityDescriptor(Sd2
);
202 if (Length1
!= Length2
)
205 if (RtlCompareMemory(Sd1
, Sd2
, Length1
) != Length1
)
213 ObpAddSecurityDescriptor(IN PSECURITY_DESCRIPTOR SourceSD
,
214 OUT PSECURITY_DESCRIPTOR
*DestinationSD
)
216 PSECURITY_DESCRIPTOR Sd
;
217 PLIST_ENTRY CurrentEntry
;
218 PSD_CACHE_ENTRY CacheEntry
;
223 DPRINT("ObpAddSecurityDescriptor() called\n");
225 HashValue
= ObpHashSecurityDescriptor(SourceSD
);
226 Index
= HashValue
& 0xFF;
230 if (!IsListEmpty(&ObpSdCache
[Index
]))
232 CurrentEntry
= ObpSdCache
[Index
].Flink
;
233 while (CurrentEntry
!= &ObpSdCache
[Index
])
235 CacheEntry
= CONTAINING_RECORD(CurrentEntry
,
238 Sd
= (PSECURITY_DESCRIPTOR
)(CacheEntry
+ 1);
240 if (CacheEntry
->HashValue
== HashValue
&&
241 ObpCompareSecurityDescriptors(SourceSD
, Sd
))
243 CacheEntry
->RefCount
++;
244 DPRINT("RefCount %lu\n", CacheEntry
->RefCount
);
249 DPRINT("ObpAddSecurityDescriptor() done\n");
251 return STATUS_SUCCESS
;
254 CurrentEntry
= CurrentEntry
->Flink
;
258 CacheEntry
= ObpCreateCacheEntry(SourceSD
,
262 if (CacheEntry
== NULL
)
264 DPRINT1("ObpCreateCacheEntry() failed\n");
265 Status
= STATUS_INSUFFICIENT_RESOURCES
;
269 DPRINT("RefCount 1\n");
270 InsertTailList(&ObpSdCache
[Index
], &CacheEntry
->ListEntry
);
271 Status
= STATUS_SUCCESS
;
276 DPRINT("ObpAddSecurityDescriptor() done\n");
283 ObpRemoveSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor
)
285 PSD_CACHE_ENTRY CacheEntry
;
287 DPRINT("ObpRemoveSecurityDescriptor() called\n");
291 CacheEntry
= (PSD_CACHE_ENTRY
)((ULONG_PTR
)SecurityDescriptor
- sizeof(SD_CACHE_ENTRY
));
293 CacheEntry
->RefCount
--;
294 DPRINT("RefCount %lu\n", CacheEntry
->RefCount
);
295 if (CacheEntry
->RefCount
== 0)
297 DPRINT("Remove cache entry\n");
298 RemoveEntryList(&CacheEntry
->ListEntry
);
299 ExFreePool(CacheEntry
);
304 DPRINT("ObpRemoveSecurityDescriptor() done\n");
306 return STATUS_SUCCESS
;
311 ObpReferenceCachedSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor
)
313 PSD_CACHE_ENTRY CacheEntry
;
315 DPRINT("ObpReferenceCachedSecurityDescriptor() called\n");
319 CacheEntry
= (PSD_CACHE_ENTRY
)((ULONG_PTR
)SecurityDescriptor
- sizeof(SD_CACHE_ENTRY
));
321 CacheEntry
->RefCount
++;
322 DPRINT("RefCount %lu\n", CacheEntry
->RefCount
);
326 DPRINT("ObpReferenceCachedSecurityDescriptor() done\n");
331 ObpDereferenceCachedSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor
)
333 DPRINT("ObpDereferenceCachedSecurityDescriptor() called\n");
335 ObpRemoveSecurityDescriptor(SecurityDescriptor
);
337 DPRINT("ObpDereferenceCachedSecurityDescriptor() done\n");