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 #define SD_CACHE_ENTRIES 0x100
33 LIST_ENTRY ObpSdCache
[SD_CACHE_ENTRIES
];
34 FAST_MUTEX ObpSdCacheMutex
;
36 /* FUNCTIONS ****************************************************************/
44 for (i
= 0; i
< (sizeof(ObpSdCache
) / sizeof(ObpSdCache
[0])); i
++)
46 InitializeListHead(&ObpSdCache
[i
]);
49 ExInitializeFastMutex(&ObpSdCacheMutex
);
51 return STATUS_SUCCESS
;
58 /* can't acquire a fast mutex in the early boot process... */
59 if(KeGetCurrentThread() != NULL
)
61 ExAcquireFastMutex(&ObpSdCacheMutex
);
67 ObpSdCacheUnlock(VOID
)
69 /* can't acquire a fast mutex in the early boot process... */
70 if(KeGetCurrentThread() != NULL
)
72 ExReleaseFastMutex(&ObpSdCacheMutex
);
87 for (i
= 0; i
< Length
; i
++)
98 ObpHashSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor
)
109 RtlGetOwnerSecurityDescriptor(SecurityDescriptor
,
113 RtlGetGroupSecurityDescriptor(SecurityDescriptor
,
117 RtlGetDaclSecurityDescriptor(SecurityDescriptor
,
122 RtlGetSaclSecurityDescriptor(SecurityDescriptor
,
130 Value
+= ObpHash(Owner
, RtlLengthSid(Owner
));
135 Value
+= ObpHash(Group
, RtlLengthSid(Group
));
138 if (DaclPresent
== TRUE
&& Dacl
!= NULL
)
140 Value
+= ObpHash(Dacl
, Dacl
->AclSize
);
143 if (SaclPresent
== TRUE
&& Sacl
!= NULL
)
145 Value
+= ObpHash(Sacl
, Sacl
->AclSize
);
152 static PSD_CACHE_ENTRY
153 ObpCreateCacheEntry(IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
156 OUT PSECURITY_DESCRIPTOR
*NewSD
)
158 PSECURITY_DESCRIPTOR Sd
;
159 PSD_CACHE_ENTRY CacheEntry
;
162 DPRINT("ObpCreateCacheEntry() called\n");
164 Length
= RtlLengthSecurityDescriptor(SecurityDescriptor
);
166 CacheEntry
= ExAllocatePool(NonPagedPool
,
167 sizeof(SD_CACHE_ENTRY
) + Length
);
168 if (CacheEntry
== NULL
)
170 DPRINT1("ExAllocatePool() failed\n");
174 CacheEntry
->HashValue
= HashValue
;
175 CacheEntry
->Index
= Index
;
176 CacheEntry
->RefCount
= 1;
178 Sd
= (PSECURITY_DESCRIPTOR
)(CacheEntry
+ 1);
185 DPRINT("ObpCreateCacheEntry() done\n");
192 ObpCompareSecurityDescriptors(IN PSECURITY_DESCRIPTOR Sd1
,
193 IN PSECURITY_DESCRIPTOR Sd2
)
198 Length1
= RtlLengthSecurityDescriptor(Sd1
);
199 Length2
= RtlLengthSecurityDescriptor(Sd2
);
200 if (Length1
!= Length2
)
203 if (RtlCompareMemory(Sd1
, Sd2
, Length1
) != Length1
)
212 ObpAddSecurityDescriptor(IN PSECURITY_DESCRIPTOR SourceSD
,
213 OUT PSECURITY_DESCRIPTOR
*DestinationSD
)
215 PSECURITY_DESCRIPTOR Sd
;
216 PLIST_ENTRY CurrentEntry
;
217 PSD_CACHE_ENTRY CacheEntry
;
222 DPRINT("ObpAddSecurityDescriptor() called\n");
224 HashValue
= ObpHashSecurityDescriptor(SourceSD
);
225 Index
= HashValue
& 0xFF;
229 if (!IsListEmpty(&ObpSdCache
[Index
]))
231 CurrentEntry
= ObpSdCache
[Index
].Flink
;
232 while (CurrentEntry
!= &ObpSdCache
[Index
])
234 CacheEntry
= CONTAINING_RECORD(CurrentEntry
,
237 Sd
= (PSECURITY_DESCRIPTOR
)(CacheEntry
+ 1);
239 if (CacheEntry
->HashValue
== HashValue
&&
240 ObpCompareSecurityDescriptors(SourceSD
, Sd
))
242 CacheEntry
->RefCount
++;
243 DPRINT("RefCount %lu\n", CacheEntry
->RefCount
);
248 DPRINT("ObpAddSecurityDescriptor() done\n");
250 return STATUS_SUCCESS
;
253 CurrentEntry
= CurrentEntry
->Flink
;
257 CacheEntry
= ObpCreateCacheEntry(SourceSD
,
261 if (CacheEntry
== NULL
)
263 DPRINT1("ObpCreateCacheEntry() failed\n");
264 Status
= STATUS_INSUFFICIENT_RESOURCES
;
268 DPRINT("RefCount 1\n");
269 InsertTailList(&ObpSdCache
[Index
], &CacheEntry
->ListEntry
);
270 Status
= STATUS_SUCCESS
;
275 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
;
312 ObpReferenceCachedSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor
)
314 PSD_CACHE_ENTRY CacheEntry
;
316 DPRINT("ObpReferenceCachedSecurityDescriptor() called\n");
320 CacheEntry
= (PSD_CACHE_ENTRY
)((ULONG_PTR
)SecurityDescriptor
- sizeof(SD_CACHE_ENTRY
));
322 CacheEntry
->RefCount
++;
323 DPRINT("RefCount %lu\n", CacheEntry
->RefCount
);
327 DPRINT("ObpReferenceCachedSecurityDescriptor() done\n");
333 ObpDereferenceCachedSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor
)
335 DPRINT("ObpDereferenceCachedSecurityDescriptor() called\n");
337 ObpRemoveSecurityDescriptor(SecurityDescriptor
);
339 DPRINT("ObpDereferenceCachedSecurityDescriptor() done\n");