update for HEAD-2003091401
[reactos.git] / lib / ntdll / rtl / security.c
1 /* $Id$
2  *
3  * COPYRIGHT:       See COPYING in the top level directory
4  * PROJECT:         ReactOS kernel
5  * FILE:            lib/ntdll/rtl/security.c
6  * PURPOSE:         Miscellaneous securitiy related functions
7  * PROGRAMMER:      Eric Kohl
8  * UPDATE HISTORY:
9  *                  21/11/2001 Created
10  */
11
12 #include <ddk/ntddk.h>
13 #include <ntdll/rtl.h>
14
15 #define NDEBUG
16 #include <ntdll/ntdll.h>
17
18
19 /* FUNCTIONS ****************************************************************/
20
21 /*
22  * @implemented
23  */
24 NTSTATUS STDCALL
25 RtlImpersonateSelf(IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
26 {
27   OBJECT_ATTRIBUTES ObjectAttributes;
28   SECURITY_QUALITY_OF_SERVICE SecQos;
29   HANDLE ProcessToken;
30   HANDLE ImpersonationToken;
31   NTSTATUS Status;
32
33   Status = NtOpenProcessToken(NtCurrentProcess(),
34                               TOKEN_DUPLICATE,
35                               &ProcessToken);
36   if (!NT_SUCCESS(Status))
37     return(Status);
38
39   SecQos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
40   SecQos.ImpersonationLevel = ImpersonationLevel;
41   SecQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
42   SecQos.EffectiveOnly = FALSE;
43
44   ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
45   ObjectAttributes.RootDirectory = 0;
46   ObjectAttributes.ObjectName = NULL;
47   ObjectAttributes.Attributes = 0;
48   ObjectAttributes.SecurityDescriptor = NULL;
49   ObjectAttributes.SecurityQualityOfService = &SecQos;
50
51   Status = NtDuplicateToken(ProcessToken,
52                             TOKEN_IMPERSONATE,
53                             &ObjectAttributes,
54                             0,
55                             TokenImpersonation,
56                             &ImpersonationToken);
57   if (!NT_SUCCESS(Status))
58     {
59       NtClose(ProcessToken);
60       return(Status);
61     }
62
63   Status = NtSetInformationThread(NtCurrentThread(),
64                                   ThreadImpersonationToken,
65                                   &ImpersonationToken,
66                                   sizeof(HANDLE));
67   NtClose(ImpersonationToken);
68   NtClose(ProcessToken);
69
70   return(Status);
71 }
72
73
74 /*
75  * @implemented
76  */
77 NTSTATUS STDCALL
78 RtlAdjustPrivilege(IN ULONG Privilege,
79                    IN BOOLEAN Enable,
80                    IN BOOLEAN CurrentThread,
81                    OUT PBOOLEAN Enabled)
82 {
83   TOKEN_PRIVILEGES NewState;
84   TOKEN_PRIVILEGES OldState;
85   ULONG ReturnLength;
86   HANDLE TokenHandle;
87   NTSTATUS Status;
88
89   DPRINT ("RtlAdjustPrivilege() called\n");
90
91   if (CurrentThread)
92     {
93       Status = NtOpenThreadToken (NtCurrentThread (),
94                                   TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
95                                   FALSE,
96                                   &TokenHandle);
97     }
98   else
99     {
100       Status = NtOpenProcessToken (NtCurrentProcess (),
101                                    TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
102                                    &TokenHandle);
103     }
104
105   if (!NT_SUCCESS (Status))
106     {
107       DPRINT1 ("Retrieving token handle failed (Status %lx)\n", Status);
108       return Status;
109     }
110
111   OldState.PrivilegeCount = 1;
112
113   NewState.PrivilegeCount = 1;
114   NewState.Privileges[0].Luid.LowPart = Privilege;
115   NewState.Privileges[0].Luid.HighPart = 0;
116   NewState.Privileges[0].Attributes = (Enable) ? SE_PRIVILEGE_ENABLED : 0;
117
118   Status = NtAdjustPrivilegesToken (TokenHandle,
119                                     FALSE,
120                                     &NewState,
121                                     sizeof(TOKEN_PRIVILEGES),
122                                     &OldState,
123                                     &ReturnLength);
124   NtClose (TokenHandle);
125   if (Status == STATUS_NOT_ALL_ASSIGNED)
126     {
127       DPRINT1 ("Failed to assign all privileges\n");
128       return STATUS_PRIVILEGE_NOT_HELD;
129     }
130   if (!NT_SUCCESS(Status))
131     {
132       DPRINT1 ("NtAdjustPrivilegesToken() failed (Status %lx)\n", Status);
133       return Status;
134     }
135
136   if (OldState.PrivilegeCount == 0)
137     {
138       *Enabled = Enable;
139     }
140   else
141     {
142       *Enabled = (OldState.Privileges[0].Attributes & SE_PRIVILEGE_ENABLED);
143     }
144
145   DPRINT ("RtlAdjustPrivilege() done\n");
146
147   return STATUS_SUCCESS;
148 }
149
150 /* EOF */