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
12 WINE_DEFAULT_DEBUG_CHANNEL(lsasrv
);
28 /* GLOBALS *****************************************************************/
30 static const PRIVILEGE_DATA WellKnownPrivileges
[] =
32 {{SE_CREATE_TOKEN_PRIVILEGE
, 0}, SE_CREATE_TOKEN_NAME
},
33 {{SE_ASSIGNPRIMARYTOKEN_PRIVILEGE
, 0}, SE_ASSIGNPRIMARYTOKEN_NAME
},
34 {{SE_LOCK_MEMORY_PRIVILEGE
, 0}, SE_LOCK_MEMORY_NAME
},
35 {{SE_INCREASE_QUOTA_PRIVILEGE
, 0}, SE_INCREASE_QUOTA_NAME
},
36 {{SE_MACHINE_ACCOUNT_PRIVILEGE
, 0}, SE_MACHINE_ACCOUNT_NAME
},
37 {{SE_TCB_PRIVILEGE
, 0}, SE_TCB_NAME
},
38 {{SE_SECURITY_PRIVILEGE
, 0}, SE_SECURITY_NAME
},
39 {{SE_TAKE_OWNERSHIP_PRIVILEGE
, 0}, SE_TAKE_OWNERSHIP_NAME
},
40 {{SE_LOAD_DRIVER_PRIVILEGE
, 0}, SE_LOAD_DRIVER_NAME
},
41 {{SE_SYSTEM_PROFILE_PRIVILEGE
, 0}, SE_SYSTEM_PROFILE_NAME
},
42 {{SE_SYSTEMTIME_PRIVILEGE
, 0}, SE_SYSTEMTIME_NAME
},
43 {{SE_PROF_SINGLE_PROCESS_PRIVILEGE
, 0}, SE_PROF_SINGLE_PROCESS_NAME
},
44 {{SE_INC_BASE_PRIORITY_PRIVILEGE
, 0}, SE_INC_BASE_PRIORITY_NAME
},
45 {{SE_CREATE_PAGEFILE_PRIVILEGE
, 0}, SE_CREATE_PAGEFILE_NAME
},
46 {{SE_CREATE_PERMANENT_PRIVILEGE
, 0}, SE_CREATE_PERMANENT_NAME
},
47 {{SE_BACKUP_PRIVILEGE
, 0}, SE_BACKUP_NAME
},
48 {{SE_RESTORE_PRIVILEGE
, 0}, SE_RESTORE_NAME
},
49 {{SE_SHUTDOWN_PRIVILEGE
, 0}, SE_SHUTDOWN_NAME
},
50 {{SE_DEBUG_PRIVILEGE
, 0}, SE_DEBUG_NAME
},
51 {{SE_AUDIT_PRIVILEGE
, 0}, SE_AUDIT_NAME
},
52 {{SE_SYSTEM_ENVIRONMENT_PRIVILEGE
, 0}, SE_SYSTEM_ENVIRONMENT_NAME
},
53 {{SE_CHANGE_NOTIFY_PRIVILEGE
, 0}, SE_CHANGE_NOTIFY_NAME
},
54 {{SE_REMOTE_SHUTDOWN_PRIVILEGE
, 0}, SE_REMOTE_SHUTDOWN_NAME
},
55 {{SE_UNDOCK_PRIVILEGE
, 0}, SE_UNDOCK_NAME
},
56 {{SE_SYNC_AGENT_PRIVILEGE
, 0}, SE_SYNC_AGENT_NAME
},
57 {{SE_ENABLE_DELEGATION_PRIVILEGE
, 0}, SE_ENABLE_DELEGATION_NAME
},
58 {{SE_MANAGE_VOLUME_PRIVILEGE
, 0}, SE_MANAGE_VOLUME_NAME
},
59 {{SE_IMPERSONATE_PRIVILEGE
, 0}, SE_IMPERSONATE_NAME
},
60 {{SE_CREATE_GLOBAL_PRIVILEGE
, 0}, SE_CREATE_GLOBAL_NAME
}
63 static const RIGHT_DATA WellKnownRights
[] =
65 {SECURITY_ACCESS_INTERACTIVE_LOGON
, SE_INTERACTIVE_LOGON_NAME
},
66 {SECURITY_ACCESS_NETWORK_LOGON
, SE_NETWORK_LOGON_NAME
},
67 {SECURITY_ACCESS_BATCH_LOGON
, SE_BATCH_LOGON_NAME
},
68 {SECURITY_ACCESS_SERVICE_LOGON
, SE_SERVICE_LOGON_NAME
},
69 {SECURITY_ACCESS_DENY_INTERACTIVE_LOGON
, SE_DENY_INTERACTIVE_LOGON_NAME
},
70 {SECURITY_ACCESS_DENY_NETWORK_LOGON
, SE_DENY_NETWORK_LOGON_NAME
},
71 {SECURITY_ACCESS_DENY_BATCH_LOGON
, SE_DENY_BATCH_LOGON_NAME
},
72 {SECURITY_ACCESS_DENY_SERVICE_LOGON
, SE_DENY_SERVICE_LOGON_NAME
},
73 {SECURITY_ACCESS_REMOTE_INTERACTIVE_LOGON
, SE_REMOTE_INTERACTIVE_LOGON_NAME
},
74 {SECURITY_ACCESS_DENY_REMOTE_INTERACTIVE_LOGON
, SE_DENY_REMOTE_INTERACTIVE_LOGON_NAME
}
78 /* FUNCTIONS ***************************************************************/
81 LsarpLookupPrivilegeName(PLUID Value
,
82 PRPC_UNICODE_STRING
*Name
)
84 PRPC_UNICODE_STRING NameBuffer
;
87 if (Value
->HighPart
!= 0 ||
88 (Value
->LowPart
< SE_MIN_WELL_KNOWN_PRIVILEGE
||
89 Value
->LowPart
> SE_MAX_WELL_KNOWN_PRIVILEGE
))
91 return STATUS_NO_SUCH_PRIVILEGE
;
94 for (Priv
= 0; Priv
< sizeof(WellKnownPrivileges
) / sizeof(WellKnownPrivileges
[0]); Priv
++)
96 if (Value
->LowPart
== WellKnownPrivileges
[Priv
].Luid
.LowPart
&&
97 Value
->HighPart
== WellKnownPrivileges
[Priv
].Luid
.HighPart
)
99 NameBuffer
= MIDL_user_allocate(sizeof(RPC_UNICODE_STRING
));
100 if (NameBuffer
== NULL
)
101 return STATUS_NO_MEMORY
;
103 NameBuffer
->Length
= wcslen(WellKnownPrivileges
[Priv
].Name
) * sizeof(WCHAR
);
104 NameBuffer
->MaximumLength
= NameBuffer
->Length
+ sizeof(WCHAR
);
106 NameBuffer
->Buffer
= MIDL_user_allocate(NameBuffer
->MaximumLength
);
107 if (NameBuffer
== NULL
)
109 MIDL_user_free(NameBuffer
);
110 return STATUS_NO_MEMORY
;
113 wcscpy(NameBuffer
->Buffer
, WellKnownPrivileges
[Priv
].Name
);
117 return STATUS_SUCCESS
;
121 return STATUS_NO_SUCH_PRIVILEGE
;
126 LsarpLookupPrivilegeValue(PRPC_UNICODE_STRING Name
,
131 if (Name
->Length
== 0 || Name
->Buffer
== NULL
)
132 return STATUS_NO_SUCH_PRIVILEGE
;
134 for (Priv
= 0; Priv
< sizeof(WellKnownPrivileges
) / sizeof(WellKnownPrivileges
[0]); Priv
++)
136 if (_wcsicmp(Name
->Buffer
, WellKnownPrivileges
[Priv
].Name
) == 0)
138 *Value
= WellKnownPrivileges
[Priv
].Luid
;
139 return STATUS_SUCCESS
;
143 return STATUS_NO_SUCH_PRIVILEGE
;
148 LsarpEnumeratePrivileges(DWORD
*EnumerationContext
,
149 PLSAPR_PRIVILEGE_ENUM_BUFFER EnumerationBuffer
,
150 DWORD PreferedMaximumLength
)
152 PLSAPR_POLICY_PRIVILEGE_DEF Privileges
= NULL
;
155 ULONG RequiredLength
= 0;
157 BOOLEAN MoreEntries
= FALSE
;
158 NTSTATUS Status
= STATUS_SUCCESS
;
160 EnumIndex
= *EnumerationContext
;
162 for (; EnumIndex
< sizeof(WellKnownPrivileges
) / sizeof(WellKnownPrivileges
[0]); EnumIndex
++)
164 TRACE("EnumIndex: %lu\n", EnumIndex
);
165 TRACE("Privilege Name: %S\n", WellKnownPrivileges
[EnumIndex
].Name
);
166 TRACE("Name Length: %lu\n", wcslen(WellKnownPrivileges
[EnumIndex
].Name
));
168 if ((RequiredLength
+
169 wcslen(WellKnownPrivileges
[EnumIndex
].Name
) * sizeof(WCHAR
) +
170 sizeof(UNICODE_NULL
) +
171 sizeof(LSAPR_POLICY_PRIVILEGE_DEF
)) > PreferedMaximumLength
)
177 RequiredLength
+= (wcslen(WellKnownPrivileges
[EnumIndex
].Name
) * sizeof(WCHAR
) +
178 sizeof(UNICODE_NULL
) + sizeof(LSAPR_POLICY_PRIVILEGE_DEF
));
182 TRACE("EnumCount: %lu\n", EnumCount
);
183 TRACE("RequiredLength: %lu\n", RequiredLength
);
188 Privileges
= MIDL_user_allocate(EnumCount
* sizeof(LSAPR_POLICY_PRIVILEGE_DEF
));
189 if (Privileges
== NULL
)
191 Status
= STATUS_INSUFFICIENT_RESOURCES
;
195 EnumIndex
= *EnumerationContext
;
197 for (i
= 0; i
< EnumCount
; i
++, EnumIndex
++)
199 Privileges
[i
].LocalValue
= WellKnownPrivileges
[EnumIndex
].Luid
;
201 Privileges
[i
].Name
.Length
= (USHORT
)wcslen(WellKnownPrivileges
[EnumIndex
].Name
) * sizeof(WCHAR
);
202 Privileges
[i
].Name
.MaximumLength
= (USHORT
)Privileges
[i
].Name
.Length
+ sizeof(UNICODE_NULL
);
204 Privileges
[i
].Name
.Buffer
= MIDL_user_allocate(Privileges
[i
].Name
.MaximumLength
);
205 if (Privileges
[i
].Name
.Buffer
== NULL
)
207 Status
= STATUS_INSUFFICIENT_RESOURCES
;
211 memcpy(Privileges
[i
].Name
.Buffer
,
212 WellKnownPrivileges
[EnumIndex
].Name
,
213 Privileges
[i
].Name
.Length
);
217 if (NT_SUCCESS(Status
))
219 EnumerationBuffer
->Entries
= EnumCount
;
220 EnumerationBuffer
->Privileges
= Privileges
;
221 *EnumerationContext
+= EnumCount
;
225 if (Privileges
!= NULL
)
227 for (i
= 0; i
< EnumCount
; i
++)
229 if (Privileges
[i
].Name
.Buffer
!= NULL
)
230 MIDL_user_free(Privileges
[i
].Name
.Buffer
);
233 MIDL_user_free(Privileges
);
237 if ((Status
== STATUS_SUCCESS
) && (MoreEntries
== TRUE
))
238 Status
= STATUS_MORE_ENTRIES
;
245 LsapLookupAccountRightName(ULONG RightValue
,
246 PRPC_UNICODE_STRING
*Name
)
248 PRPC_UNICODE_STRING NameBuffer
;
251 for (i
= 0; i
< sizeof(WellKnownRights
) / sizeof(WellKnownRights
[0]); i
++)
253 if (WellKnownRights
[i
].Flag
== RightValue
)
255 NameBuffer
= MIDL_user_allocate(sizeof(RPC_UNICODE_STRING
));
256 if (NameBuffer
== NULL
)
257 return STATUS_NO_MEMORY
;
259 NameBuffer
->Length
= wcslen(WellKnownRights
[i
].Name
) * sizeof(WCHAR
);
260 NameBuffer
->MaximumLength
= NameBuffer
->Length
+ sizeof(WCHAR
);
262 NameBuffer
->Buffer
= MIDL_user_allocate(NameBuffer
->MaximumLength
);
263 if (NameBuffer
== NULL
)
265 MIDL_user_free(NameBuffer
);
266 return STATUS_INSUFFICIENT_RESOURCES
;
269 wcscpy(NameBuffer
->Buffer
, WellKnownRights
[i
].Name
);
273 return STATUS_SUCCESS
;
277 return STATUS_NO_SUCH_PRIVILEGE
;