set eol-style:native
[reactos.git] / reactos / lib / rtl / security.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: lib/rtl/security.c
5 * PURPOSE: Security related functions and Security Objects
6 * PROGRAMMER: Eric Kohl
7 */
8
9 /* INCLUDES *****************************************************************/
10
11 #include <rtl.h>
12
13 #define NDEBUG
14 #include <debug.h>
15
16 /* FUNCTIONS ***************************************************************/
17
18 /*
19 * @implemented
20 */
21 NTSTATUS NTAPI
22 RtlImpersonateSelf(IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
23 {
24 HANDLE ProcessToken;
25 HANDLE ImpersonationToken;
26 NTSTATUS Status;
27 OBJECT_ATTRIBUTES ObjAttr;
28 SECURITY_QUALITY_OF_SERVICE Sqos;
29
30 PAGED_CODE_RTL();
31
32 Status = ZwOpenProcessToken(NtCurrentProcess(),
33 TOKEN_DUPLICATE,
34 &ProcessToken);
35 if (!NT_SUCCESS(Status))
36 {
37 DPRINT1("NtOpenProcessToken() failed (Status %lx)\n", Status);
38 return(Status);
39 }
40
41 Sqos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
42 Sqos.ImpersonationLevel = ImpersonationLevel;
43 Sqos.ContextTrackingMode = 0;
44 Sqos.EffectiveOnly = FALSE;
45
46 InitializeObjectAttributes(
47 &ObjAttr,
48 NULL,
49 0,
50 NULL,
51 NULL
52 );
53
54 ObjAttr.SecurityQualityOfService = &Sqos;
55
56 Status = ZwDuplicateToken(ProcessToken,
57 TOKEN_IMPERSONATE,
58 &ObjAttr,
59 Sqos.EffectiveOnly, /* why both here _and_ in Sqos? */
60 TokenImpersonation,
61 &ImpersonationToken);
62 if (!NT_SUCCESS(Status))
63 {
64 DPRINT1("NtDuplicateToken() failed (Status %lx)\n", Status);
65 NtClose(ProcessToken);
66 return(Status);
67 }
68
69 Status = ZwSetInformationThread(NtCurrentThread(),
70 ThreadImpersonationToken,
71 &ImpersonationToken,
72 sizeof(HANDLE));
73 if (!NT_SUCCESS(Status))
74 {
75 DPRINT1("NtSetInformationThread() failed (Status %lx)\n", Status);
76 }
77
78 ZwClose(ImpersonationToken);
79 ZwClose(ProcessToken);
80
81 return(Status);
82 }
83
84
85 /*
86 * @implemented
87 */
88 NTSTATUS NTAPI
89 RtlAdjustPrivilege(IN ULONG Privilege,
90 IN BOOLEAN Enable,
91 IN BOOLEAN CurrentThread,
92 OUT PBOOLEAN Enabled)
93 {
94 TOKEN_PRIVILEGES NewState;
95 TOKEN_PRIVILEGES OldState;
96 ULONG ReturnLength;
97 HANDLE TokenHandle;
98 NTSTATUS Status;
99
100 PAGED_CODE_RTL();
101
102 DPRINT ("RtlAdjustPrivilege() called\n");
103
104 if (CurrentThread)
105 {
106 Status = ZwOpenThreadToken (NtCurrentThread (),
107 TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
108 FALSE,
109 &TokenHandle);
110 }
111 else
112 {
113 Status = ZwOpenProcessToken (NtCurrentProcess (),
114 TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
115 &TokenHandle);
116 }
117
118 if (!NT_SUCCESS (Status))
119 {
120 DPRINT1 ("Retrieving token handle failed (Status %lx)\n", Status);
121 return Status;
122 }
123
124 OldState.PrivilegeCount = 1;
125
126 NewState.PrivilegeCount = 1;
127 NewState.Privileges[0].Luid.LowPart = Privilege;
128 NewState.Privileges[0].Luid.HighPart = 0;
129 NewState.Privileges[0].Attributes = (Enable) ? SE_PRIVILEGE_ENABLED : 0;
130
131 Status = ZwAdjustPrivilegesToken (TokenHandle,
132 FALSE,
133 &NewState,
134 sizeof(TOKEN_PRIVILEGES),
135 &OldState,
136 &ReturnLength);
137 ZwClose (TokenHandle);
138 if (Status == STATUS_NOT_ALL_ASSIGNED)
139 {
140 DPRINT1 ("Failed to assign all privileges\n");
141 return STATUS_PRIVILEGE_NOT_HELD;
142 }
143 if (!NT_SUCCESS(Status))
144 {
145 DPRINT1 ("NtAdjustPrivilegesToken() failed (Status %lx)\n", Status);
146 return Status;
147 }
148
149 if (OldState.PrivilegeCount == 0)
150 {
151 *Enabled = Enable;
152 }
153 else
154 {
155 *Enabled = (OldState.Privileges[0].Attributes & SE_PRIVILEGE_ENABLED);
156 }
157
158 DPRINT ("RtlAdjustPrivilege() done\n");
159
160 return STATUS_SUCCESS;
161 }
162
163 /*
164 * @implemented
165 */
166 NTSTATUS
167 NTAPI
168 RtlDeleteSecurityObject(IN PSECURITY_DESCRIPTOR *ObjectDescriptor)
169 {
170 DPRINT("RtlDeleteSecurityObject(%p)\n", ObjectDescriptor);
171
172 RtlFreeHeap(RtlGetProcessHeap(),
173 0,
174 *ObjectDescriptor);
175
176 return STATUS_SUCCESS;
177 }
178
179
180 /*
181 * @unimplemented
182 */
183 NTSTATUS
184 NTAPI
185 RtlNewSecurityObject(IN PSECURITY_DESCRIPTOR ParentDescriptor,
186 IN PSECURITY_DESCRIPTOR CreatorDescriptor,
187 OUT PSECURITY_DESCRIPTOR *NewDescriptor,
188 IN BOOLEAN IsDirectoryObject,
189 IN HANDLE Token,
190 IN PGENERIC_MAPPING GenericMapping)
191 {
192 UNIMPLEMENTED;
193 return STATUS_NOT_IMPLEMENTED;
194 }
195
196
197 /*
198 * @unimplemented
199 */
200 NTSTATUS
201 NTAPI
202 RtlQuerySecurityObject(IN PSECURITY_DESCRIPTOR ObjectDescriptor,
203 IN SECURITY_INFORMATION SecurityInformation,
204 OUT PSECURITY_DESCRIPTOR ResultantDescriptor,
205 IN ULONG DescriptorLength,
206 OUT PULONG ReturnLength)
207 {
208 UNIMPLEMENTED;
209 return STATUS_NOT_IMPLEMENTED;
210 }
211
212
213 /*
214 * @unimplemented
215 */
216 NTSTATUS
217 NTAPI
218 RtlSetSecurityObject(IN SECURITY_INFORMATION SecurityInformation,
219 IN PSECURITY_DESCRIPTOR ModificationDescriptor,
220 OUT PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor,
221 IN PGENERIC_MAPPING GenericMapping,
222 IN HANDLE Token)
223 {
224 UNIMPLEMENTED;
225 return STATUS_NOT_IMPLEMENTED;
226 }
227 /* EOF */