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
25 /* GLOBALS *****************************************************************/
27 static const PRIVILEGE_DATA WellKnownPrivileges
[] =
29 {{SE_CREATE_TOKEN_PRIVILEGE
, 0}, SE_CREATE_TOKEN_NAME
},
30 {{SE_ASSIGNPRIMARYTOKEN_PRIVILEGE
, 0}, SE_ASSIGNPRIMARYTOKEN_NAME
},
31 {{SE_LOCK_MEMORY_PRIVILEGE
, 0}, SE_LOCK_MEMORY_NAME
},
32 {{SE_INCREASE_QUOTA_PRIVILEGE
, 0}, SE_INCREASE_QUOTA_NAME
},
33 {{SE_MACHINE_ACCOUNT_PRIVILEGE
, 0}, SE_MACHINE_ACCOUNT_NAME
},
34 {{SE_TCB_PRIVILEGE
, 0}, SE_TCB_NAME
},
35 {{SE_SECURITY_PRIVILEGE
, 0}, SE_SECURITY_NAME
},
36 {{SE_TAKE_OWNERSHIP_PRIVILEGE
, 0}, SE_TAKE_OWNERSHIP_NAME
},
37 {{SE_LOAD_DRIVER_PRIVILEGE
, 0}, SE_LOAD_DRIVER_NAME
},
38 {{SE_SYSTEM_PROFILE_PRIVILEGE
, 0}, SE_SYSTEM_PROFILE_NAME
},
39 {{SE_SYSTEMTIME_PRIVILEGE
, 0}, SE_SYSTEMTIME_NAME
},
40 {{SE_PROF_SINGLE_PROCESS_PRIVILEGE
, 0}, SE_PROF_SINGLE_PROCESS_NAME
},
41 {{SE_INC_BASE_PRIORITY_PRIVILEGE
, 0}, SE_INC_BASE_PRIORITY_NAME
},
42 {{SE_CREATE_PAGEFILE_PRIVILEGE
, 0}, SE_CREATE_PAGEFILE_NAME
},
43 {{SE_CREATE_PERMANENT_PRIVILEGE
, 0}, SE_CREATE_PERMANENT_NAME
},
44 {{SE_BACKUP_PRIVILEGE
, 0}, SE_BACKUP_NAME
},
45 {{SE_RESTORE_PRIVILEGE
, 0}, SE_RESTORE_NAME
},
46 {{SE_SHUTDOWN_PRIVILEGE
, 0}, SE_SHUTDOWN_NAME
},
47 {{SE_DEBUG_PRIVILEGE
, 0}, SE_DEBUG_NAME
},
48 {{SE_AUDIT_PRIVILEGE
, 0}, SE_AUDIT_NAME
},
49 {{SE_SYSTEM_ENVIRONMENT_PRIVILEGE
, 0}, SE_SYSTEM_ENVIRONMENT_NAME
},
50 {{SE_CHANGE_NOTIFY_PRIVILEGE
, 0}, SE_CHANGE_NOTIFY_NAME
},
51 {{SE_REMOTE_SHUTDOWN_PRIVILEGE
, 0}, SE_REMOTE_SHUTDOWN_NAME
},
52 {{SE_UNDOCK_PRIVILEGE
, 0}, SE_UNDOCK_NAME
},
53 {{SE_SYNC_AGENT_PRIVILEGE
, 0}, SE_SYNC_AGENT_NAME
},
54 {{SE_ENABLE_DELEGATION_PRIVILEGE
, 0}, SE_ENABLE_DELEGATION_NAME
},
55 {{SE_MANAGE_VOLUME_PRIVILEGE
, 0}, SE_MANAGE_VOLUME_NAME
},
56 {{SE_IMPERSONATE_PRIVILEGE
, 0}, SE_IMPERSONATE_NAME
},
57 {{SE_CREATE_GLOBAL_PRIVILEGE
, 0}, SE_CREATE_GLOBAL_NAME
}
60 static const RIGHT_DATA WellKnownRights
[] =
62 {SECURITY_ACCESS_INTERACTIVE_LOGON
, SE_INTERACTIVE_LOGON_NAME
},
63 {SECURITY_ACCESS_NETWORK_LOGON
, SE_NETWORK_LOGON_NAME
},
64 {SECURITY_ACCESS_BATCH_LOGON
, SE_BATCH_LOGON_NAME
},
65 {SECURITY_ACCESS_SERVICE_LOGON
, SE_SERVICE_LOGON_NAME
},
66 {SECURITY_ACCESS_DENY_INTERACTIVE_LOGON
, SE_DENY_INTERACTIVE_LOGON_NAME
},
67 {SECURITY_ACCESS_DENY_NETWORK_LOGON
, SE_DENY_NETWORK_LOGON_NAME
},
68 {SECURITY_ACCESS_DENY_BATCH_LOGON
, SE_DENY_BATCH_LOGON_NAME
},
69 {SECURITY_ACCESS_DENY_SERVICE_LOGON
, SE_DENY_SERVICE_LOGON_NAME
},
70 {SECURITY_ACCESS_REMOTE_INTERACTIVE_LOGON
, SE_REMOTE_INTERACTIVE_LOGON_NAME
},
71 {SECURITY_ACCESS_DENY_REMOTE_INTERACTIVE_LOGON
, SE_DENY_REMOTE_INTERACTIVE_LOGON_NAME
}
75 /* FUNCTIONS ***************************************************************/
78 LsarpLookupPrivilegeName(PLUID Value
,
79 PRPC_UNICODE_STRING
*Name
)
81 PRPC_UNICODE_STRING NameBuffer
;
84 if (Value
->HighPart
!= 0 ||
85 (Value
->LowPart
< SE_MIN_WELL_KNOWN_PRIVILEGE
||
86 Value
->LowPart
> SE_MAX_WELL_KNOWN_PRIVILEGE
))
88 return STATUS_NO_SUCH_PRIVILEGE
;
91 for (Priv
= 0; Priv
< ARRAYSIZE(WellKnownPrivileges
); Priv
++)
93 if (Value
->LowPart
== WellKnownPrivileges
[Priv
].Luid
.LowPart
&&
94 Value
->HighPart
== WellKnownPrivileges
[Priv
].Luid
.HighPart
)
96 NameBuffer
= MIDL_user_allocate(sizeof(RPC_UNICODE_STRING
));
97 if (NameBuffer
== NULL
)
98 return STATUS_NO_MEMORY
;
100 NameBuffer
->Length
= wcslen(WellKnownPrivileges
[Priv
].Name
) * sizeof(WCHAR
);
101 NameBuffer
->MaximumLength
= NameBuffer
->Length
+ sizeof(WCHAR
);
103 NameBuffer
->Buffer
= MIDL_user_allocate(NameBuffer
->MaximumLength
);
104 if (NameBuffer
->Buffer
== NULL
)
106 MIDL_user_free(NameBuffer
);
107 return STATUS_NO_MEMORY
;
110 wcscpy(NameBuffer
->Buffer
, WellKnownPrivileges
[Priv
].Name
);
114 return STATUS_SUCCESS
;
118 return STATUS_NO_SUCH_PRIVILEGE
;
122 LsarpLookupPrivilegeDisplayName(PRPC_UNICODE_STRING Name
,
123 USHORT ClientLanguage
,
124 USHORT ClientSystemDefaultLanguage
,
125 PRPC_UNICODE_STRING
*DisplayName
,
126 USHORT
*LanguageReturned
)
128 PRPC_UNICODE_STRING DisplayNameBuffer
;
131 /* For now, description is equal to privilege name */
133 DisplayNameBuffer
= MIDL_user_allocate(sizeof(RPC_UNICODE_STRING
));
134 if (DisplayNameBuffer
== NULL
)
136 return STATUS_NO_MEMORY
;
138 DisplayNameBuffer
->Length
= Name
->Length
;
139 DisplayNameBuffer
->MaximumLength
= Name
->MaximumLength
;
141 DisplayNameBuffer
->Buffer
= MIDL_user_allocate(DisplayNameBuffer
->MaximumLength
);
142 if (DisplayNameBuffer
->Buffer
== NULL
)
144 MIDL_user_free(DisplayNameBuffer
);
145 return STATUS_NO_MEMORY
;
148 wcscpy(DisplayNameBuffer
->Buffer
, Name
->Buffer
);
150 *DisplayName
= DisplayNameBuffer
;
152 return STATUS_SUCCESS
;
157 LsarpLookupPrivilegeValue(
158 IN PRPC_UNICODE_STRING Name
)
162 if (Name
->Length
== 0 || Name
->Buffer
== NULL
)
165 for (Priv
= 0; Priv
< ARRAYSIZE(WellKnownPrivileges
); Priv
++)
167 if (_wcsicmp(Name
->Buffer
, WellKnownPrivileges
[Priv
].Name
) == 0)
168 return (PLUID
)&(WellKnownPrivileges
[Priv
].Luid
);
176 LsarpEnumeratePrivileges(DWORD
*EnumerationContext
,
177 PLSAPR_PRIVILEGE_ENUM_BUFFER EnumerationBuffer
,
178 DWORD PreferedMaximumLength
)
180 PLSAPR_POLICY_PRIVILEGE_DEF Privileges
= NULL
;
183 ULONG RequiredLength
= 0;
185 BOOLEAN MoreEntries
= FALSE
;
186 NTSTATUS Status
= STATUS_SUCCESS
;
188 EnumIndex
= *EnumerationContext
;
190 for (; EnumIndex
< ARRAYSIZE(WellKnownPrivileges
); EnumIndex
++)
192 TRACE("EnumIndex: %lu\n", EnumIndex
);
193 TRACE("Privilege Name: %S\n", WellKnownPrivileges
[EnumIndex
].Name
);
194 TRACE("Name Length: %lu\n", wcslen(WellKnownPrivileges
[EnumIndex
].Name
));
196 if ((RequiredLength
+
197 wcslen(WellKnownPrivileges
[EnumIndex
].Name
) * sizeof(WCHAR
) +
198 sizeof(UNICODE_NULL
) +
199 sizeof(LSAPR_POLICY_PRIVILEGE_DEF
)) > PreferedMaximumLength
)
205 RequiredLength
+= (wcslen(WellKnownPrivileges
[EnumIndex
].Name
) * sizeof(WCHAR
) +
206 sizeof(UNICODE_NULL
) + sizeof(LSAPR_POLICY_PRIVILEGE_DEF
));
210 TRACE("EnumCount: %lu\n", EnumCount
);
211 TRACE("RequiredLength: %lu\n", RequiredLength
);
216 Privileges
= MIDL_user_allocate(EnumCount
* sizeof(LSAPR_POLICY_PRIVILEGE_DEF
));
217 if (Privileges
== NULL
)
219 Status
= STATUS_INSUFFICIENT_RESOURCES
;
223 EnumIndex
= *EnumerationContext
;
225 for (i
= 0; i
< EnumCount
; i
++, EnumIndex
++)
227 Privileges
[i
].LocalValue
= WellKnownPrivileges
[EnumIndex
].Luid
;
229 Privileges
[i
].Name
.Length
= (USHORT
)wcslen(WellKnownPrivileges
[EnumIndex
].Name
) * sizeof(WCHAR
);
230 Privileges
[i
].Name
.MaximumLength
= (USHORT
)Privileges
[i
].Name
.Length
+ sizeof(UNICODE_NULL
);
232 Privileges
[i
].Name
.Buffer
= MIDL_user_allocate(Privileges
[i
].Name
.MaximumLength
);
233 if (Privileges
[i
].Name
.Buffer
== NULL
)
235 Status
= STATUS_INSUFFICIENT_RESOURCES
;
239 memcpy(Privileges
[i
].Name
.Buffer
,
240 WellKnownPrivileges
[EnumIndex
].Name
,
241 Privileges
[i
].Name
.Length
);
245 if (NT_SUCCESS(Status
))
247 EnumerationBuffer
->Entries
= EnumCount
;
248 EnumerationBuffer
->Privileges
= Privileges
;
249 *EnumerationContext
+= EnumCount
;
253 if (Privileges
!= NULL
)
255 for (i
= 0; i
< EnumCount
; i
++)
257 if (Privileges
[i
].Name
.Buffer
!= NULL
)
258 MIDL_user_free(Privileges
[i
].Name
.Buffer
);
261 MIDL_user_free(Privileges
);
265 if ((Status
== STATUS_SUCCESS
) && (MoreEntries
== TRUE
))
266 Status
= STATUS_MORE_ENTRIES
;
273 LsapLookupAccountRightName(ULONG RightValue
,
274 PRPC_UNICODE_STRING
*Name
)
276 PRPC_UNICODE_STRING NameBuffer
;
279 for (i
= 0; i
< ARRAYSIZE(WellKnownRights
); i
++)
281 if (WellKnownRights
[i
].Flag
== RightValue
)
283 NameBuffer
= MIDL_user_allocate(sizeof(RPC_UNICODE_STRING
));
284 if (NameBuffer
== NULL
)
285 return STATUS_NO_MEMORY
;
287 NameBuffer
->Length
= wcslen(WellKnownRights
[i
].Name
) * sizeof(WCHAR
);
288 NameBuffer
->MaximumLength
= NameBuffer
->Length
+ sizeof(WCHAR
);
290 NameBuffer
->Buffer
= MIDL_user_allocate(NameBuffer
->MaximumLength
);
291 if (NameBuffer
->Buffer
== NULL
)
293 MIDL_user_free(NameBuffer
);
294 return STATUS_INSUFFICIENT_RESOURCES
;
297 wcscpy(NameBuffer
->Buffer
, WellKnownRights
[i
].Name
);
301 return STATUS_SUCCESS
;
305 return STATUS_NO_SUCH_PRIVILEGE
;
310 LsapLookupAccountRightValue(
311 IN PRPC_UNICODE_STRING Name
)
315 if (Name
->Length
== 0 || Name
->Buffer
== NULL
)
318 for (i
= 0; i
< ARRAYSIZE(WellKnownRights
); i
++)
320 if (_wcsicmp(Name
->Buffer
, WellKnownRights
[i
].Name
) == 0)
321 return WellKnownRights
[i
].Flag
;