2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: Local Security Authority (LSA) Server
4 * FILE: reactos/dll/win32/lsasrv/privileges.c
5 * PURPOSE: Privilege lookup functions
7 * PROGRAMMERS: Eric Kohl <eric.kohl@reactos.org>
11 #include "resources.h"
27 /* GLOBALS *****************************************************************/
29 static const PRIVILEGE_DATA WellKnownPrivileges
[] =
31 {{SE_CREATE_TOKEN_PRIVILEGE
, 0}, SE_CREATE_TOKEN_NAME
, IDS_CREATE_TOKEN_PRIVILEGE
},
32 {{SE_ASSIGNPRIMARYTOKEN_PRIVILEGE
, 0}, SE_ASSIGNPRIMARYTOKEN_NAME
, IDS_ASSIGNPRIMARYTOKEN_PRIVILEGE
},
33 {{SE_LOCK_MEMORY_PRIVILEGE
, 0}, SE_LOCK_MEMORY_NAME
, IDS_LOCK_MEMORY_PRIVILEGE
},
34 {{SE_INCREASE_QUOTA_PRIVILEGE
, 0}, SE_INCREASE_QUOTA_NAME
, IDS_INCREASE_QUOTA_PRIVILEGE
},
35 {{SE_MACHINE_ACCOUNT_PRIVILEGE
, 0}, SE_MACHINE_ACCOUNT_NAME
, IDS_MACHINE_ACCOUNT_PRIVILEGE
},
36 {{SE_TCB_PRIVILEGE
, 0}, SE_TCB_NAME
, IDS_TCB_PRIVILEGE
},
37 {{SE_SECURITY_PRIVILEGE
, 0}, SE_SECURITY_NAME
, IDS_SECURITY_PRIVILEGE
},
38 {{SE_TAKE_OWNERSHIP_PRIVILEGE
, 0}, SE_TAKE_OWNERSHIP_NAME
, IDS_TAKE_OWNERSHIP_PRIVILEGE
},
39 {{SE_LOAD_DRIVER_PRIVILEGE
, 0}, SE_LOAD_DRIVER_NAME
, IDS_LOAD_DRIVER_PRIVILEGE
},
40 {{SE_SYSTEM_PROFILE_PRIVILEGE
, 0}, SE_SYSTEM_PROFILE_NAME
, IDS_SYSTEM_PROFILE_PRIVILEGE
},
41 {{SE_SYSTEMTIME_PRIVILEGE
, 0}, SE_SYSTEMTIME_NAME
, IDS_SYSTEMTIME_PRIVILEGE
},
42 {{SE_PROF_SINGLE_PROCESS_PRIVILEGE
, 0}, SE_PROF_SINGLE_PROCESS_NAME
, IDS_PROF_SINGLE_PROCESS_PRIVILEGE
},
43 {{SE_INC_BASE_PRIORITY_PRIVILEGE
, 0}, SE_INC_BASE_PRIORITY_NAME
, IDS_INC_BASE_PRIORITY_PRIVILEGE
},
44 {{SE_CREATE_PAGEFILE_PRIVILEGE
, 0}, SE_CREATE_PAGEFILE_NAME
, IDS_CREATE_PAGEFILE_PRIVILEGE
},
45 {{SE_CREATE_PERMANENT_PRIVILEGE
, 0}, SE_CREATE_PERMANENT_NAME
, IDS_CREATE_PERMANENT_PRIVILEGE
},
46 {{SE_BACKUP_PRIVILEGE
, 0}, SE_BACKUP_NAME
, IDS_BACKUP_PRIVILEGE
},
47 {{SE_RESTORE_PRIVILEGE
, 0}, SE_RESTORE_NAME
, IDS_RESTORE_PRIVILEGE
},
48 {{SE_SHUTDOWN_PRIVILEGE
, 0}, SE_SHUTDOWN_NAME
, IDS_SHUTDOWN_PRIVILEGE
},
49 {{SE_DEBUG_PRIVILEGE
, 0}, SE_DEBUG_NAME
, IDS_DEBUG_PRIVILEGE
},
50 {{SE_AUDIT_PRIVILEGE
, 0}, SE_AUDIT_NAME
, IDS_AUDIT_PRIVILEGE
},
51 {{SE_SYSTEM_ENVIRONMENT_PRIVILEGE
, 0}, SE_SYSTEM_ENVIRONMENT_NAME
, IDS_SYSTEM_ENVIRONMENT_PRIVILEGE
},
52 {{SE_CHANGE_NOTIFY_PRIVILEGE
, 0}, SE_CHANGE_NOTIFY_NAME
, IDS_CHANGE_NOTIFY_PRIVILEGE
},
53 {{SE_REMOTE_SHUTDOWN_PRIVILEGE
, 0}, SE_REMOTE_SHUTDOWN_NAME
, IDS_REMOTE_SHUTDOWN_PRIVILEGE
},
54 {{SE_UNDOCK_PRIVILEGE
, 0}, SE_UNDOCK_NAME
, IDS_UNDOCK_PRIVILEGE
},
55 {{SE_SYNC_AGENT_PRIVILEGE
, 0}, SE_SYNC_AGENT_NAME
, IDS_SYNC_AGENT_PRIVILEGE
},
56 {{SE_ENABLE_DELEGATION_PRIVILEGE
, 0}, SE_ENABLE_DELEGATION_NAME
, IDS_ENABLE_DELEGATION_PRIVILEGE
},
57 {{SE_MANAGE_VOLUME_PRIVILEGE
, 0}, SE_MANAGE_VOLUME_NAME
, IDS_MANAGE_VOLUME_PRIVILEGE
},
58 {{SE_IMPERSONATE_PRIVILEGE
, 0}, SE_IMPERSONATE_NAME
, IDS_IMPERSONATE_PRIVILEGE
},
59 {{SE_CREATE_GLOBAL_PRIVILEGE
, 0}, SE_CREATE_GLOBAL_NAME
, IDS_CREATE_GLOBAL_PRIVILEGE
}
62 static const RIGHT_DATA WellKnownRights
[] =
64 {SECURITY_ACCESS_INTERACTIVE_LOGON
, SE_INTERACTIVE_LOGON_NAME
},
65 {SECURITY_ACCESS_NETWORK_LOGON
, SE_NETWORK_LOGON_NAME
},
66 {SECURITY_ACCESS_BATCH_LOGON
, SE_BATCH_LOGON_NAME
},
67 {SECURITY_ACCESS_SERVICE_LOGON
, SE_SERVICE_LOGON_NAME
},
68 {SECURITY_ACCESS_DENY_INTERACTIVE_LOGON
, SE_DENY_INTERACTIVE_LOGON_NAME
},
69 {SECURITY_ACCESS_DENY_NETWORK_LOGON
, SE_DENY_NETWORK_LOGON_NAME
},
70 {SECURITY_ACCESS_DENY_BATCH_LOGON
, SE_DENY_BATCH_LOGON_NAME
},
71 {SECURITY_ACCESS_DENY_SERVICE_LOGON
, SE_DENY_SERVICE_LOGON_NAME
},
72 {SECURITY_ACCESS_REMOTE_INTERACTIVE_LOGON
, SE_REMOTE_INTERACTIVE_LOGON_NAME
},
73 {SECURITY_ACCESS_DENY_REMOTE_INTERACTIVE_LOGON
, SE_DENY_REMOTE_INTERACTIVE_LOGON_NAME
}
77 /* FUNCTIONS ***************************************************************/
80 LsarpLookupPrivilegeName(PLUID Value
,
81 PRPC_UNICODE_STRING
*Name
)
83 PRPC_UNICODE_STRING NameBuffer
;
86 if (Value
->HighPart
!= 0 ||
87 (Value
->LowPart
< SE_MIN_WELL_KNOWN_PRIVILEGE
||
88 Value
->LowPart
> SE_MAX_WELL_KNOWN_PRIVILEGE
))
90 return STATUS_NO_SUCH_PRIVILEGE
;
93 for (Priv
= 0; Priv
< ARRAYSIZE(WellKnownPrivileges
); Priv
++)
95 if (Value
->LowPart
== WellKnownPrivileges
[Priv
].Luid
.LowPart
&&
96 Value
->HighPart
== WellKnownPrivileges
[Priv
].Luid
.HighPart
)
98 NameBuffer
= MIDL_user_allocate(sizeof(RPC_UNICODE_STRING
));
99 if (NameBuffer
== NULL
)
100 return STATUS_NO_MEMORY
;
102 NameBuffer
->Length
= wcslen(WellKnownPrivileges
[Priv
].Name
) * sizeof(WCHAR
);
103 NameBuffer
->MaximumLength
= NameBuffer
->Length
+ sizeof(WCHAR
);
105 NameBuffer
->Buffer
= MIDL_user_allocate(NameBuffer
->MaximumLength
);
106 if (NameBuffer
->Buffer
== NULL
)
108 MIDL_user_free(NameBuffer
);
109 return STATUS_NO_MEMORY
;
112 wcscpy(NameBuffer
->Buffer
, WellKnownPrivileges
[Priv
].Name
);
116 return STATUS_SUCCESS
;
120 return STATUS_NO_SUCH_PRIVILEGE
;
125 LsarpLookupPrivilegeDisplayName(PRPC_UNICODE_STRING Name
,
126 USHORT ClientLanguage
,
127 USHORT ClientSystemDefaultLanguage
,
128 PRPC_UNICODE_STRING
*DisplayName
,
129 USHORT
*LanguageReturned
)
131 PRPC_UNICODE_STRING DisplayNameBuffer
;
136 TRACE("LsarpLookupPrivilegeDisplayName(%p 0x%04hu 0x%04hu %p %p)",
137 Name
, ClientLanguage
, ClientSystemDefaultLanguage
, DisplayName
, LanguageReturned
);
139 if (Name
->Length
== 0 || Name
->Buffer
== NULL
)
140 return STATUS_INVALID_PARAMETER
;
142 hInstance
= GetModuleHandleW(L
"lsasrv.dll");
144 for (Index
= 0; Index
< ARRAYSIZE(WellKnownPrivileges
); Index
++)
146 if (_wcsicmp(Name
->Buffer
, WellKnownPrivileges
[Index
].Name
) == 0)
148 TRACE("Index: %u\n", Index
);
149 nLength
= LsapGetResourceStringLengthEx(hInstance
,
150 IDS_CREATE_TOKEN_PRIVILEGE
+ Index
,
154 DisplayNameBuffer
= MIDL_user_allocate(sizeof(RPC_UNICODE_STRING
));
155 if (DisplayNameBuffer
== NULL
)
156 return STATUS_NO_MEMORY
;
158 DisplayNameBuffer
->Length
= nLength
* sizeof(WCHAR
);
159 DisplayNameBuffer
->MaximumLength
= DisplayNameBuffer
->Length
+ sizeof(WCHAR
);
161 DisplayNameBuffer
->Buffer
= MIDL_user_allocate(DisplayNameBuffer
->MaximumLength
);
162 if (DisplayNameBuffer
->Buffer
== NULL
)
164 MIDL_user_free(DisplayNameBuffer
);
165 return STATUS_NO_MEMORY
;
168 LsapLoadStringEx(hInstance
,
169 IDS_CREATE_TOKEN_PRIVILEGE
+ Index
,
171 DisplayNameBuffer
->Buffer
,
174 *DisplayName
= DisplayNameBuffer
;
175 *LanguageReturned
= ClientLanguage
;
179 nLength
= LsapGetResourceStringLengthEx(hInstance
,
180 IDS_CREATE_TOKEN_PRIVILEGE
+ Index
,
181 ClientSystemDefaultLanguage
);
184 DisplayNameBuffer
= MIDL_user_allocate(sizeof(RPC_UNICODE_STRING
));
185 if (DisplayNameBuffer
== NULL
)
186 return STATUS_NO_MEMORY
;
188 DisplayNameBuffer
->Length
= nLength
* sizeof(WCHAR
);
189 DisplayNameBuffer
->MaximumLength
= DisplayNameBuffer
->Length
+ sizeof(WCHAR
);
191 DisplayNameBuffer
->Buffer
= MIDL_user_allocate(DisplayNameBuffer
->MaximumLength
);
192 if (DisplayNameBuffer
->Buffer
== NULL
)
194 MIDL_user_free(DisplayNameBuffer
);
195 return STATUS_NO_MEMORY
;
198 LsapLoadStringEx(hInstance
,
199 IDS_CREATE_TOKEN_PRIVILEGE
+ Index
,
200 ClientSystemDefaultLanguage
,
201 DisplayNameBuffer
->Buffer
,
204 *DisplayName
= DisplayNameBuffer
;
205 *LanguageReturned
= ClientSystemDefaultLanguage
;
209 return STATUS_INVALID_PARAMETER
;
211 nLength
= LsapGetResourceStringLengthEx(hInstance
,
212 IDS_CREATE_TOKEN_PRIVILEGE
+ Index
,
218 return STATUS_SUCCESS
;
222 return STATUS_NO_SUCH_PRIVILEGE
;
227 LsarpLookupPrivilegeValue(
228 IN PRPC_UNICODE_STRING Name
)
232 if (Name
->Length
== 0 || Name
->Buffer
== NULL
)
235 for (Priv
= 0; Priv
< ARRAYSIZE(WellKnownPrivileges
); Priv
++)
237 if (_wcsicmp(Name
->Buffer
, WellKnownPrivileges
[Priv
].Name
) == 0)
238 return (PLUID
)&(WellKnownPrivileges
[Priv
].Luid
);
246 LsarpEnumeratePrivileges(DWORD
*EnumerationContext
,
247 PLSAPR_PRIVILEGE_ENUM_BUFFER EnumerationBuffer
,
248 DWORD PreferedMaximumLength
)
250 PLSAPR_POLICY_PRIVILEGE_DEF Privileges
= NULL
;
253 ULONG RequiredLength
= 0;
255 BOOLEAN MoreEntries
= FALSE
;
256 NTSTATUS Status
= STATUS_SUCCESS
;
258 EnumIndex
= *EnumerationContext
;
260 for (; EnumIndex
< ARRAYSIZE(WellKnownPrivileges
); EnumIndex
++)
262 TRACE("EnumIndex: %lu\n", EnumIndex
);
263 TRACE("Privilege Name: %S\n", WellKnownPrivileges
[EnumIndex
].Name
);
264 TRACE("Name Length: %lu\n", wcslen(WellKnownPrivileges
[EnumIndex
].Name
));
266 if ((RequiredLength
+
267 wcslen(WellKnownPrivileges
[EnumIndex
].Name
) * sizeof(WCHAR
) +
268 sizeof(UNICODE_NULL
) +
269 sizeof(LSAPR_POLICY_PRIVILEGE_DEF
)) > PreferedMaximumLength
)
275 RequiredLength
+= (wcslen(WellKnownPrivileges
[EnumIndex
].Name
) * sizeof(WCHAR
) +
276 sizeof(UNICODE_NULL
) + sizeof(LSAPR_POLICY_PRIVILEGE_DEF
));
280 TRACE("EnumCount: %lu\n", EnumCount
);
281 TRACE("RequiredLength: %lu\n", RequiredLength
);
286 Privileges
= MIDL_user_allocate(EnumCount
* sizeof(LSAPR_POLICY_PRIVILEGE_DEF
));
287 if (Privileges
== NULL
)
289 Status
= STATUS_INSUFFICIENT_RESOURCES
;
293 EnumIndex
= *EnumerationContext
;
295 for (i
= 0; i
< EnumCount
; i
++, EnumIndex
++)
297 Privileges
[i
].LocalValue
= WellKnownPrivileges
[EnumIndex
].Luid
;
299 Privileges
[i
].Name
.Length
= (USHORT
)wcslen(WellKnownPrivileges
[EnumIndex
].Name
) * sizeof(WCHAR
);
300 Privileges
[i
].Name
.MaximumLength
= (USHORT
)Privileges
[i
].Name
.Length
+ sizeof(UNICODE_NULL
);
302 Privileges
[i
].Name
.Buffer
= MIDL_user_allocate(Privileges
[i
].Name
.MaximumLength
);
303 if (Privileges
[i
].Name
.Buffer
== NULL
)
305 Status
= STATUS_INSUFFICIENT_RESOURCES
;
309 memcpy(Privileges
[i
].Name
.Buffer
,
310 WellKnownPrivileges
[EnumIndex
].Name
,
311 Privileges
[i
].Name
.Length
);
315 if (NT_SUCCESS(Status
))
317 EnumerationBuffer
->Entries
= EnumCount
;
318 EnumerationBuffer
->Privileges
= Privileges
;
319 *EnumerationContext
+= EnumCount
;
323 if (Privileges
!= NULL
)
325 for (i
= 0; i
< EnumCount
; i
++)
327 if (Privileges
[i
].Name
.Buffer
!= NULL
)
328 MIDL_user_free(Privileges
[i
].Name
.Buffer
);
331 MIDL_user_free(Privileges
);
335 if ((Status
== STATUS_SUCCESS
) && (MoreEntries
== TRUE
))
336 Status
= STATUS_MORE_ENTRIES
;
343 LsapLookupAccountRightName(ULONG RightValue
,
344 PRPC_UNICODE_STRING
*Name
)
346 PRPC_UNICODE_STRING NameBuffer
;
349 for (i
= 0; i
< ARRAYSIZE(WellKnownRights
); i
++)
351 if (WellKnownRights
[i
].Flag
== RightValue
)
353 NameBuffer
= MIDL_user_allocate(sizeof(RPC_UNICODE_STRING
));
354 if (NameBuffer
== NULL
)
355 return STATUS_NO_MEMORY
;
357 NameBuffer
->Length
= wcslen(WellKnownRights
[i
].Name
) * sizeof(WCHAR
);
358 NameBuffer
->MaximumLength
= NameBuffer
->Length
+ sizeof(WCHAR
);
360 NameBuffer
->Buffer
= MIDL_user_allocate(NameBuffer
->MaximumLength
);
361 if (NameBuffer
->Buffer
== NULL
)
363 MIDL_user_free(NameBuffer
);
364 return STATUS_INSUFFICIENT_RESOURCES
;
367 wcscpy(NameBuffer
->Buffer
, WellKnownRights
[i
].Name
);
371 return STATUS_SUCCESS
;
375 return STATUS_NO_SUCH_PRIVILEGE
;
380 LsapLookupAccountRightValue(
381 IN PRPC_UNICODE_STRING Name
)
385 if (Name
->Length
== 0 || Name
->Buffer
== NULL
)
388 for (i
= 0; i
< ARRAYSIZE(WellKnownRights
); i
++)
390 if (_wcsicmp(Name
->Buffer
, WellKnownRights
[i
].Name
) == 0)
391 return WellKnownRights
[i
].Flag
;