1 use crate::string::UTF8Const;
2 use winapi::shared::basetsd::ULONG64;
3 use winapi::shared::minwindef::DWORD;
4 use winapi::shared::ntdef::{
5     BOOLEAN, HANDLE, LARGE_INTEGER, NTSTATUS, OEM_STRING, PLARGE_INTEGER, POBJECT_ATTRIBUTES,
6     PUCHAR, PULONG, PUNICODE_STRING, PVOID, PWSTR, ULONG, UNICODE_STRING, USHORT,
7 };
8 use winapi::um::ntsecapi::PDOMAIN_PASSWORD_INFORMATION;
9 use winapi::um::subauth::LOGON_HOURS;
10 use winapi::um::winnt::{
11     ACCESS_MASK, PSECURITY_DESCRIPTOR, PSID, PSID_NAME_USE, SECURITY_INFORMATION, SID_NAME_USE,
12     STANDARD_RIGHTS_EXECUTE, STANDARD_RIGHTS_READ, STANDARD_RIGHTS_REQUIRED, STANDARD_RIGHTS_WRITE,
13 };
14 pub const SAM_MAXIMUM_LOOKUP_COUNT: u32 = 1000;
15 pub const SAM_MAXIMUM_LOOKUP_LENGTH: u32 = 32000;
16 pub const SAM_MAX_PASSWORD_LENGTH: u32 = 256;
17 pub const SAM_PASSWORD_ENCRYPTION_SALT_LEN: u32 = 16;
18 pub type PSAM_HANDLE = *mut PVOID;
19 pub type SAM_HANDLE = PVOID;
20 pub type SAM_ENUMERATE_HANDLE = ULONG;
21 pub type PSAM_ENUMERATE_HANDLE = *mut ULONG;
22 STRUCT!{struct SAM_RID_ENUMERATION {
23     RelativeId: ULONG,
24     Name: UNICODE_STRING,
25 }}
26 pub type PSAM_RID_ENUMERATION = *mut SAM_RID_ENUMERATION;
27 STRUCT!{struct SAM_SID_ENUMERATION {
28     Sid: PSID,
29     Name: UNICODE_STRING,
30 }}
31 pub type PSAM_SID_ENUMERATION = *mut SAM_SID_ENUMERATION;
32 STRUCT!{struct SAM_BYTE_ARRAY {
33     Size: ULONG,
34     Data: PUCHAR,
35 }}
36 pub type PSAM_BYTE_ARRAY = *mut SAM_BYTE_ARRAY;
37 STRUCT!{struct SAM_BYTE_ARRAY_32K {
38     Size: ULONG,
39     Data: PUCHAR,
40 }}
41 pub type PSAM_BYTE_ARRAY_32K = *mut SAM_BYTE_ARRAY_32K;
42 pub type PSAM_SHELL_OBJECT_PROPERTIES = *mut SAM_BYTE_ARRAY_32K;
43 pub type SAM_SHELL_OBJECT_PROPERTIES = SAM_BYTE_ARRAY_32K;
44 EXTERN!{extern "system" {
45     fn SamFreeMemory(
46         Buffer: PVOID,
47     ) -> NTSTATUS;
48     fn SamCloseHandle(
49         SamHandle: SAM_HANDLE,
50     ) -> NTSTATUS;
51     fn SamSetSecurityObject(
52         ObjectHandle: SAM_HANDLE,
53         SecurityInformation: SECURITY_INFORMATION,
54         SecurityDescriptor: PSECURITY_DESCRIPTOR,
55     ) -> NTSTATUS;
56     fn SamQuerySecurityObject(
57         ObjectHandle: SAM_HANDLE,
58         SecurityInformation: SECURITY_INFORMATION,
59         SecurityDescriptor: *mut PSECURITY_DESCRIPTOR,
60     ) -> NTSTATUS;
61     fn SamRidToSid(
62         ObjectHandle: SAM_HANDLE,
63         Rid: ULONG,
64         Sid: *mut PSID,
65     ) -> NTSTATUS;
66 }}
67 pub const SAM_SERVER_CONNECT: ACCESS_MASK = 0x0001;
68 pub const SAM_SERVER_SHUTDOWN: ACCESS_MASK = 0x0002;
69 pub const SAM_SERVER_INITIALIZE: ACCESS_MASK = 0x0004;
70 pub const SAM_SERVER_CREATE_DOMAIN: ACCESS_MASK = 0x0008;
71 pub const SAM_SERVER_ENUMERATE_DOMAINS: ACCESS_MASK = 0x0010;
72 pub const SAM_SERVER_LOOKUP_DOMAIN: ACCESS_MASK = 0x0020;
73 pub const SAM_SERVER_ALL_ACCESS: ACCESS_MASK = STANDARD_RIGHTS_REQUIRED | SAM_SERVER_CONNECT
74     | SAM_SERVER_INITIALIZE | SAM_SERVER_CREATE_DOMAIN | SAM_SERVER_SHUTDOWN
75     | SAM_SERVER_ENUMERATE_DOMAINS | SAM_SERVER_LOOKUP_DOMAIN;
76 pub const SAM_SERVER_READ: ACCESS_MASK = STANDARD_RIGHTS_READ | SAM_SERVER_ENUMERATE_DOMAINS;
77 pub const SAM_SERVER_WRITE: ACCESS_MASK =
78     STANDARD_RIGHTS_WRITE | SAM_SERVER_INITIALIZE | SAM_SERVER_CREATE_DOMAIN | SAM_SERVER_SHUTDOWN;
79 pub const SAM_SERVER_EXECUTE: ACCESS_MASK =
80     STANDARD_RIGHTS_EXECUTE | SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN;
81 EXTERN!{extern "system" {
82     fn SamConnect(
83         ServerName: PUNICODE_STRING,
84         ServerHandle: PSAM_HANDLE,
85         DesiredAccess: ACCESS_MASK,
86         ObjectAttributes: POBJECT_ATTRIBUTES,
87     ) -> NTSTATUS;
88     fn SamShutdownSamServer(
89         ServerHandle: SAM_HANDLE,
90     ) -> NTSTATUS;
91 }}
92 pub const DOMAIN_READ_PASSWORD_PARAMETERS: u32 = 0x0001;
93 pub const DOMAIN_WRITE_PASSWORD_PARAMS: u32 = 0x0002;
94 pub const DOMAIN_READ_OTHER_PARAMETERS: u32 = 0x0004;
95 pub const DOMAIN_WRITE_OTHER_PARAMETERS: u32 = 0x0008;
96 pub const DOMAIN_CREATE_USER: u32 = 0x0010;
97 pub const DOMAIN_CREATE_GROUP: u32 = 0x0020;
98 pub const DOMAIN_CREATE_ALIAS: u32 = 0x0040;
99 pub const DOMAIN_GET_ALIAS_MEMBERSHIP: u32 = 0x0080;
100 pub const DOMAIN_LIST_ACCOUNTS: u32 = 0x0100;
101 pub const DOMAIN_LOOKUP: u32 = 0x0200;
102 pub const DOMAIN_ADMINISTER_SERVER: u32 = 0x0400;
103 pub const DOMAIN_ALL_ACCESS: u32 = STANDARD_RIGHTS_REQUIRED | DOMAIN_READ_OTHER_PARAMETERS
104     | DOMAIN_WRITE_OTHER_PARAMETERS | DOMAIN_WRITE_PASSWORD_PARAMS | DOMAIN_CREATE_USER
105     | DOMAIN_CREATE_GROUP | DOMAIN_CREATE_ALIAS | DOMAIN_GET_ALIAS_MEMBERSHIP
106     | DOMAIN_LIST_ACCOUNTS | DOMAIN_READ_PASSWORD_PARAMETERS | DOMAIN_LOOKUP
107     | DOMAIN_ADMINISTER_SERVER;
108 pub const DOMAIN_READ: u32 =
109     STANDARD_RIGHTS_READ | DOMAIN_GET_ALIAS_MEMBERSHIP | DOMAIN_READ_OTHER_PARAMETERS;
110 pub const DOMAIN_WRITE: u32 = STANDARD_RIGHTS_WRITE | DOMAIN_WRITE_OTHER_PARAMETERS
111     | DOMAIN_WRITE_PASSWORD_PARAMS | DOMAIN_CREATE_USER | DOMAIN_CREATE_GROUP | DOMAIN_CREATE_ALIAS
112     | DOMAIN_ADMINISTER_SERVER;
113 pub const DOMAIN_EXECUTE: u32 = STANDARD_RIGHTS_EXECUTE | DOMAIN_READ_PASSWORD_PARAMETERS
114     | DOMAIN_LIST_ACCOUNTS | DOMAIN_LOOKUP;
115 ENUM!{enum DOMAIN_INFORMATION_CLASS {
116     DomainPasswordInformation = 1,
117     DomainGeneralInformation = 2,
118     DomainLogoffInformation = 3,
119     DomainOemInformation = 4,
120     DomainNameInformation = 5,
121     DomainReplicationInformation = 6,
122     DomainServerRoleInformation = 7,
123     DomainModifiedInformation = 8,
124     DomainStateInformation = 9,
125     DomainUasInformation = 10,
126     DomainGeneralInformation2 = 11,
127     DomainLockoutInformation = 12,
128     DomainModifiedInformation2 = 13,
129 }}
130 ENUM!{enum DOMAIN_SERVER_ENABLE_STATE {
131     DomainServerEnabled = 1,
132     DomainServerDisabled = 2,
133 }}
134 pub type PDOMAIN_SERVER_ENABLE_STATE = *mut DOMAIN_SERVER_ENABLE_STATE;
135 ENUM!{enum DOMAIN_SERVER_ROLE {
136     DomainServerRoleBackup = 2,
137     DomainServerRolePrimary = 3,
138 }}
139 pub type PDOMAIN_SERVER_ROLE = *mut DOMAIN_SERVER_ROLE;
140 STRUCT!{#[repr(packed(4))] struct DOMAIN_GENERAL_INFORMATION {
141     ForceLogoff: LARGE_INTEGER,
142     OemInformation: UNICODE_STRING,
143     DomainName: UNICODE_STRING,
144     ReplicaSourceNodeName: UNICODE_STRING,
145     DomainModifiedCount: LARGE_INTEGER,
146     DomainServerState: DOMAIN_SERVER_ENABLE_STATE,
147     DomainServerRole: DOMAIN_SERVER_ROLE,
148     UasCompatibilityRequired: BOOLEAN,
149     UserCount: ULONG,
150     GroupCount: ULONG,
151     AliasCount: ULONG,
152 }}
153 pub type PDOMAIN_GENERAL_INFORMATION = *mut DOMAIN_GENERAL_INFORMATION;
154 STRUCT!{#[repr(packed(4))] struct DOMAIN_GENERAL_INFORMATION2 {
155     I1: DOMAIN_GENERAL_INFORMATION,
156     LockoutDuration: LARGE_INTEGER,
157     LockoutObservationWindow: LARGE_INTEGER,
158     LockoutThreshold: USHORT,
159 }}
160 pub type PDOMAIN_GENERAL_INFORMATION2 = *mut DOMAIN_GENERAL_INFORMATION2;
161 STRUCT!{struct DOMAIN_UAS_INFORMATION {
162     UasCompatibilityRequired: BOOLEAN,
163 }}
164 ENUM!{enum DOMAIN_PASSWORD_CONSTRUCTION {
165     DomainPasswordSimple = 1,
166     DomainPasswordComplex = 2,
167 }}
168 STRUCT!{struct DOMAIN_LOGOFF_INFORMATION {
169     ForceLogoff: LARGE_INTEGER,
170 }}
171 pub type PDOMAIN_LOGOFF_INFORMATION = *mut DOMAIN_LOGOFF_INFORMATION;
172 STRUCT!{struct DOMAIN_OEM_INFORMATION {
173     OemInformation: UNICODE_STRING,
174 }}
175 pub type PDOMAIN_OEM_INFORMATION = *mut DOMAIN_OEM_INFORMATION;
176 STRUCT!{struct DOMAIN_NAME_INFORMATION {
177     DomainName: UNICODE_STRING,
178 }}
179 pub type PDOMAIN_NAME_INFORMATION = *mut DOMAIN_NAME_INFORMATION;
180 STRUCT!{struct DOMAIN_SERVER_ROLE_INFORMATION {
181     DomainServerRole: DOMAIN_SERVER_ROLE,
182 }}
183 pub type PDOMAIN_SERVER_ROLE_INFORMATION = *mut DOMAIN_SERVER_ROLE_INFORMATION;
184 STRUCT!{struct DOMAIN_REPLICATION_INFORMATION {
185     ReplicaSourceNodeName: UNICODE_STRING,
186 }}
187 pub type PDOMAIN_REPLICATION_INFORMATION = *mut DOMAIN_REPLICATION_INFORMATION;
188 STRUCT!{struct DOMAIN_MODIFIED_INFORMATION {
189     DomainModifiedCount: LARGE_INTEGER,
190     CreationTime: LARGE_INTEGER,
191 }}
192 pub type PDOMAIN_MODIFIED_INFORMATION = *mut DOMAIN_MODIFIED_INFORMATION;
193 STRUCT!{struct DOMAIN_MODIFIED_INFORMATION2 {
194     DomainModifiedCount: LARGE_INTEGER,
195     CreationTime: LARGE_INTEGER,
196     ModifiedCountAtLastPromotion: LARGE_INTEGER,
197 }}
198 pub type PDOMAIN_MODIFIED_INFORMATION2 = *mut DOMAIN_MODIFIED_INFORMATION2;
199 STRUCT!{struct DOMAIN_STATE_INFORMATION {
200     DomainServerState: DOMAIN_SERVER_ENABLE_STATE,
201 }}
202 pub type PDOMAIN_STATE_INFORMATION = *mut DOMAIN_STATE_INFORMATION;
203 STRUCT!{struct DOMAIN_LOCKOUT_INFORMATION {
204     LockoutDuration: LARGE_INTEGER,
205     LockoutObservationWindow: LARGE_INTEGER,
206     LockoutThreshold: USHORT,
207 }}
208 pub type PDOMAIN_LOCKOUT_INFORMATION = *mut DOMAIN_LOCKOUT_INFORMATION;
209 ENUM!{enum DOMAIN_DISPLAY_INFORMATION {
210     DomainDisplayUser = 1,
211     DomainDisplayMachine = 2,
212     DomainDisplayGroup = 3,
213     DomainDisplayOemUser = 4,
214     DomainDisplayOemGroup = 5,
215     DomainDisplayServer = 6,
216 }}
217 pub type PDOMAIN_DISPLAY_INFORMATION = *mut DOMAIN_DISPLAY_INFORMATION;
218 STRUCT!{struct DOMAIN_DISPLAY_USER {
219     Index: ULONG,
220     Rid: ULONG,
221     AccountControl: ULONG,
222     LogonName: UNICODE_STRING,
223     AdminComment: UNICODE_STRING,
224     FullName: UNICODE_STRING,
225 }}
226 pub type PDOMAIN_DISPLAY_USER = *mut DOMAIN_DISPLAY_USER;
227 STRUCT!{struct DOMAIN_DISPLAY_MACHINE {
228     Index: ULONG,
229     Rid: ULONG,
230     AccountControl: ULONG,
231     Machine: UNICODE_STRING,
232     Comment: UNICODE_STRING,
233 }}
234 pub type PDOMAIN_DISPLAY_MACHINE = *mut DOMAIN_DISPLAY_MACHINE;
235 STRUCT!{struct DOMAIN_DISPLAY_GROUP {
236     Index: ULONG,
237     Rid: ULONG,
238     Attributes: ULONG,
239     Group: UNICODE_STRING,
240     Comment: UNICODE_STRING,
241 }}
242 pub type PDOMAIN_DISPLAY_GROUP = *mut DOMAIN_DISPLAY_GROUP;
243 STRUCT!{struct DOMAIN_DISPLAY_OEM_USER {
244     Index: ULONG,
245     User: OEM_STRING,
246 }}
247 pub type PDOMAIN_DISPLAY_OEM_USER = *mut DOMAIN_DISPLAY_OEM_USER;
248 STRUCT!{struct DOMAIN_DISPLAY_OEM_GROUP {
249     Index: ULONG,
250     Group: OEM_STRING,
251 }}
252 pub type PDOMAIN_DISPLAY_OEM_GROUP = *mut DOMAIN_DISPLAY_OEM_GROUP;
253 ENUM!{enum DOMAIN_LOCALIZABLE_ACCOUNTS_INFORMATION {
254     DomainLocalizableAccountsBasic = 1,
255 }}
256 pub type PDOMAIN_LOCALIZABLE_ACCOUNTS_INFORMATION = *mut DOMAIN_LOCALIZABLE_ACCOUNTS_INFORMATION;
257 STRUCT!{struct DOMAIN_LOCALIZABLE_ACCOUNT_ENTRY {
258     Rid: ULONG,
259     Use: SID_NAME_USE,
260     Name: UNICODE_STRING,
261     AdminComment: UNICODE_STRING,
262 }}
263 pub type PDOMAIN_LOCALIZABLE_ACCOUNT_ENTRY = *mut DOMAIN_LOCALIZABLE_ACCOUNT_ENTRY;
264 STRUCT!{struct DOMAIN_LOCALIZABLE_ACCOUNTS_BASIC {
265     Count: ULONG,
266     Entries: *mut DOMAIN_LOCALIZABLE_ACCOUNT_ENTRY,
267 }}
268 pub type PDOMAIN_LOCALIZABLE_ACCOUNTS_BASIC = *mut DOMAIN_LOCALIZABLE_ACCOUNTS_BASIC;
269 UNION!{union DOMAIN_LOCALIZABLE_ACCOUNTS_INFO_BUFFER {
270     Basic: DOMAIN_LOCALIZABLE_ACCOUNTS_BASIC,
271 }}
272 pub type PDOMAIN_LOCALIZABLE_ACCOUNTS_INFO_BUFFER = *mut DOMAIN_LOCALIZABLE_ACCOUNTS_INFO_BUFFER;
273 EXTERN!{extern "system" {
274     fn SamLookupDomainInSamServer(
275         ServerHandle: SAM_HANDLE,
276         Name: PUNICODE_STRING,
277         DomainId: *mut PSID,
278     ) -> NTSTATUS;
279     fn SamEnumerateDomainsInSamServer(
280         ServerHandle: SAM_HANDLE,
281         EnumerationContext: PSAM_ENUMERATE_HANDLE,
282         Buffer: *mut PVOID,
283         PreferedMaximumLength: ULONG,
284         CountReturned: PULONG,
285     ) -> NTSTATUS;
286     fn SamOpenDomain(
287         ServerHandle: SAM_HANDLE,
288         DesiredAccess: ACCESS_MASK,
289         DomainId: PSID,
290         DomainHandle: PSAM_HANDLE,
291     ) -> NTSTATUS;
292     fn SamQueryInformationDomain(
293         DomainHandle: SAM_HANDLE,
294         DomainInformationClass: DOMAIN_INFORMATION_CLASS,
295         Buffer: *mut PVOID,
296     ) -> NTSTATUS;
297     fn SamSetInformationDomain(
298         DomainHandle: SAM_HANDLE,
299         DomainInformationClass: DOMAIN_INFORMATION_CLASS,
300         DomainInformation: PVOID,
301     ) -> NTSTATUS;
302     fn SamLookupNamesInDomain(
303         DomainHandle: SAM_HANDLE,
304         Count: ULONG,
305         Names: PUNICODE_STRING,
306         RelativeIds: *mut PULONG,
307         Use: *mut PSID_NAME_USE,
308     ) -> NTSTATUS;
309     fn SamLookupIdsInDomain(
310         DomainHandle: SAM_HANDLE,
311         Count: ULONG,
312         RelativeIds: PULONG,
313         Names: *mut PUNICODE_STRING,
314         Use: *mut PSID_NAME_USE,
315     ) -> NTSTATUS;
316     fn SamRemoveMemberFromForeignDomain(
317         DomainHandle: SAM_HANDLE,
318         MemberId: PSID,
319     ) -> NTSTATUS;
320     fn SamQueryLocalizableAccountsInDomain(
321         Domain: SAM_HANDLE,
322         Flags: ULONG,
323         LanguageId: ULONG,
324         Class: DOMAIN_LOCALIZABLE_ACCOUNTS_INFORMATION,
325         Buffer: *mut PVOID,
326     ) -> NTSTATUS;
327 }}
328 pub const GROUP_READ_INFORMATION: ACCESS_MASK = 0x0001;
329 pub const GROUP_WRITE_ACCOUNT: ACCESS_MASK = 0x0002;
330 pub const GROUP_ADD_MEMBER: ACCESS_MASK = 0x0004;
331 pub const GROUP_REMOVE_MEMBER: ACCESS_MASK = 0x0008;
332 pub const GROUP_LIST_MEMBERS: ACCESS_MASK = 0x0010;
333 pub const GROUP_ALL_ACCESS: ACCESS_MASK = STANDARD_RIGHTS_REQUIRED | GROUP_LIST_MEMBERS
334     | GROUP_WRITE_ACCOUNT | GROUP_ADD_MEMBER | GROUP_REMOVE_MEMBER | GROUP_READ_INFORMATION;
335 pub const GROUP_READ: ACCESS_MASK = STANDARD_RIGHTS_READ | GROUP_LIST_MEMBERS;
336 pub const GROUP_WRITE: ACCESS_MASK =
337     STANDARD_RIGHTS_WRITE | GROUP_WRITE_ACCOUNT | GROUP_ADD_MEMBER | GROUP_REMOVE_MEMBER;
338 pub const GROUP_EXECUTE: ACCESS_MASK = STANDARD_RIGHTS_EXECUTE | GROUP_READ_INFORMATION;
339 STRUCT!{struct GROUP_MEMBERSHIP {
340     RelativeId: ULONG,
341     Attributes: ULONG,
342 }}
343 pub type PGROUP_MEMBERSHIP = *mut GROUP_MEMBERSHIP;
344 ENUM!{enum GROUP_INFORMATION_CLASS {
345     GroupGeneralInformation = 1,
346     GroupNameInformation = 2,
347     GroupAttributeInformation = 3,
348     GroupAdminCommentInformation = 4,
349     GroupReplicationInformation = 5,
350 }}
351 STRUCT!{struct GROUP_GENERAL_INFORMATION {
352     Name: UNICODE_STRING,
353     Attributes: ULONG,
354     MemberCount: ULONG,
355     AdminComment: UNICODE_STRING,
356 }}
357 pub type PGROUP_GENERAL_INFORMATION = *mut GROUP_GENERAL_INFORMATION;
358 STRUCT!{struct GROUP_NAME_INFORMATION {
359     Name: UNICODE_STRING,
360 }}
361 pub type PGROUP_NAME_INFORMATION = *mut GROUP_NAME_INFORMATION;
362 STRUCT!{struct GROUP_ATTRIBUTE_INFORMATION {
363     Attributes: ULONG,
364 }}
365 pub type PGROUP_ATTRIBUTE_INFORMATION = *mut GROUP_ATTRIBUTE_INFORMATION;
366 STRUCT!{struct GROUP_ADM_COMMENT_INFORMATION {
367     AdminComment: UNICODE_STRING,
368 }}
369 pub type PGROUP_ADM_COMMENT_INFORMATION = *mut GROUP_ADM_COMMENT_INFORMATION;
370 EXTERN!{extern "system" {
371     fn SamEnumerateGroupsInDomain(
372         DomainHandle: SAM_HANDLE,
373         EnumerationContext: PSAM_ENUMERATE_HANDLE,
374         Buffer: *mut PVOID,
375         PreferedMaximumLength: ULONG,
376         CountReturned: PULONG,
377     ) -> NTSTATUS;
378     fn SamCreateGroupInDomain(
379         DomainHandle: SAM_HANDLE,
380         AccountName: PUNICODE_STRING,
381         DesiredAccess: ACCESS_MASK,
382         GroupHandle: PSAM_HANDLE,
383         RelativeId: PULONG,
384     ) -> NTSTATUS;
385     fn SamOpenGroup(
386         DomainHandle: SAM_HANDLE,
387         DesiredAccess: ACCESS_MASK,
388         GroupId: ULONG,
389         GroupHandle: PSAM_HANDLE,
390     ) -> NTSTATUS;
391     fn SamDeleteGroup(
392         GroupHandle: SAM_HANDLE,
393     ) -> NTSTATUS;
394     fn SamQueryInformationGroup(
395         GroupHandle: SAM_HANDLE,
396         GroupInformationClass: GROUP_INFORMATION_CLASS,
397         Buffer: *mut PVOID,
398     ) -> NTSTATUS;
399     fn SamSetInformationGroup(
400         GroupHandle: SAM_HANDLE,
401         GroupInformationClass: GROUP_INFORMATION_CLASS,
402         Buffer: PVOID,
403     ) -> NTSTATUS;
404     fn SamAddMemberToGroup(
405         GroupHandle: SAM_HANDLE,
406         MemberId: ULONG,
407         Attributes: ULONG,
408     ) -> NTSTATUS;
409     fn SamRemoveMemberFromGroup(
410         GroupHandle: SAM_HANDLE,
411         MemberId: ULONG,
412     ) -> NTSTATUS;
413     fn SamGetMembersInGroup(
414         GroupHandle: SAM_HANDLE,
415         MemberIds: *mut PULONG,
416         Attributes: *mut PULONG,
417         MemberCount: PULONG,
418     ) -> NTSTATUS;
419     fn SamSetMemberAttributesOfGroup(
420         GroupHandle: SAM_HANDLE,
421         MemberId: ULONG,
422         Attributes: ULONG,
423     ) -> NTSTATUS;
424 }}
425 pub const ALIAS_ADD_MEMBER: ACCESS_MASK = 0x0001;
426 pub const ALIAS_REMOVE_MEMBER: ACCESS_MASK = 0x0002;
427 pub const ALIAS_LIST_MEMBERS: ACCESS_MASK = 0x0004;
428 pub const ALIAS_READ_INFORMATION: ACCESS_MASK = 0x0008;
429 pub const ALIAS_WRITE_ACCOUNT: ACCESS_MASK = 0x0010;
430 pub const ALIAS_ALL_ACCESS: ACCESS_MASK = STANDARD_RIGHTS_REQUIRED | ALIAS_READ_INFORMATION
431     | ALIAS_WRITE_ACCOUNT | ALIAS_LIST_MEMBERS | ALIAS_ADD_MEMBER | ALIAS_REMOVE_MEMBER;
432 pub const ALIAS_READ: ACCESS_MASK = STANDARD_RIGHTS_READ | ALIAS_LIST_MEMBERS;
433 pub const ALIAS_WRITE: ACCESS_MASK =
434     STANDARD_RIGHTS_WRITE | ALIAS_WRITE_ACCOUNT | ALIAS_ADD_MEMBER | ALIAS_REMOVE_MEMBER;
435 pub const ALIAS_EXECUTE: ACCESS_MASK = STANDARD_RIGHTS_EXECUTE | ALIAS_READ_INFORMATION;
436 ENUM!{enum ALIAS_INFORMATION_CLASS {
437     AliasGeneralInformation = 1,
438     AliasNameInformation = 2,
439     AliasAdminCommentInformation = 3,
440     AliasReplicationInformation = 4,
441     AliasExtendedInformation = 5,
442 }}
443 STRUCT!{struct ALIAS_GENERAL_INFORMATION {
444     Name: UNICODE_STRING,
445     MemberCount: ULONG,
446     AdminComment: UNICODE_STRING,
447 }}
448 pub type PALIAS_GENERAL_INFORMATION = *mut ALIAS_GENERAL_INFORMATION;
449 STRUCT!{struct ALIAS_NAME_INFORMATION {
450     Name: UNICODE_STRING,
451 }}
452 pub type PALIAS_NAME_INFORMATION = *mut ALIAS_NAME_INFORMATION;
453 STRUCT!{struct ALIAS_ADM_COMMENT_INFORMATION {
454     AdminComment: UNICODE_STRING,
455 }}
456 pub type PALIAS_ADM_COMMENT_INFORMATION = *mut ALIAS_ADM_COMMENT_INFORMATION;
457 pub const ALIAS_ALL_NAME: ULONG = 0x00000001;
458 pub const ALIAS_ALL_MEMBER_COUNT: ULONG = 0x00000002;
459 pub const ALIAS_ALL_ADMIN_COMMENT: ULONG = 0x00000004;
460 pub const ALIAS_ALL_SHELL_ADMIN_OBJECT_PROPERTIES: ULONG = 0x00000008;
461 STRUCT!{struct ALIAS_EXTENDED_INFORMATION {
462     WhichFields: ULONG,
463     ShellAdminObjectProperties: SAM_SHELL_OBJECT_PROPERTIES,
464 }}
465 pub type PALIAS_EXTENDED_INFORMATION = *mut ALIAS_EXTENDED_INFORMATION;
466 EXTERN!{extern "system" {
467     fn SamEnumerateAliasesInDomain(
468         DomainHandle: SAM_HANDLE,
469         EnumerationContext: PSAM_ENUMERATE_HANDLE,
470         Buffer: *mut PVOID,
471         PreferedMaximumLength: ULONG,
472         CountReturned: PULONG,
473     ) -> NTSTATUS;
474     fn SamCreateAliasInDomain(
475         DomainHandle: SAM_HANDLE,
476         AccountName: PUNICODE_STRING,
477         DesiredAccess: ACCESS_MASK,
478         AliasHandle: PSAM_HANDLE,
479         RelativeId: PULONG,
480     ) -> NTSTATUS;
481     fn SamOpenAlias(
482         DomainHandle: SAM_HANDLE,
483         DesiredAccess: ACCESS_MASK,
484         AliasId: ULONG,
485         AliasHandle: PSAM_HANDLE,
486     ) -> NTSTATUS;
487     fn SamDeleteAlias(
488         AliasHandle: SAM_HANDLE,
489     ) -> NTSTATUS;
490     fn SamQueryInformationAlias(
491         AliasHandle: SAM_HANDLE,
492         AliasInformationClass: ALIAS_INFORMATION_CLASS,
493         Buffer: *mut PVOID,
494     ) -> NTSTATUS;
495     fn SamSetInformationAlias(
496         AliasHandle: SAM_HANDLE,
497         AliasInformationClass: ALIAS_INFORMATION_CLASS,
498         Buffer: PVOID,
499     ) -> NTSTATUS;
500     fn SamAddMemberToAlias(
501         AliasHandle: SAM_HANDLE,
502         MemberId: PSID,
503     ) -> NTSTATUS;
504     fn SamAddMultipleMembersToAlias(
505         AliasHandle: SAM_HANDLE,
506         MemberIds: *mut PSID,
507         MemberCount: ULONG,
508     ) -> NTSTATUS;
509     fn SamRemoveMemberFromAlias(
510         AliasHandle: SAM_HANDLE,
511         MemberId: PSID,
512     ) -> NTSTATUS;
513     fn SamRemoveMultipleMembersFromAlias(
514         AliasHandle: SAM_HANDLE,
515         MemberIds: *mut PSID,
516         MemberCount: ULONG,
517     ) -> NTSTATUS;
518     fn SamGetMembersInAlias(
519         AliasHandle: SAM_HANDLE,
520         MemberIds: *mut *mut PSID,
521         MemberCount: PULONG,
522     ) -> NTSTATUS;
523     fn SamGetAliasMembership(
524         DomainHandle: SAM_HANDLE,
525         PassedCount: ULONG,
526         Sids: *mut PSID,
527         MembershipCount: PULONG,
528         Aliases: *mut PULONG,
529     ) -> NTSTATUS;
530 }}
531 pub const GROUP_TYPE_BUILTIN_LOCAL_GROUP: u32 = 0x00000001;
532 pub const GROUP_TYPE_ACCOUNT_GROUP: u32 = 0x00000002;
533 pub const GROUP_TYPE_RESOURCE_GROUP: u32 = 0x00000004;
534 pub const GROUP_TYPE_UNIVERSAL_GROUP: u32 = 0x00000008;
535 pub const GROUP_TYPE_APP_BASIC_GROUP: u32 = 0x00000010;
536 pub const GROUP_TYPE_APP_QUERY_GROUP: u32 = 0x00000020;
537 pub const GROUP_TYPE_SECURITY_ENABLED: u32 = 0x80000000;
538 pub const GROUP_TYPE_RESOURCE_BEHAVOIR: u32 =
539     GROUP_TYPE_RESOURCE_GROUP | GROUP_TYPE_APP_BASIC_GROUP | GROUP_TYPE_APP_QUERY_GROUP;
540 pub const USER_READ_GENERAL: DWORD = 0x0001;
541 pub const USER_READ_PREFERENCES: DWORD = 0x0002;
542 pub const USER_WRITE_PREFERENCES: DWORD = 0x0004;
543 pub const USER_READ_LOGON: DWORD = 0x0008;
544 pub const USER_READ_ACCOUNT: DWORD = 0x0010;
545 pub const USER_WRITE_ACCOUNT: DWORD = 0x0020;
546 pub const USER_CHANGE_PASSWORD: DWORD = 0x0040;
547 pub const USER_FORCE_PASSWORD_CHANGE: DWORD = 0x0080;
548 pub const USER_LIST_GROUPS: DWORD = 0x0100;
549 pub const USER_READ_GROUP_INFORMATION: DWORD = 0x0200;
550 pub const USER_WRITE_GROUP_INFORMATION: DWORD = 0x0400;
551 pub const USER_ALL_ACCESS: DWORD = STANDARD_RIGHTS_REQUIRED | USER_READ_PREFERENCES
552     | USER_READ_LOGON | USER_LIST_GROUPS | USER_READ_GROUP_INFORMATION | USER_WRITE_PREFERENCES
553     | USER_CHANGE_PASSWORD | USER_FORCE_PASSWORD_CHANGE | USER_READ_GENERAL | USER_READ_ACCOUNT
554     | USER_WRITE_ACCOUNT | USER_WRITE_GROUP_INFORMATION;
555 pub const USER_READ: DWORD = STANDARD_RIGHTS_READ | USER_READ_PREFERENCES | USER_READ_LOGON
556     | USER_READ_ACCOUNT | USER_LIST_GROUPS | USER_READ_GROUP_INFORMATION;
557 pub const USER_WRITE: DWORD =
558     STANDARD_RIGHTS_WRITE | USER_WRITE_PREFERENCES | USER_CHANGE_PASSWORD;
559 pub const USER_EXECUTE: DWORD = STANDARD_RIGHTS_EXECUTE | USER_READ_GENERAL | USER_CHANGE_PASSWORD;
560 ENUM!{enum USER_INFORMATION_CLASS {
561     UserGeneralInformation = 1,
562     UserPreferencesInformation = 2,
563     UserLogonInformation = 3,
564     UserLogonHoursInformation = 4,
565     UserAccountInformation = 5,
566     UserNameInformation = 6,
567     UserAccountNameInformation = 7,
568     UserFullNameInformation = 8,
569     UserPrimaryGroupInformation = 9,
570     UserHomeInformation = 10,
571     UserScriptInformation = 11,
572     UserProfileInformation = 12,
573     UserAdminCommentInformation = 13,
574     UserWorkStationsInformation = 14,
575     UserSetPasswordInformation = 15,
576     UserControlInformation = 16,
577     UserExpiresInformation = 17,
578     UserInternal1Information = 18,
579     UserInternal2Information = 19,
580     UserParametersInformation = 20,
581     UserAllInformation = 21,
582     UserInternal3Information = 22,
583     UserInternal4Information = 23,
584     UserInternal5Information = 24,
585     UserInternal4InformationNew = 25,
586     UserInternal5InformationNew = 26,
587     UserInternal6Information = 27,
588     UserExtendedInformation = 28,
589     UserLogonUIInformation = 29,
590 }}
591 pub type PUSER_INFORMATION_CLASS = *mut USER_INFORMATION_CLASS;
592 pub const USER_ALL_USERNAME: ULONG = 0x00000001;
593 pub const USER_ALL_FULLNAME: ULONG = 0x00000002;
594 pub const USER_ALL_USERID: ULONG = 0x00000004;
595 pub const USER_ALL_PRIMARYGROUPID: ULONG = 0x00000008;
596 pub const USER_ALL_ADMINCOMMENT: ULONG = 0x00000010;
597 pub const USER_ALL_USERCOMMENT: ULONG = 0x00000020;
598 pub const USER_ALL_HOMEDIRECTORY: ULONG = 0x00000040;
599 pub const USER_ALL_HOMEDIRECTORYDRIVE: ULONG = 0x00000080;
600 pub const USER_ALL_SCRIPTPATH: ULONG = 0x00000100;
601 pub const USER_ALL_PROFILEPATH: ULONG = 0x00000200;
602 pub const USER_ALL_WORKSTATIONS: ULONG = 0x00000400;
603 pub const USER_ALL_LASTLOGON: ULONG = 0x00000800;
604 pub const USER_ALL_LASTLOGOFF: ULONG = 0x00001000;
605 pub const USER_ALL_LOGONHOURS: ULONG = 0x00002000;
606 pub const USER_ALL_BADPASSWORDCOUNT: ULONG = 0x00004000;
607 pub const USER_ALL_LOGONCOUNT: ULONG = 0x00008000;
608 pub const USER_ALL_PASSWORDCANCHANGE: ULONG = 0x00010000;
609 pub const USER_ALL_PASSWORDMUSTCHANGE: ULONG = 0x00020000;
610 pub const USER_ALL_PASSWORDLASTSET: ULONG = 0x00040000;
611 pub const USER_ALL_ACCOUNTEXPIRES: ULONG = 0x00080000;
612 pub const USER_ALL_USERACCOUNTCONTROL: ULONG = 0x00100000;
613 pub const USER_ALL_PARAMETERS: ULONG = 0x00200000;
614 pub const USER_ALL_COUNTRYCODE: ULONG = 0x00400000;
615 pub const USER_ALL_CODEPAGE: ULONG = 0x00800000;
616 pub const USER_ALL_NTPASSWORDPRESENT: ULONG = 0x01000000;
617 pub const USER_ALL_LMPASSWORDPRESENT: ULONG = 0x02000000;
618 pub const USER_ALL_PRIVATEDATA: ULONG = 0x04000000;
619 pub const USER_ALL_PASSWORDEXPIRED: ULONG = 0x08000000;
620 pub const USER_ALL_SECURITYDESCRIPTOR: ULONG = 0x10000000;
621 pub const USER_ALL_OWFPASSWORD: ULONG = 0x20000000;
622 pub const USER_ALL_UNDEFINED_MASK: ULONG = 0xc0000000;
623 pub const USER_ALL_READ_GENERAL_MASK: ULONG = USER_ALL_USERNAME | USER_ALL_FULLNAME
624     | USER_ALL_USERID | USER_ALL_PRIMARYGROUPID | USER_ALL_ADMINCOMMENT | USER_ALL_USERCOMMENT;
625 pub const USER_ALL_READ_LOGON_MASK: ULONG = USER_ALL_HOMEDIRECTORY | USER_ALL_HOMEDIRECTORYDRIVE
626     | USER_ALL_SCRIPTPATH | USER_ALL_PROFILEPATH | USER_ALL_WORKSTATIONS | USER_ALL_LASTLOGON
627     | USER_ALL_LASTLOGOFF | USER_ALL_LOGONHOURS | USER_ALL_BADPASSWORDCOUNT | USER_ALL_LOGONCOUNT
628     | USER_ALL_PASSWORDCANCHANGE | USER_ALL_PASSWORDMUSTCHANGE;
629 pub const USER_ALL_READ_ACCOUNT_MASK: ULONG = USER_ALL_PASSWORDLASTSET | USER_ALL_ACCOUNTEXPIRES
630     | USER_ALL_USERACCOUNTCONTROL | USER_ALL_PARAMETERS;
631 pub const USER_ALL_READ_PREFERENCES_MASK: ULONG = USER_ALL_COUNTRYCODE | USER_ALL_CODEPAGE;
632 pub const USER_ALL_READ_TRUSTED_MASK: ULONG = USER_ALL_NTPASSWORDPRESENT
633     | USER_ALL_LMPASSWORDPRESENT | USER_ALL_PASSWORDEXPIRED | USER_ALL_SECURITYDESCRIPTOR
634     | USER_ALL_PRIVATEDATA;
635 pub const USER_ALL_READ_CANT_MASK: ULONG = USER_ALL_UNDEFINED_MASK;
636 pub const USER_ALL_WRITE_ACCOUNT_MASK: ULONG = USER_ALL_USERNAME | USER_ALL_FULLNAME
637     | USER_ALL_PRIMARYGROUPID | USER_ALL_HOMEDIRECTORY | USER_ALL_HOMEDIRECTORYDRIVE
638     | USER_ALL_SCRIPTPATH | USER_ALL_PROFILEPATH | USER_ALL_ADMINCOMMENT | USER_ALL_WORKSTATIONS
639     | USER_ALL_LOGONHOURS | USER_ALL_ACCOUNTEXPIRES | USER_ALL_USERACCOUNTCONTROL
640     | USER_ALL_PARAMETERS;
641 pub const USER_ALL_WRITE_PREFERENCES_MASK: ULONG =
642     USER_ALL_USERCOMMENT | USER_ALL_COUNTRYCODE | USER_ALL_CODEPAGE;
643 pub const USER_ALL_WRITE_FORCE_PASSWORD_CHANGE_MASK: ULONG =
644     USER_ALL_NTPASSWORDPRESENT | USER_ALL_LMPASSWORDPRESENT | USER_ALL_PASSWORDEXPIRED;
645 pub const USER_ALL_WRITE_TRUSTED_MASK: ULONG = USER_ALL_LASTLOGON | USER_ALL_LASTLOGOFF
646     | USER_ALL_BADPASSWORDCOUNT | USER_ALL_LOGONCOUNT | USER_ALL_PASSWORDLASTSET
647     | USER_ALL_SECURITYDESCRIPTOR | USER_ALL_PRIVATEDATA;
648 pub const USER_ALL_WRITE_CANT_MASK: ULONG = USER_ALL_USERID | USER_ALL_PASSWORDCANCHANGE
649     | USER_ALL_PASSWORDMUSTCHANGE | USER_ALL_UNDEFINED_MASK;
650 STRUCT!{struct USER_GENERAL_INFORMATION {
651     UserName: UNICODE_STRING,
652     FullName: UNICODE_STRING,
653     PrimaryGroupId: ULONG,
654     AdminComment: UNICODE_STRING,
655     UserComment: UNICODE_STRING,
656 }}
657 pub type PUSER_GENERAL_INFORMATION = *mut USER_GENERAL_INFORMATION;
658 STRUCT!{struct USER_PREFERENCES_INFORMATION {
659     UserComment: UNICODE_STRING,
660     Reserved1: UNICODE_STRING,
661     CountryCode: USHORT,
662     CodePage: USHORT,
663 }}
664 pub type PUSER_PREFERENCES_INFORMATION = *mut USER_PREFERENCES_INFORMATION;
665 STRUCT!{struct USER_PARAMETERS_INFORMATION {
666     Parameters: UNICODE_STRING,
667 }}
668 pub type PUSER_PARAMETERS_INFORMATION = *mut USER_PARAMETERS_INFORMATION;
669 STRUCT!{#[repr(packed(4))] struct USER_LOGON_INFORMATION {
670     UserName: UNICODE_STRING,
671     FullName: UNICODE_STRING,
672     UserId: ULONG,
673     PrimaryGroupId: ULONG,
674     HomeDirectory: UNICODE_STRING,
675     HomeDirectoryDrive: UNICODE_STRING,
676     ScriptPath: UNICODE_STRING,
677     ProfilePath: UNICODE_STRING,
678     WorkStations: UNICODE_STRING,
679     LastLogon: LARGE_INTEGER,
680     LastLogoff: LARGE_INTEGER,
681     PasswordLastSet: LARGE_INTEGER,
682     PasswordCanChange: LARGE_INTEGER,
683     PasswordMustChange: LARGE_INTEGER,
684     LogonHours: LOGON_HOURS,
685     BadPasswordCount: USHORT,
686     LogonCount: USHORT,
687     UserAccountControl: ULONG,
688 }}
689 pub type PUSER_LOGON_INFORMATION = *mut USER_LOGON_INFORMATION;
690 STRUCT!{#[repr(packed(4))] struct USER_ACCOUNT_INFORMATION {
691     UserName: UNICODE_STRING,
692     FullName: UNICODE_STRING,
693     UserId: ULONG,
694     PrimaryGroupId: ULONG,
695     HomeDirectory: UNICODE_STRING,
696     HomeDirectoryDrive: UNICODE_STRING,
697     ScriptPath: UNICODE_STRING,
698     ProfilePath: UNICODE_STRING,
699     AdminComment: UNICODE_STRING,
700     WorkStations: UNICODE_STRING,
701     LastLogon: LARGE_INTEGER,
702     LastLogoff: LARGE_INTEGER,
703     LogonHours: LOGON_HOURS,
704     BadPasswordCount: USHORT,
705     LogonCount: USHORT,
706     PasswordLastSet: LARGE_INTEGER,
707     AccountExpires: LARGE_INTEGER,
708     UserAccountControl: ULONG,
709 }}
710 pub type PUSER_ACCOUNT_INFORMATION = *mut USER_ACCOUNT_INFORMATION;
711 STRUCT!{struct USER_ACCOUNT_NAME_INFORMATION {
712     UserName: UNICODE_STRING,
713 }}
714 pub type PUSER_ACCOUNT_NAME_INFORMATION = *mut USER_ACCOUNT_NAME_INFORMATION;
715 STRUCT!{struct USER_FULL_NAME_INFORMATION {
716     FullName: UNICODE_STRING,
717 }}
718 pub type PUSER_FULL_NAME_INFORMATION = *mut USER_FULL_NAME_INFORMATION;
719 STRUCT!{struct USER_NAME_INFORMATION {
720     UserName: UNICODE_STRING,
721     FullName: UNICODE_STRING,
722 }}
723 pub type PUSER_NAME_INFORMATION = *mut USER_NAME_INFORMATION;
724 STRUCT!{struct USER_PRIMARY_GROUP_INFORMATION {
725     PrimaryGroupId: ULONG,
726 }}
727 pub type PUSER_PRIMARY_GROUP_INFORMATION = *mut USER_PRIMARY_GROUP_INFORMATION;
728 STRUCT!{struct USER_HOME_INFORMATION {
729     HomeDirectory: UNICODE_STRING,
730     HomeDirectoryDrive: UNICODE_STRING,
731 }}
732 pub type PUSER_HOME_INFORMATION = *mut USER_HOME_INFORMATION;
733 STRUCT!{struct USER_SCRIPT_INFORMATION {
734     ScriptPath: UNICODE_STRING,
735 }}
736 pub type PUSER_SCRIPT_INFORMATION = *mut USER_SCRIPT_INFORMATION;
737 STRUCT!{struct USER_PROFILE_INFORMATION {
738     ProfilePath: UNICODE_STRING,
739 }}
740 pub type PUSER_PROFILE_INFORMATION = *mut USER_PROFILE_INFORMATION;
741 STRUCT!{struct USER_ADMIN_COMMENT_INFORMATION {
742     AdminComment: UNICODE_STRING,
743 }}
744 pub type PUSER_ADMIN_COMMENT_INFORMATION = *mut USER_ADMIN_COMMENT_INFORMATION;
745 STRUCT!{struct USER_WORKSTATIONS_INFORMATION {
746     WorkStations: UNICODE_STRING,
747 }}
748 pub type PUSER_WORKSTATIONS_INFORMATION = *mut USER_WORKSTATIONS_INFORMATION;
749 STRUCT!{struct USER_SET_PASSWORD_INFORMATION {
750     Password: UNICODE_STRING,
751     PasswordExpired: BOOLEAN,
752 }}
753 pub type PUSER_SET_PASSWORD_INFORMATION = *mut USER_SET_PASSWORD_INFORMATION;
754 STRUCT!{struct USER_CONTROL_INFORMATION {
755     UserAccountControl: ULONG,
756 }}
757 pub type PUSER_CONTROL_INFORMATION = *mut USER_CONTROL_INFORMATION;
758 STRUCT!{struct USER_EXPIRES_INFORMATION {
759     AccountExpires: LARGE_INTEGER,
760 }}
761 pub type PUSER_EXPIRES_INFORMATION = *mut USER_EXPIRES_INFORMATION;
762 STRUCT!{struct USER_LOGON_HOURS_INFORMATION {
763     LogonHours: LOGON_HOURS,
764 }}
765 pub type PUSER_LOGON_HOURS_INFORMATION = *mut USER_LOGON_HOURS_INFORMATION;
766 pub type SAM_USER_TILE = SAM_BYTE_ARRAY_32K;
767 pub type PSAM_USER_TILE = *mut SAM_BYTE_ARRAY_32K;
768 pub const USER_EXTENDED_FIELD_USER_TILE: ULONG = 0x00001000;
769 pub const USER_EXTENDED_FIELD_PASSWORD_HINT: ULONG = 0x00002000;
770 pub const USER_EXTENDED_FIELD_DONT_SHOW_IN_LOGON_UI: ULONG = 0x00004000;
771 pub const USER_EXTENDED_FIELD_SHELL_ADMIN_OBJECT_PROPERTIES: ULONG = 0x00008000;
772 STRUCT!{struct USER_EXTENDED_INFORMATION {
773     ExtendedWhichFields: ULONG,
774     UserTile: SAM_USER_TILE,
775     PasswordHint: UNICODE_STRING,
776     DontShowInLogonUI: BOOLEAN,
777     ShellAdminObjectProperties: SAM_SHELL_OBJECT_PROPERTIES,
778 }}
779 pub type PUSER_EXTENDED_INFORMATION = *mut USER_EXTENDED_INFORMATION;
780 STRUCT!{struct USER_LOGON_UI_INFORMATION {
781     PasswordIsBlank: BOOLEAN,
782     AccountIsDisabled: BOOLEAN,
783 }}
784 pub type PUSER_LOGON_UI_INFORMATION = *mut USER_LOGON_UI_INFORMATION;
785 STRUCT!{struct USER_PWD_CHANGE_FAILURE_INFORMATION {
786     ExtendedFailureReason: ULONG,
787     FilterModuleName: UNICODE_STRING,
788 }}
789 pub type PUSER_PWD_CHANGE_FAILURE_INFORMATION = *mut USER_PWD_CHANGE_FAILURE_INFORMATION;
790 pub const SAM_PWD_CHANGE_NO_ERROR: u32 = 0;
791 pub const SAM_PWD_CHANGE_PASSWORD_TOO_SHORT: u32 = 1;
792 pub const SAM_PWD_CHANGE_PWD_IN_HISTORY: u32 = 2;
793 pub const SAM_PWD_CHANGE_USERNAME_IN_PASSWORD: u32 = 3;
794 pub const SAM_PWD_CHANGE_FULLNAME_IN_PASSWORD: u32 = 4;
795 pub const SAM_PWD_CHANGE_NOT_COMPLEX: u32 = 5;
796 pub const SAM_PWD_CHANGE_MACHINE_PASSWORD_NOT_DEFAULT: u32 = 6;
797 pub const SAM_PWD_CHANGE_FAILED_BY_FILTER: u32 = 7;
798 pub const SAM_PWD_CHANGE_PASSWORD_TOO_LONG: u32 = 8;
799 pub const SAM_PWD_CHANGE_FAILURE_REASON_MAX: u32 = 8;
800 EXTERN!{extern "system" {
801     fn SamEnumerateUsersInDomain(
802         DomainHandle: SAM_HANDLE,
803         EnumerationContext: PSAM_ENUMERATE_HANDLE,
804         UserAccountControl: ULONG,
805         Buffer: *mut PVOID,
806         PreferedMaximumLength: ULONG,
807         CountReturned: PULONG,
808     ) -> NTSTATUS;
809     fn SamCreateUserInDomain(
810         DomainHandle: SAM_HANDLE,
811         AccountName: PUNICODE_STRING,
812         DesiredAccess: ACCESS_MASK,
813         UserHandle: PSAM_HANDLE,
814         RelativeId: PULONG,
815     ) -> NTSTATUS;
816     fn SamCreateUser2InDomain(
817         DomainHandle: SAM_HANDLE,
818         AccountName: PUNICODE_STRING,
819         AccountType: ULONG,
820         DesiredAccess: ACCESS_MASK,
821         UserHandle: PSAM_HANDLE,
822         GrantedAccess: PULONG,
823         RelativeId: PULONG,
824     ) -> NTSTATUS;
825     fn SamOpenUser(
826         DomainHandle: SAM_HANDLE,
827         DesiredAccess: ACCESS_MASK,
828         UserId: ULONG,
829         UserHandle: PSAM_HANDLE,
830     ) -> NTSTATUS;
831     fn SamDeleteUser(
832         UserHandle: SAM_HANDLE,
833     ) -> NTSTATUS;
834     fn SamQueryInformationUser(
835         UserHandle: SAM_HANDLE,
836         UserInformationClass: USER_INFORMATION_CLASS,
837         Buffer: *mut PVOID,
838     ) -> NTSTATUS;
839     fn SamSetInformationUser(
840         UserHandle: SAM_HANDLE,
841         UserInformationClass: USER_INFORMATION_CLASS,
842         Buffer: PVOID,
843     ) -> NTSTATUS;
844     fn SamGetGroupsForUser(
845         UserHandle: SAM_HANDLE,
846         Groups: *mut PGROUP_MEMBERSHIP,
847         MembershipCount: PULONG,
848     ) -> NTSTATUS;
849     fn SamChangePasswordUser(
850         UserHandle: SAM_HANDLE,
851         OldPassword: PUNICODE_STRING,
852         NewPassword: PUNICODE_STRING,
853     ) -> NTSTATUS;
854     fn SamChangePasswordUser2(
855         ServerName: PUNICODE_STRING,
856         UserName: PUNICODE_STRING,
857         OldPassword: PUNICODE_STRING,
858         NewPassword: PUNICODE_STRING,
859     ) -> NTSTATUS;
860     fn SamChangePasswordUser3(
861         ServerName: PUNICODE_STRING,
862         UserName: PUNICODE_STRING,
863         OldPassword: PUNICODE_STRING,
864         NewPassword: PUNICODE_STRING,
865         EffectivePasswordPolicy: *mut PDOMAIN_PASSWORD_INFORMATION,
866         PasswordChangeFailureInfo: *mut PUSER_PWD_CHANGE_FAILURE_INFORMATION,
867     ) -> NTSTATUS;
868     fn SamQueryDisplayInformation(
869         DomainHandle: SAM_HANDLE,
870         DisplayInformation: DOMAIN_DISPLAY_INFORMATION,
871         Index: ULONG,
872         EntryCount: ULONG,
873         PreferredMaximumLength: ULONG,
874         TotalAvailable: PULONG,
875         TotalReturned: PULONG,
876         ReturnedEntryCount: PULONG,
877         SortedBuffer: *mut PVOID,
878     ) -> NTSTATUS;
879     fn SamGetDisplayEnumerationIndex(
880         DomainHandle: SAM_HANDLE,
881         DisplayInformation: DOMAIN_DISPLAY_INFORMATION,
882         Prefix: PUNICODE_STRING,
883         Index: PULONG,
884     ) -> NTSTATUS;
885 }}
886 ENUM!{enum SECURITY_DB_DELTA_TYPE {
887     SecurityDbNew = 1,
888     SecurityDbRename = 2,
889     SecurityDbDelete = 3,
890     SecurityDbChangeMemberAdd = 4,
891     SecurityDbChangeMemberSet = 5,
892     SecurityDbChangeMemberDel = 6,
893     SecurityDbChange = 7,
894     SecurityDbChangePassword = 8,
895 }}
896 pub type PSECURITY_DB_DELTA_TYPE = *mut SECURITY_DB_DELTA_TYPE;
897 ENUM!{enum SECURITY_DB_OBJECT_TYPE {
898     SecurityDbObjectSamDomain = 1,
899     SecurityDbObjectSamUser = 2,
900     SecurityDbObjectSamGroup = 3,
901     SecurityDbObjectSamAlias = 4,
902     SecurityDbObjectLsaPolicy = 5,
903     SecurityDbObjectLsaTDomain = 6,
904     SecurityDbObjectLsaAccount = 7,
905     SecurityDbObjectLsaSecret = 8,
906 }}
907 pub type PSECURITY_DB_OBJECT_TYPE = *mut SECURITY_DB_OBJECT_TYPE;
908 ENUM!{enum SAM_ACCOUNT_TYPE {
909     SamObjectUser = 1,
910     SamObjectGroup = 2,
911     SamObjectAlias = 3,
912 }}
913 pub type PSAM_ACCOUNT_TYPE = *mut SAM_ACCOUNT_TYPE;
914 pub const SAM_USER_ACCOUNT: u32 = 0x00000001;
915 pub const SAM_GLOBAL_GROUP_ACCOUNT: u32 = 0x00000002;
916 pub const SAM_LOCAL_GROUP_ACCOUNT: u32 = 0x00000004;
917 STRUCT!{struct SAM_GROUP_MEMBER_ID {
918     MemberRid: ULONG,
919 }}
920 pub type PSAM_GROUP_MEMBER_ID = *mut SAM_GROUP_MEMBER_ID;
921 STRUCT!{struct SAM_ALIAS_MEMBER_ID {
922     MemberSid: PSID,
923 }}
924 pub type PSAM_ALIAS_MEMBER_ID = *mut SAM_ALIAS_MEMBER_ID;
925 UNION!{union SAM_DELTA_DATA {
926     GroupMemberId: SAM_GROUP_MEMBER_ID,
927     AliasMemberId: SAM_ALIAS_MEMBER_ID,
928     AccountControl: ULONG,
929 }}
930 pub type PSAM_DELTA_DATA = *mut SAM_DELTA_DATA;
931 FN!{stdcall PSAM_DELTA_NOTIFICATION_ROUTINE(
932     DomainSid: PSID,
933     DeltaType: SECURITY_DB_DELTA_TYPE,
934     ObjectType: SECURITY_DB_OBJECT_TYPE,
935     ObjectRid: ULONG,
936     ObjectName: PUNICODE_STRING,
937     ModifiedCount: PLARGE_INTEGER,
938     DeltaData: PSAM_DELTA_DATA,
939 ) -> NTSTATUS}
940 pub const SAM_DELTA_NOTIFY_ROUTINE: UTF8Const = UTF8Const("DeltaNotify\0");
941 EXTERN!{extern "system" {
942     fn SamRegisterObjectChangeNotification(
943         ObjectType: SECURITY_DB_OBJECT_TYPE,
944         NotificationEventHandle: HANDLE,
945     ) -> NTSTATUS;
946     fn SamUnregisterObjectChangeNotification(
947         ObjectType: SECURITY_DB_OBJECT_TYPE,
948         NotificationEventHandle: HANDLE,
949     ) -> NTSTATUS;
950 }}
951 pub const SAM_SID_COMPATIBILITY_ALL: u32 = 0;
952 pub const SAM_SID_COMPATIBILITY_LAX: u32 = 1;
953 pub const SAM_SID_COMPATIBILITY_STRICT: u32 = 2;
954 EXTERN!{extern "system" {
955     fn SamGetCompatibilityMode(
956         ObjectHandle: SAM_HANDLE,
957         Mode: *mut ULONG,
958     ) -> NTSTATUS;
959 }}
960 ENUM!{enum PASSWORD_POLICY_VALIDATION_TYPE {
961     SamValidateAuthentication = 1,
962     SamValidatePasswordChange = 2,
963     SamValidatePasswordReset = 3,
964 }}
965 STRUCT!{struct SAM_VALIDATE_PASSWORD_HASH {
966     Length: ULONG,
967     Hash: PUCHAR,
968 }}
969 pub type PSAM_VALIDATE_PASSWORD_HASH = *mut SAM_VALIDATE_PASSWORD_HASH;
970 pub const SAM_VALIDATE_PASSWORD_LAST_SET: u32 = 0x00000001;
971 pub const SAM_VALIDATE_BAD_PASSWORD_TIME: u32 = 0x00000002;
972 pub const SAM_VALIDATE_LOCKOUT_TIME: u32 = 0x00000004;
973 pub const SAM_VALIDATE_BAD_PASSWORD_COUNT: u32 = 0x00000008;
974 pub const SAM_VALIDATE_PASSWORD_HISTORY_LENGTH: u32 = 0x00000010;
975 pub const SAM_VALIDATE_PASSWORD_HISTORY: u32 = 0x00000020;
976 STRUCT!{struct SAM_VALIDATE_PERSISTED_FIELDS {
977     PresentFields: ULONG,
978     PasswordLastSet: LARGE_INTEGER,
979     BadPasswordTime: LARGE_INTEGER,
980     LockoutTime: LARGE_INTEGER,
981     BadPasswordCount: ULONG,
982     PasswordHistoryLength: ULONG,
983     PasswordHistory: PSAM_VALIDATE_PASSWORD_HASH,
984 }}
985 pub type PSAM_VALIDATE_PERSISTED_FIELDS = *mut SAM_VALIDATE_PERSISTED_FIELDS;
986 ENUM!{enum SAM_VALIDATE_VALIDATION_STATUS {
987     SamValidateSuccess = 0,
988     SamValidatePasswordMustChange = 1,
989     SamValidateAccountLockedOut = 2,
990     SamValidatePasswordExpired = 3,
991     SamValidatePasswordIncorrect = 4,
992     SamValidatePasswordIsInHistory = 5,
993     SamValidatePasswordTooShort = 6,
994     SamValidatePasswordTooLong = 7,
995     SamValidatePasswordNotComplexEnough = 8,
996     SamValidatePasswordTooRecent = 9,
997     SamValidatePasswordFilterError = 10,
998 }}
999 pub type PSAM_VALIDATE_VALIDATION_STATUS = *mut SAM_VALIDATE_VALIDATION_STATUS;
1000 STRUCT!{struct SAM_VALIDATE_STANDARD_OUTPUT_ARG {
1001     ChangedPersistedFields: SAM_VALIDATE_PERSISTED_FIELDS,
1002     ValidationStatus: SAM_VALIDATE_VALIDATION_STATUS,
1003 }}
1004 pub type PSAM_VALIDATE_STANDARD_OUTPUT_ARG = *mut SAM_VALIDATE_STANDARD_OUTPUT_ARG;
1005 STRUCT!{struct SAM_VALIDATE_AUTHENTICATION_INPUT_ARG {
1006     InputPersistedFields: SAM_VALIDATE_PERSISTED_FIELDS,
1007     PasswordMatched: BOOLEAN,
1008 }}
1009 pub type PSAM_VALIDATE_AUTHENTICATION_INPUT_ARG = *mut SAM_VALIDATE_AUTHENTICATION_INPUT_ARG;
1010 STRUCT!{struct SAM_VALIDATE_PASSWORD_CHANGE_INPUT_ARG {
1011     InputPersistedFields: SAM_VALIDATE_PERSISTED_FIELDS,
1012     ClearPassword: UNICODE_STRING,
1013     UserAccountName: UNICODE_STRING,
1014     HashedPassword: SAM_VALIDATE_PASSWORD_HASH,
1015     PasswordMatch: BOOLEAN,
1016 }}
1017 pub type PSAM_VALIDATE_PASSWORD_CHANGE_INPUT_ARG = *mut SAM_VALIDATE_PASSWORD_CHANGE_INPUT_ARG;
1018 STRUCT!{struct SAM_VALIDATE_PASSWORD_RESET_INPUT_ARG {
1019     InputPersistedFields: SAM_VALIDATE_PERSISTED_FIELDS,
1020     ClearPassword: UNICODE_STRING,
1021     UserAccountName: UNICODE_STRING,
1022     HashedPassword: SAM_VALIDATE_PASSWORD_HASH,
1023     PasswordMustChangeAtNextLogon: BOOLEAN,
1024     ClearLockout: BOOLEAN,
1025 }}
1026 pub type PSAM_VALIDATE_PASSWORD_RESET_INPUT_ARG = *mut SAM_VALIDATE_PASSWORD_RESET_INPUT_ARG;
1027 UNION!{union SAM_VALIDATE_INPUT_ARG {
1028     ValidateAuthenticationInput: SAM_VALIDATE_AUTHENTICATION_INPUT_ARG,
1029     ValidatePasswordChangeInput: SAM_VALIDATE_PASSWORD_CHANGE_INPUT_ARG,
1030     ValidatePasswordResetInput: SAM_VALIDATE_PASSWORD_RESET_INPUT_ARG,
1031 }}
1032 pub type PSAM_VALIDATE_INPUT_ARG = *mut SAM_VALIDATE_INPUT_ARG;
1033 UNION!{union SAM_VALIDATE_OUTPUT_ARG {
1034     ValidateAuthenticationOutput: SAM_VALIDATE_STANDARD_OUTPUT_ARG,
1035     ValidatePasswordChangeOutput: SAM_VALIDATE_STANDARD_OUTPUT_ARG,
1036     ValidatePasswordResetOutput: SAM_VALIDATE_STANDARD_OUTPUT_ARG,
1037 }}
1038 pub type PSAM_VALIDATE_OUTPUT_ARG = *mut SAM_VALIDATE_OUTPUT_ARG;
1039 EXTERN!{extern "system" {
1040     fn SamValidatePassword(
1041         ServerName: PUNICODE_STRING,
1042         ValidationType: PASSWORD_POLICY_VALIDATION_TYPE,
1043         InputArg: PSAM_VALIDATE_INPUT_ARG,
1044         OutputArg: *mut PSAM_VALIDATE_OUTPUT_ARG,
1045     ) -> NTSTATUS;
1046 }}
1047 ENUM!{enum SAM_GENERIC_OPERATION_TYPE {
1048     SamObjectChangeNotificationOperation = 0,
1049 }}
1050 pub type PSAM_GENERIC_OPERATION_TYPE = *mut SAM_GENERIC_OPERATION_TYPE;
1051 STRUCT!{struct SAM_OPERATION_OBJCHG_INPUT {
1052     Register: BOOLEAN,
1053     EventHandle: ULONG64,
1054     ObjectType: SECURITY_DB_OBJECT_TYPE,
1055     ProcessID: ULONG,
1056 }}
1057 pub type PSAM_OPERATION_OBJCHG_INPUT = *mut SAM_OPERATION_OBJCHG_INPUT;
1058 STRUCT!{struct SAM_OPERATION_OBJCHG_OUTPUT {
1059     Reserved: ULONG,
1060 }}
1061 pub type PSAM_OPERATION_OBJCHG_OUTPUT = *mut SAM_OPERATION_OBJCHG_OUTPUT;
1062 UNION!{union SAM_GENERIC_OPERATION_INPUT {
1063     ObjChangeIn: SAM_OPERATION_OBJCHG_INPUT,
1064 }}
1065 pub type PSAM_GENERIC_OPERATION_INPUT = *mut SAM_GENERIC_OPERATION_INPUT;
1066 UNION!{union SAM_GENERIC_OPERATION_OUTPUT {
1067     ObjChangeOut: SAM_OPERATION_OBJCHG_OUTPUT,
1068 }}
1069 pub type PSAM_GENERIC_OPERATION_OUTPUT = *mut SAM_GENERIC_OPERATION_OUTPUT;
1070 EXTERN!{extern "system" {
1071     fn SamPerformGenericOperation(
1072         ServerName: PWSTR,
1073         OperationType: SAM_GENERIC_OPERATION_TYPE,
1074         OperationIn: PSAM_GENERIC_OPERATION_INPUT,
1075         OperationOut: *mut PSAM_GENERIC_OPERATION_OUTPUT,
1076     ) -> NTSTATUS;
1077 }}
1078