xref: /reactos/sdk/lib/cmlib/cmse.c (revision 3e1f4074)
1 /*
2  * PROJECT:         ReactOS Kernel
3  * LICENSE:         GPL - See COPYING in the top level directory
4  * FILE:            lib/cmlib/cmse.c
5  * PURPOSE:         Configuration Manager Library - Security Subsystem Interface
6  * PROGRAMMERS:     Hermes Belusca-Maito (hermes.belusca@sfr.fr)
7  */
8 
9 /* INCLUDES ******************************************************************/
10 
11 #include "cmlib.h"
12 #define NDEBUG
13 #include <debug.h>
14 
15 /* FUNCTIONS *****************************************************************/
16 
17 VOID
18 NTAPI
19 CmpRemoveSecurityCellList(IN PHHIVE Hive,
20                           IN HCELL_INDEX SecurityCell)
21 {
22     PCM_KEY_SECURITY SecurityData, FlinkCell, BlinkCell;
23 
24     PAGED_CODE();
25 
26     // ASSERT( (((PCMHIVE)Hive)->HiveSecurityLockOwner == KeGetCurrentThread()) || (CmpTestRegistryLockExclusive() == TRUE) );
27 
28     SecurityData = (PCM_KEY_SECURITY)HvGetCell(Hive, SecurityCell);
29     if (!SecurityData) return;
30 
31     FlinkCell = (PCM_KEY_SECURITY)HvGetCell(Hive, SecurityData->Flink);
32     if (!FlinkCell)
33     {
34         HvReleaseCell(Hive, SecurityCell);
35         return;
36     }
37 
38     BlinkCell = (PCM_KEY_SECURITY)HvGetCell(Hive, SecurityData->Blink);
39     if (!BlinkCell)
40     {
41         HvReleaseCell(Hive, SecurityData->Flink);
42         HvReleaseCell(Hive, SecurityCell);
43         return;
44     }
45 
46     /* Sanity checks */
47     ASSERT(FlinkCell->Blink == SecurityCell);
48     ASSERT(BlinkCell->Flink == SecurityCell);
49 
50     /* Unlink the security block and free it */
51     FlinkCell->Blink = SecurityData->Blink;
52     BlinkCell->Flink = SecurityData->Flink;
53 #ifdef USE_CM_CACHE
54     CmpRemoveFromSecurityCache(Hive, SecurityCell);
55 #endif
56 
57     /* Release the cells */
58     HvReleaseCell(Hive, SecurityData->Blink);
59     HvReleaseCell(Hive, SecurityData->Flink);
60     HvReleaseCell(Hive, SecurityCell);
61 }
62 
63 VOID
64 NTAPI
65 CmpFreeSecurityDescriptor(IN PHHIVE Hive,
66                           IN HCELL_INDEX Cell)
67 {
68     PCM_KEY_NODE CellData;
69     PCM_KEY_SECURITY SecurityData;
70 
71     PAGED_CODE();
72 
73     // ASSERT( (((PCMHIVE)Hive)->HiveSecurityLockOwner == KeGetCurrentThread()) || (CmpTestRegistryLockExclusive() == TRUE) );
74 
75     CellData = (PCM_KEY_NODE)HvGetCell(Hive, Cell);
76     if (!CellData) return;
77 
78     ASSERT(CellData->Signature == CM_KEY_NODE_SIGNATURE);
79 
80     // FIXME: ReactOS-specific: check whether this key has a security block.
81     // On Windows there is no such check, all keys seem to have a valid
82     // security block.
83     // If we remove this check on ReactOS (and continue running) then we get
84     // a BSOD at the end...
85     if (CellData->Security == HCELL_NIL)
86     {
87         DPRINT("Cell 0x%08x (data 0x%p) has no security block!\n", Cell, CellData);
88         HvReleaseCell(Hive, Cell);
89         return;
90     }
91 
92     SecurityData = (PCM_KEY_SECURITY)HvGetCell(Hive, CellData->Security);
93     if (!SecurityData)
94     {
95         HvReleaseCell(Hive, Cell);
96         return;
97     }
98 
99     ASSERT(SecurityData->Signature == CM_KEY_SECURITY_SIGNATURE);
100 
101     if (SecurityData->ReferenceCount > 1)
102     {
103         SecurityData->ReferenceCount--;
104     }
105     else // if (SecurityData->ReferenceCount <= 1)
106     {
107         CmpRemoveSecurityCellList(Hive, CellData->Security);
108         HvFreeCell(Hive, CellData->Security);
109     }
110 
111     CellData->Security = HCELL_NIL;
112     HvReleaseCell(Hive, CellData->Security);
113     HvReleaseCell(Hive, Cell);
114 }
115