xref: /illumos-gate/usr/src/uts/common/smbsrv/ndl/samrpc.ndl (revision 9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829)
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21/*
22 * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23 * Use is subject to license terms.
24 */
25
26#ifndef _MLSVC_SAM_NDL_
27#define _MLSVC_SAM_NDL_
28
29/*
30 * Security Accounts Manager RPC (SAMR) interface definition.
31 */
32
33#include "ndrtypes.ndl"
34
35/* Windows NT */
36#define SAMR_OPNUM_ConnectAnon			0x00	/* SamrConnect */
37#define SAMR_OPNUM_CloseHandle			0x01
38#define SAMR_OPNUM_SetSecObject			0x02
39#define SAMR_OPNUM_QuerySecObject		0x03
40#define SAMR_OPNUM_ShutdownSamServer		0x04	/* NotUsedOnWire */
41#define SAMR_OPNUM_LookupDomain			0x05
42#define SAMR_OPNUM_EnumLocalDomains		0x06
43#define SAMR_OPNUM_OpenDomain			0x07
44#define SAMR_OPNUM_QueryDomainInfo		0x08
45#define SAMR_OPNUM_SetDomainInfo		0x09
46#define SAMR_OPNUM_CreateDomainGroup		0x0a
47#define SAMR_OPNUM_QueryDomainGroups		0x0b
48#define SAMR_OPNUM_CreateDomainUser		0x0c
49#define SAMR_OPNUM_EnumDomainUsers		0x0d
50#define SAMR_OPNUM_CreateDomainAlias		0x0e
51#define SAMR_OPNUM_EnumDomainAliases		0x0f
52#define SAMR_OPNUM_LookupIds			0x10	/* GetAliasMembership */
53#define SAMR_OPNUM_LookupNames			0x11
54#define SAMR_OPNUM_LookupDomainIds		0x12
55#define SAMR_OPNUM_OpenGroup			0x13
56#define SAMR_OPNUM_QueryGroupInfo		0x14
57#define SAMR_OPNUM_StoreGroupInfo		0x15
58#define SAMR_OPNUM_AddGroupMember		0x16
59#define SAMR_OPNUM_DeleteDomainGroup		0x17
60#define SAMR_OPNUM_DeleteGroupMember		0x18
61#define SAMR_OPNUM_ListGroupMembers		0x19
62#define SAMR_OPNUM_SetGroupMemberAttributes	0x1a
63#define SAMR_OPNUM_OpenAlias			0x1b
64#define SAMR_OPNUM_QueryAliasInfo		0x1c
65#define SAMR_OPNUM_SetAliasInfo			0x1d
66#define SAMR_OPNUM_DeleteDomainAlias		0x1e
67#define SAMR_OPNUM_AddAliasMember		0x1f
68#define SAMR_OPNUM_DeleteAliasMember		0x20
69#define SAMR_OPNUM_QueryAliasMember		0x21
70#define SAMR_OPNUM_OpenUser			0x22
71#define SAMR_OPNUM_DeleteUser			0x23
72#define SAMR_OPNUM_QueryUserInfo		0x24
73#define SAMR_OPNUM_SetUserInfo0			0x25	/* SetUserInfo */
74#define SAMR_OPNUM_ChangeUserPassword0		0x26	/* ChangeUserPassword */
75#define SAMR_OPNUM_QueryUserGroups		0x27
76#define SAMR_OPNUM_QueryDispInfo		0x28	/* QueryDispInfo1 */
77#define	SAMR_OPNUM_GetDisplayEnumIndex		0x29
78#define	SAMR_OPNUM_TestPrivateDomainFunctions	0x2a	/* NotUsedOnWire */
79#define	SAMR_OPNUM_TestPrivateUserFunctions	0x2b	/* NotUsedOnWire */
80#define SAMR_OPNUM_GetUserPwInfo		0x2c
81
82/* Windows 2000 */
83#define	SAMR_OPNUM_RemoveMemberFromForeignDomain        0x2d
84#define	SAMR_OPNUM_QueryInfoDomain2		0x2e
85#define	SAMR_OPNUM_QueryInfoUser2		0x2f
86#define	SAMR_OPNUM_EnumDomainGroups		0x30    /* QueryDispInfo2 */
87#define	SAMR_OPNUM_GetDisplayEnumIndex2		0x31
88#define	SAMR_OPNUM_CreateUser			0x32
89#define	SAMR_OPNUM_QueryDispInfo4		0x33
90#define	SAMR_OPNUM_AddMultipleAliasMembers	0x34
91#define	SAMR_OPNUM_RemoveMultipleAliasMembers	0x35
92#define	SAMR_OPNUM_ChangeUserOemPassword	0x36
93#define SAMR_OPNUM_ChangeUserPasswd		0x37	/* UnicodePasswd */
94#define SAMR_OPNUM_GetDomainPwInfo		0x38
95#define SAMR_OPNUM_Connect			0x39	/* SamrConnect2 */
96#define SAMR_OPNUM_SetUserInfo			0x3a
97#define	SAMR_OPNUM_SetBootKeyInformation	0x3b
98#define	SAMR_OPNUM_GetBootKeyInformation	0x3c
99#define	SAMR_OPNUM_Connect2			0x3d	/* SamrConnect3 */
100#define	SAMR_OPNUM_Connect3			0x3e	/* SamrConnect4 */
101#define	SAMR_OPNUM_ChangeUserUnicodePassword3	0x3f
102
103/* Windows XP and Windows Server 2003 */
104#define	SAMR_OPNUM_Connect4			0x40	/* SamrConnect5 */
105#define	SAMR_OPNUM_RidToSid                     0x41
106#define	SAMR_OPNUM_SetDSRMPassword              0x42
107#define	SAMR_OPNUM_ValidatePassword             0x43
108
109/* Windows Vista */
110#define SAMR_OPNUM_QueryLocalizableAccountsInDomain     0x44
111#define SAMR_OPNUM_PerformGenericOperation              0x45
112
113
114/*
115 * UNION_INFO_ENT is intended to simplify adding new entries to a union.
116 * If the entry structures are named using the form samr_QueryUserInfoX,
117 * where X is the sitch_value, you can just add a single line. Note
118 * that you must also update the fixup function in mlsvc_sam.c.
119 */
120#define UNION_INFO_ENT(N,NAME) CASE(N) struct NAME##N info##N
121
122
123/*
124 * Sam account flags used when creating an account. These flags seem
125 * to be very similar to the USER_INFO_X flags (UF_XXX) in lmaccess.h
126 * but the values are different.
127 */
128#define SAMR_AF_ACCOUNTDISABLE			0x0001
129#define SAMR_AF_HOMEDIR_REQUIRED		0x0002
130#define SAMR_AF_PASSWD_NOTREQD			0x0004
131#define SAMR_AF_TEMP_DUPLICATE_ACCOUNT		0x0008
132#define SAMR_AF_NORMAL_ACCOUNT			0x0010
133#define SAMR_AF_MNS_LOGON_ACCOUNT		0x0020
134#define SAMR_AF_INTERDOMAIN_TRUST_ACCOUNT	0x0040
135#define SAMR_AF_WORKSTATION_TRUST_ACCOUNT	0x0080
136#define SAMR_AF_SERVER_TRUST_ACCOUNT		0x0100
137#define SAMR_AF_DONT_EXPIRE_PASSWD		0x0200
138#define SAMR_AF_ACCOUNT_AUTOLOCK		0x0400
139
140
141#define SAMR_AF_MACHINE_ACCOUNT_MASK	( \
142				SAMR_AF_INTERDOMAIN_TRUST_ACCOUNT \
143				| SAMR_AF_WORKSTATION_TRUST_ACCOUNT \
144				| SAMR_AF_SERVER_TRUST_ACCOUNT)
145
146#define SAMR_AF_ACCOUNT_TYPE_MASK	( \
147				SAMR_AF_TEMP_DUPLICATE_ACCOUNT \
148				| SAMR_AF_NORMAL_ACCOUNT \
149				| SAMR_AF_INTERDOMAIN_TRUST_ACCOUNT \
150				| SAMR_AF_WORKSTATION_TRUST_ACCOUNT \
151				| SAMR_AF_SERVER_TRUST_ACCOUNT)
152
153
154/*
155 * specific access rights which can be used in OpenAlias.
156 * extracted from Ethereal network analyzer
157 */
158#define SAMR_ALIAS_ACCESS_SET_INFO		0x00000010
159#define SAMR_ALIAS_ACCESS_GET_INFO		0x00000008
160#define SAMR_ALIAS_ACCESS_GET_MEMBERS		0x00000004
161#define SAMR_ALIAS_ACCESS_DEL_MEMBER		0x00000002
162#define SAMR_ALIAS_ACCESS_ADD_MEMBER		0x00000001
163
164#define	SAMR_REVISION_1			1	/* Pre Windows 2000 */
165#define	SAMR_REVISION_2			2	/* Windows 2000 */
166#define	SAMR_REVISION_3			3	/* Post Windows 2000 */
167
168/*
169 * Definition for a SID. The ndl compiler does not allow a typedef of
170 * a structure containing variable size members.
171 */
172struct samr_sid {
173	BYTE		Revision;
174	BYTE		SubAuthCount;
175	BYTE		Authority[6];
176  SIZE_IS(SubAuthCount)
177	DWORD		SubAuthority[ANY_SIZE_ARRAY];
178};
179
180
181/*
182 * SAMR definition of a security_descriptor.
183 */
184struct samr_sec_desc {
185	BYTE Revision;
186	BYTE Sbz1;
187	WORD Control;
188	struct samr_sid *owner;
189	struct samr_sid *group;
190	struct samr_sid *sacl;
191	struct samr_sid *dacl;
192};
193
194
195/*
196 * Definition for a string. The length and allosize should be set to
197 * twice the string length (i.e. strlen(str) * 2). The runtime code
198 * will perform the appropriate string to a wide-char conversions,
199 * so str should point to a regular char * string.
200 */
201struct samr_string {
202	WORD		length;
203	WORD		allosize;
204	LPTSTR		str;
205};
206typedef struct samr_string samr_string_t;
207
208
209/*
210 * Alternative varying/conformant string definition - for
211 * non-null terminated strings. This definition must match
212 * ndr_vcbuf_t.
213 */
214struct samr_vcb {
215	/*
216	 * size_is (actually a copy of length_is) will
217	 * be inserted here by the marshalling library.
218	 */
219	DWORD vc_first_is;
220	DWORD vc_length_is;
221  SIZE_IS(vc_length_is)
222	WORD buffer[ANY_SIZE_ARRAY];
223};
224
225struct samr_vcbuf {
226	WORD wclen;
227	WORD wcsize;
228	struct samr_vcb *vcb;
229};
230typedef struct samr_vcbuf samr_vcbuf_t;
231
232CONTEXT_HANDLE(samr_handle) samr_handle_t;
233
234/*
235 * A long long, i.e. 64-bit, value.
236 */
237struct samr_quad {
238	DWORD low;
239	DWORD high;
240};
241typedef struct samr_quad samr_quad_t;
242
243
244/*
245 ***********************************************************************
246 * ConnectAnon. It looks like the SAM handle is identical to an LSA
247 * handle. See Connect.
248 ***********************************************************************
249 */
250OPERATION(SAMR_OPNUM_ConnectAnon)
251struct samr_ConnectAnon {
252	IN	DWORD *servername;
253	IN	DWORD access_mask;
254	OUT	samr_handle_t handle;
255	OUT	DWORD status;
256};
257
258
259/*
260 ***********************************************************************
261 * Connect. I'm not sure what the difference is between Connect and
262 * ConnectAnon but this call seems to work better than ConnectAnon.
263 ***********************************************************************
264 */
265OPERATION(SAMR_OPNUM_Connect)
266struct samr_Connect {
267	IN	LPTSTR servername;
268	IN	DWORD access_mask;
269	OUT	samr_handle_t handle;
270	OUT	DWORD status;
271};
272
273
274/*
275 ***********************************************************************
276 * SamrConnect3. A new form of connect first seen with Windows 2000.
277 * A new field has been added to the input request. Value: 0x00000002.
278 * I haven't looked at the Win2K response yet to see if it differs
279 * from SAMR_OPNUM_Connect.
280 ***********************************************************************
281 */
282OPERATION(SAMR_OPNUM_Connect3)
283struct samr_Connect3 {
284	IN	LPTSTR servername;
285	IN	DWORD revision;
286	IN	DWORD access_mask;
287	OUT	samr_handle_t handle;
288	OUT	DWORD status;
289};
290
291
292/*
293 ***********************************************************************
294 * SamrConnect4. A new form of connect first seen with Windows XP.
295 * The server name is the fully qualified domain name, i.e.
296 *	\\server.sun.com.
297 *
298 * [in]  DWORD	 InVersion,
299 * [in]  [switch_is(InVersion)]    samr_revision_info *InRevisionInfo
300 * [out] DWORD	 *OutVersion
301 * [out] [switch_is(*OutVersion)] *samr_revision_info *OutRevisionInfo
302 *
303 * SupportedFeatures (see notes in [MS-SAMR]
304 *	0x00000001	RID values returned from the server must not be
305 *			concatenated with the domain SID.
306 *	0x00000002	Reserved
307 *	0x00000004	Reserved
308 ***********************************************************************
309 */
310struct samr_revision_info1 {
311	DWORD revision;
312	DWORD supported_features;
313};
314typedef struct samr_revision_info1 samr_revision_info1_t;
315
316union samr_revision_info {
317	UNION_INFO_ENT(1,samr_revision_info);
318	DEFAULT	char *nullptr;
319};
320
321OPERATION(SAMR_OPNUM_Connect4)
322struct samr_Connect4 {
323	IN		LPTSTR servername;
324	IN		DWORD access_mask;
325	INOUT	DWORD unknown2_00000001;
326	INOUT	DWORD unknown3_00000001;
327	INOUT	DWORD unknown4_00000003;
328	INOUT	DWORD unknown5_00000000;
329	OUT		samr_handle_t handle;
330	OUT		DWORD status;
331};
332
333
334/*
335 ***********************************************************************
336 * CloseHandle closes an association with the SAM. Using the same
337 * structure as the LSA seems to work.
338 ***********************************************************************
339 */
340OPERATION(SAMR_OPNUM_CloseHandle)
341struct samr_CloseHandle {
342	IN	samr_handle_t handle;
343	OUT	samr_handle_t result_handle;
344	OUT	DWORD status;
345};
346
347
348/*
349 ***********************************************************************
350 * LookupDomain: lookup up the domain SID.
351 ***********************************************************************
352 */
353OPERATION(SAMR_OPNUM_LookupDomain)
354struct samr_LookupDomain {
355	IN	samr_handle_t handle;
356	IN	samr_string_t domain_name;
357	OUT struct samr_sid *sid;
358	OUT	DWORD status;
359};
360
361
362/*
363 ***********************************************************************
364 * EnumLocalDomain
365 *
366 * This looks like a request to get the local domains supported by a
367 * remote server. NT always seems to return 2 domains: the local
368 * domain (hostname) and the Builtin domain.
369 *
370 * The max_length field is set to 0x2000.
371 * Enum_context is set to 0 in the request and set to entries_read in
372 * the reply. Like most of these enums, total_entries is the same as
373 * entries_read.
374 ***********************************************************************
375 */
376struct samr_LocalDomainEntry {
377	DWORD unknown;
378	samr_string_t name;
379};
380
381struct samr_LocalDomainInfo {
382	DWORD entries_read;
383  SIZE_IS(entries_read)
384	struct samr_LocalDomainEntry *entry;
385};
386
387
388OPERATION(SAMR_OPNUM_EnumLocalDomains)
389struct samr_EnumLocalDomain {
390	IN		samr_handle_t handle;
391	INOUT	DWORD enum_context;
392	IN		DWORD max_length;
393	OUT		struct samr_LocalDomainInfo *info;
394	OUT		DWORD total_entries;
395	OUT		DWORD status;
396};
397
398
399/*
400 ***********************************************************************
401 * OpenDomain
402 *
403 * Open a specific domain within the SAM. From this I assume that each
404 * SAM can handle multiple domains so you need to identify the one with
405 * which you want to work. Working with a domain handle does appear to
406 * offer the benefit that you can then use RIDs instead of full SIDs,
407 * which simplifies things a bit. The domain handle can be used to get
408 * user and group handles.
409 ***********************************************************************
410 */
411OPERATION(SAMR_OPNUM_OpenDomain)
412struct samr_OpenDomain {
413	IN	samr_handle_t handle;
414	IN	DWORD access_mask;
415	IN REFERENCE struct samr_sid *sid;
416	OUT	samr_handle_t domain_handle;
417	OUT	DWORD status;
418};
419
420
421/*
422 ***********************************************************************
423 * QueryDomainInfo
424 *
425 * Windows 95 Server Manager sends requests for levels 6 and 7 when
426 * the services menu item is selected.
427 ***********************************************************************
428 */
429#define SAMR_QUERY_DOMAIN_INFO_2		2
430#define SAMR_QUERY_DOMAIN_INFO_6		6
431#define SAMR_QUERY_DOMAIN_INFO_7		7
432
433
434struct samr_QueryDomainInfo2 {
435	DWORD unknown1;			/* 00 00 00 00 */
436	DWORD unknown2;			/* 00 00 00 80 */
437	samr_string_t s1;
438	samr_string_t domain;
439	samr_string_t s2;
440	DWORD sequence_num;		/* 2B 00 00 00 */
441	DWORD unknown3;			/* 00 00 00 00 */
442	DWORD unknown4;			/* 01 00 00 00 */
443	DWORD unknown5;			/* 03 00 00 00 */
444	DWORD unknown6;			/* 01 */
445	DWORD num_users;
446	DWORD num_groups;
447	DWORD num_aliases;
448};
449
450
451struct samr_QueryDomainInfo6 {
452	DWORD unknown1;			/* 00 00 00 00 */
453	DWORD unknown2;			/* B0 7F 14 00 */
454	DWORD unknown3;			/* 00 00 00 00 */
455	DWORD unknown4;			/* 00 00 00 00 */
456	DWORD unknown5;			/* 00 00 00 00 */
457};
458
459
460struct samr_QueryDomainInfo7 {
461	DWORD unknown1;			/* 03 00 00 00 */
462};
463
464
465union samr_QueryDomainInfo_ru {
466	UNION_INFO_ENT(2,samr_QueryDomainInfo);
467	UNION_INFO_ENT(6,samr_QueryDomainInfo);
468	UNION_INFO_ENT(7,samr_QueryDomainInfo);
469	DEFAULT	char *nullptr;
470};
471
472struct samr_QueryDomainInfoRes {
473	WORD switch_value;
474	SWITCH(switch_value)
475		union samr_QueryDomainInfo_ru ru;
476};
477
478OPERATION(SAMR_OPNUM_QueryDomainInfo)
479struct samr_QueryDomainInfo {
480	IN	samr_handle_t domain_handle;
481	IN	WORD info_level;
482	OUT	struct samr_QueryDomainInfoRes *info;
483	OUT	DWORD status;
484};
485
486#define SAMR_QUERY_ALIAS_INFO_1			1
487#define SAMR_QUERY_ALIAS_INFO_3			3
488
489
490struct samr_QueryAliasInfo1 {
491	WORD level;
492	samr_string_t name;
493	DWORD unknown;
494	samr_string_t desc;
495};
496
497struct samr_QueryAliasInfo3 {
498	WORD level;
499	samr_string_t desc;
500};
501
502union samr_QueryAliasInfo_ru {
503	UNION_INFO_ENT(1,samr_QueryAliasInfo);
504	UNION_INFO_ENT(3,samr_QueryAliasInfo);
505	DEFAULT	char *nullptr;
506};
507
508struct samr_QueryAliasInfoRes {
509	DWORD address;
510	WORD switch_value;
511	SWITCH(switch_value)
512		union samr_QueryAliasInfo_ru ru;
513};
514
515OPERATION(SAMR_OPNUM_QueryAliasInfo)
516struct samr_QueryAliasInfo {
517	IN	samr_handle_t alias_handle;
518	IN	WORD level;
519	OUT DWORD address;
520  SWITCH (level)
521	OUT	union samr_QueryAliasInfo_ru ru;
522	OUT	DWORD status;
523};
524
525OPERATION(SAMR_OPNUM_CreateDomainAlias)
526struct samr_CreateDomainAlias {
527	IN	samr_handle_t domain_handle;
528	IN	samr_string_t alias_name;
529	IN	DWORD access_mask;
530	OUT samr_handle_t alias_handle;
531	OUT	DWORD rid;
532	OUT	DWORD status;
533};
534
535OPERATION(SAMR_OPNUM_SetAliasInfo)
536struct samr_SetAliasInfo {
537	IN	samr_handle_t alias_handle;
538	IN	WORD level;
539	/* TBD */
540	OUT	DWORD status;
541};
542
543OPERATION(SAMR_OPNUM_DeleteDomainAlias)
544struct samr_DeleteDomainAlias {
545	IN	samr_handle_t alias_handle;
546	OUT	DWORD status;
547};
548
549OPERATION(SAMR_OPNUM_OpenAlias)
550struct samr_OpenAlias {
551	IN	samr_handle_t domain_handle;
552	IN	DWORD access_mask;
553	IN	DWORD rid;
554	OUT samr_handle_t alias_handle;
555	OUT	DWORD status;
556};
557
558struct name_rid {
559	DWORD rid;
560	samr_string_t name;
561};
562
563struct aliases_info {
564	DWORD count;
565	DWORD address;
566	SIZE_IS(count)
567	struct name_rid info[ANY_SIZE_ARRAY];
568};
569
570OPERATION(SAMR_OPNUM_EnumDomainAliases)
571struct samr_EnumDomainAliases {
572	IN	samr_handle_t domain_handle;
573	IN	DWORD resume_handle;
574	IN	DWORD mask;
575	OUT	DWORD out_resume;
576	OUT struct aliases_info *aliases;
577	OUT DWORD entries;
578	OUT	DWORD status;
579};
580
581struct user_acct_info {
582	DWORD index;
583	DWORD rid;
584	DWORD ctrl;
585	samr_string_t name;
586	samr_string_t fullname;
587	samr_string_t desc;
588};
589
590struct user_disp_info {
591	OUT DWORD total_size;
592	OUT DWORD returned_size;
593	OUT WORD switch_value;
594	DWORD count;
595	SIZE_IS(count)
596	struct user_acct_info *acct;
597};
598
599OPERATION(SAMR_OPNUM_QueryDispInfo)
600struct samr_QueryDispInfo {
601	IN	samr_handle_t domain_handle;
602	IN	WORD level;
603	IN	DWORD start_idx;
604	IN	DWORD max_entries;
605	IN	DWORD pref_maxsize;
606	OUT struct user_disp_info users;
607	OUT	DWORD status;
608};
609
610struct group_acct_info {
611	DWORD index;
612	DWORD rid;
613	DWORD ctrl;
614	samr_string_t name;
615	samr_string_t desc;
616};
617
618struct group_disp_info {
619	DWORD count;
620	/* right now we just need one entry */
621	struct group_acct_info acct[1];
622};
623
624OPERATION(SAMR_OPNUM_EnumDomainGroups)
625struct samr_EnumDomainGroups {
626	IN	samr_handle_t domain_handle;
627	IN	WORD level;
628	IN	DWORD start_idx;
629	IN	DWORD max_entries;
630	IN	DWORD pref_maxsize;
631	OUT DWORD total_size;
632	OUT DWORD returned_size;
633	OUT WORD switch_value;
634	OUT DWORD count;
635	OUT struct group_disp_info *groups;
636	OUT	DWORD status;
637};
638
639/*
640 ***********************************************************************
641 * OpenUser
642 *
643 * Input must be a domain handle obtained via SAMR_OPNUM_OpenDomain,
644 * an access mask and the appropriate user rid. The output will be a
645 * handle for use with the specified user.
646 ***********************************************************************
647 */
648OPERATION(SAMR_OPNUM_OpenUser)
649struct samr_OpenUser {
650	IN	samr_handle_t handle;
651	IN	DWORD access_mask;
652	IN	DWORD rid;
653	OUT	samr_handle_t user_handle;
654	OUT	DWORD status;
655};
656
657
658/*
659 ***********************************************************************
660 * DeleteUser
661 ***********************************************************************
662 */
663OPERATION(SAMR_OPNUM_DeleteUser)
664struct samr_DeleteUser {
665	INOUT	samr_handle_t user_handle;
666	OUT	DWORD status;
667};
668
669
670/*
671 ***********************************************************************
672 * QueryUserInfo
673 *
674 * Provides various pieces of information on a specific user (see
675 * SAM_Q_QUERY_USERINFO and SAM_R_QUERY_USERINFO). The handle must
676 * be a valid SAM user handle.
677 *
678 * QueryUserInfo (
679 *	IN samr_handle_t user_handle,
680 *	IN WORD switch_value,
681 *	OUT union switch(switch_value) {
682 *		case 1: struct QueryUserInfo1 *info1;
683 *	} bufptr,
684 *	OUT DWORD status
685 * )
686 *
687 * The cases identified so far are:
688 *
689 * 1 = username, fullname, description and some other stuff.
690 * 2 = unknown
691 * 3 = large structure containing user rid, group rid, username
692 *     and fullname.
693 * 4 = unknown
694 * 5 = large structure (like 3) containing user rid, group rid,
695 *     username, fullname and description.
696 * 6 = username and fullname
697 * 7 = username
698 * 8 = fullname
699 * 9 = group rid
700 * 16 = used after creating a new account
701 *
702 * Due to an ndrgen bug, a function must be provided to to patch the
703 * offsets used by the unmarshalling code at runtime.  In order to
704 * simplify things it is useful to use a naming convention that
705 * indicates the switch value for each structure.
706 *
707 ***********************************************************************
708 */
709
710
711#define SAMR_QUERY_USER_INFO_1			1
712#define SAMR_QUERY_USER_UNAME_AND_FNAME		6
713#define SAMR_QUERY_USER_USERNAME		7
714#define SAMR_QUERY_USER_FULLNAME		8
715#define SAMR_QUERY_USER_GROUPRID		9
716#define SAMR_QUERY_USER_UNKNOWN16		16
717
718
719struct samr_QueryUserInfo1 {
720	samr_string_t username;
721	samr_string_t fullname;
722	DWORD group_rid;
723	samr_string_t description;
724	samr_string_t unknown;
725};
726
727
728struct samr_QueryUserInfo6 {
729	samr_string_t username;
730	samr_string_t fullname;
731};
732
733struct samr_QueryUserInfo7 {
734	samr_string_t username;
735};
736
737
738struct samr_QueryUserInfo8 {
739	samr_string_t fullname;
740};
741
742
743struct samr_QueryUserInfo9 {
744	DWORD group_rid;
745};
746
747
748struct samr_QueryUserInfo16 {
749	DWORD unknown;
750};
751
752
753union QueryUserInfo_result_u {
754	UNION_INFO_ENT(1,samr_QueryUserInfo);
755	UNION_INFO_ENT(6,samr_QueryUserInfo);
756	UNION_INFO_ENT(7,samr_QueryUserInfo);
757	UNION_INFO_ENT(8,samr_QueryUserInfo);
758	UNION_INFO_ENT(9,samr_QueryUserInfo);
759	UNION_INFO_ENT(16,samr_QueryUserInfo);
760	DEFAULT	char *nullptr;
761};
762
763
764/*
765 * This structure needs to be declared, even though it can't be used in
766 * samr_QueryUserInfo, in order to get the appropriate size to calculate
767 * the correct fixup offsets.  If ndrgen did the right thing,
768 * QueryUserInfo_result would be one of the out parameters.  However, if
769 * we do it that way, the switch_value isn't known early enough to do
770 * the fixup calculation.  So it all has to go in samr_QueryUserInfo.
771 */
772struct QueryUserInfo_result {
773	DWORD address;
774	WORD switch_value;
775	SWITCH(switch_value)
776		union QueryUserInfo_result_u ru;
777};
778
779
780OPERATION(SAMR_OPNUM_QueryUserInfo)
781struct samr_QueryUserInfo {
782	IN	samr_handle_t user_handle;
783	IN	WORD switch_value;
784	/*
785	 * Can't use this form because we need to include members explicitly.
786	 * OUT	struct QueryUserInfo_result result;
787	 */
788	OUT	DWORD address;
789	OUT	WORD switch_index;
790  SWITCH(switch_value)
791	OUT	union QueryUserInfo_result_u ru;
792	OUT	DWORD status;
793};
794
795
796/*
797 ***********************************************************************
798 * QueryUserGroups
799 ***********************************************************************
800 */
801struct samr_UserGroups {
802	DWORD rid;
803	DWORD attr;
804};
805
806
807struct samr_UserGroupInfo {
808	DWORD n_entry;
809  SIZE_IS(n_entry)
810	struct samr_UserGroups *groups;
811};
812
813
814OPERATION(SAMR_OPNUM_QueryUserGroups)
815struct samr_QueryUserGroups {
816	IN	samr_handle_t user_handle;
817	OUT struct samr_UserGroupInfo *info;
818	OUT	DWORD status;
819};
820
821
822/*
823 ***********************************************************************
824 * LookupName
825 ***********************************************************************
826 */
827struct samr_LookupNameTable {
828	DWORD n_entry;
829  SIZE_IS(n_entry)
830	samr_string_t names[ANY_SIZE_ARRAY];
831};
832
833
834struct samr_LookupRidTable {
835	DWORD n_entry;
836  SIZE_IS(n_entry)
837	DWORD *rid;
838};
839
840struct samr_RidType {
841	DWORD n_entry;
842  SIZE_IS(n_entry)
843	DWORD *rid_type;
844};
845
846
847OPERATION(SAMR_OPNUM_LookupNames)
848struct samr_LookupNames {
849	IN	samr_handle_t handle;
850	IN	DWORD n_entry;
851	IN	DWORD max_n_entry;
852	IN	DWORD index;
853	IN	DWORD total;
854	IN	samr_string_t name;
855	OUT	struct samr_LookupRidTable rids;
856	OUT	struct samr_RidType rid_types;
857	OUT	DWORD status;
858};
859
860
861/*
862 ***********************************************************************
863 * OpenGroup
864 *
865 * Input must be a domain handle obtained via SAMR_OPNUM_OpenDomain,
866 * an access mask and the appropriate group rid. The output will be a
867 * handle for use with the specified group.
868 ***********************************************************************
869 */
870OPERATION(SAMR_OPNUM_OpenGroup)
871struct samr_OpenGroup {
872	IN	samr_handle_t handle;
873	IN	DWORD access_mask;
874	IN	DWORD rid;
875	OUT	samr_handle_t group_handle;
876	OUT	DWORD status;
877};
878
879
880/*
881 ***********************************************************************
882 * QueryGroupInfo
883 *
884 * Input must be a group handle obtained via SAMR_OPNUM_OpenGroup,
885 * an access mask and the appropriate group rid. The output will
886 * be a handle for use with the specified group.
887 ***********************************************************************
888 */
889struct samr_QueryGroupInfo1 {
890	samr_string_t groupname;
891};
892
893
894union samr_QueryGroupInfo_result_u {
895	UNION_INFO_ENT(1,samr_QueryGroupInfo);
896	DEFAULT	char *nullptr;
897};
898
899
900struct samr_QueryGroupInfo_result {
901	DWORD address;
902	WORD switch_index;
903  SWITCH(switch_index)
904	union samr_QueryGroupInfo_result_u ru;
905};
906
907
908OPERATION(SAMR_OPNUM_QueryGroupInfo)
909struct samr_QueryGroupInfo {
910	IN	samr_handle_t group_handle;
911	IN	DWORD switch_value;
912	OUT	DWORD address;
913	OUT	WORD switch_index;
914  SWITCH(switch_index)
915	OUT	union samr_QueryGroupInfo_result_u ru;
916	OUT	DWORD status;
917};
918
919
920/*
921 ***********************************************************************
922 * StoreGroupInfo
923 *
924 * This definition is mostly just a place holder in case this is useful
925 * in the future. Note that it may not be correct. The information is
926 * from a netmon trace captured when I added a group description. I
927 * haven't implemented it because we don't have to update anything on
928 * the PDC. The description should almost certainly be in a separate
929 * structure.
930 ***********************************************************************
931 */
932OPERATION(SAMR_OPNUM_StoreGroupInfo)
933struct samr_StoreGroupInfo {
934	IN	samr_handle_t group_handle;
935	IN	DWORD switch_value;
936	IN	samr_string_t group_description;
937	OUT	DWORD status;
938};
939
940
941/*
942 ***********************************************************************
943 * Request 0x2c is a user request. The only parameter is a user handle.
944 * The response is 12 bytes of the form:
945 *		unknown: 00 00 BB 01 (443)
946 *		unknown: 00 00 00 00
947 *		status:  00 00 00 00
948 * RPC book lists this as GetUsrDomPwInfo.
949 ***********************************************************************
950 */
951struct samr_UserPwInfo {
952	WORD	unknown1;
953	WORD	unknown2;
954	DWORD	unknown3;
955};
956
957
958OPERATION(SAMR_OPNUM_GetUserPwInfo)
959struct samr_GetUserPwInfo {
960	IN	samr_handle_t user_handle;
961	OUT struct samr_UserPwInfo pw_info;
962	OUT	DWORD status;
963};
964
965
966/*
967 ***********************************************************************
968 * CreateUser
969 *
970 * Create a user in the domain specified by the domain handle. The
971 * domain handle is obtained obtained via SAMR_OPNUM_OpenDomain.
972 * DesiredAccess: 0xe00500b0.
973 * The output will be a handle for use with the specified user and the
974 * user's RID. I think the RID may be a unique pointer (it can be null).
975 ***********************************************************************
976 */
977OPERATION(SAMR_OPNUM_CreateUser)
978struct samr_CreateUser {
979	IN	samr_handle_t handle;
980	IN	samr_vcbuf_t username;
981	IN	DWORD account_flags;
982	IN	DWORD desired_access;
983	OUT	samr_handle_t user_handle;
984	OUT	DWORD maybe_ptr;
985	OUT	DWORD rid;
986	OUT	DWORD status;
987};
988
989
990/*
991 ***********************************************************************
992 * ChangeUserPasswd
993 ***********************************************************************
994 */
995struct samr_newpasswd {
996	BYTE data[516];
997};
998
999
1000struct samr_oldpasswd {
1001	BYTE data[16];
1002};
1003
1004
1005OPERATION(SAMR_OPNUM_ChangeUserPasswd)
1006struct samr_ChangeUserPasswd {
1007	IN	LPTSTR servername;
1008	IN	LPTSTR username;
1009	IN	struct samr_newpasswd *nt_newpasswd;
1010	IN	struct samr_oldpasswd *nt_oldpasswd;
1011	IN	struct samr_newpasswd *lm_newpasswd;
1012	IN	struct samr_oldpasswd *lm_oldpasswd;
1013	OUT	DWORD status;
1014};
1015
1016
1017/*
1018 ***********************************************************************
1019 * GetDomainPwInfo
1020 ***********************************************************************
1021 */
1022OPERATION(SAMR_OPNUM_GetDomainPwInfo)
1023struct samr_GetDomainPwInfo {
1024	IN	LPTSTR servername;
1025	OUT	WORD unknown0;
1026	OUT	WORD unknown1;
1027	OUT	WORD unknown2;
1028	OUT	DWORD status;
1029};
1030
1031
1032/*
1033 ***********************************************************************
1034 * SetUserInfo
1035 *
1036 *	+++ 20 byte user handle and the union switch_value +++
1037 *	00 00 00 00 77 F2 DD D5 66 48 D4 11 AD 5F D1 CD
1038 *	18 43 7A DF 17 00 17 00
1039 *
1040 *	+++ 14 dwords (56 bytes) of zeros +++
1041 *	00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1042 *	00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1043 *	00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1044 *	00 00 00 00 00 00 00 00
1045 *
1046 *	+++ 9 sets of something - 72 bytes +++
1047 *	00 00 02 00 D0 04 8A 77
1048 *	00 00 02 00 D0 04 8A 77
1049 *	00 00 02 00 D0 04 8A 77
1050 *	00 00 02 00 D0 04 8A 77
1051 *	00 00 02 00 D0 04 8A 77
1052 *	00 00 02 00 D0 04 8A 77
1053 *	00 00 02 00 D0 04 8A 77
1054 *	00 00 02 00 D0 04 8A 77
1055 *	00 00 02 00 D0 04 8A 77
1056 *
1057 *	+++ 9 DWORD zeros +++
1058 *	00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1059 *	00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1060 *	00 00 00 00
1061 *
1062 *	+++ miscellaneous +++
1063 *	01 02 00 00
1064 *	80 00 00 00
1065 *	FA 27 F8 09
1066 *	A8 00 00 00 70 F1 14 00
1067 *	00 00 00 00 00 00 00 00 00 00 00 00
1068 *
1069 *	+++ encrypted password buffer - 512 bytes +++
1070 *	76 68 E8 AA 23 4F 62 C4 81 4E 30 B8 92 29 66 B9
1071 *	12 FF 3A 84 82 3A 55 0F C7 18 EA 56 86 50 D7 C5
1072 *	43 BA 9C F8 32 D4 E0 15 74 A1 6F E1 59 C2 F2 95
1073 *	53 A9 F2 68 9F 7F 29 B9 88 4C 65 A5 C1 DC 0B 44
1074 *	B8 3C ED 74 D1 6A F7 09 66 97 94 6B 2C 3A A5 88
1075 *	39 34 C6 FE 24 59 30 2D CF 6D 7F D5 EC B1 9A 84
1076 *	E6 57 96 29 40 32 FB 62 9D 93 E2 BE D8 A3 74 88
1077 *	8B 85 BC A0 76 D6 C9 DB 8C AF 81 BD 8A F0 08 8D
1078 *	23 B0 52 FD 69 DE EF A1 36 E5 30 19 BD DA 67 A3
1079 *	81 BD 3F D0 2A A2 8F 60 62 B0 8D 34 9E A4 4F 20
1080 *	4E 79 93 82 58 A8 E5 6F 7A DC 12 13 33 E6 74 02
1081 *	4C 32 F9 FC 1A E1 C5 0D E2 CC 36 8D FC 72 87 DD
1082 *	6C 44 E3 6F 4B FD 46 10 08 89 E5 64 B8 27 14 83
1083 *	E7 08 DE CF 69 C7 E1 40 63 DF CB 67 95 73 03 1B
1084 *	CA 99 E1 1B 53 2A 89 6B 30 39 CD 5C DF A0 8A 1C
1085 *	4E 50 74 7C 6D 3D E7 EA E9 B2 97 DD 38 7B DA EC
1086 *	1A AD DA CE C4 58 9B 29 F3 6D 30 70 4E 63 6D 84
1087 *	DB DC 5B CD 9A 4E 57 9C E4 65 5D 4F 76 E3 C7 52
1088 *	8B 3B 20 0A 3B 4C 4B B1 2E 5B 4D AB BA 2F 45 6A
1089 *	CA 17 AD 9F C0 B2 07 FB 56 7F E4 3F 9F D4 C6 8C
1090 *	A1 05 BF 53 42 1E 67 F4 57 54 E3 2C 38 CF E1 94
1091 *	75 69 F7 4E 5C 74 CC B3 FD EF 73 3F D5 28 22 EC
1092 *	9B 40 E1 1D 65 44 7C BB 69 88 57 10 05 3A C5 48
1093 *	8E 4F 77 DB 1A 5C 49 9C D5 06 00 AC 79 BC 7E 89
1094 *	B0 01 66 70 88 A2 E5 DF 96 DC 75 98 10 12 45 02
1095 *	33 35 6C DF 74 8B 14 2F 26 C6 FD 7A B4 D0 A6 7D
1096 *	DE 2B 13 44 EF 34 46 4D 9D 3E C3 75 BC 11 B4 41
1097 *	27 58 25 1E AF AA F0 BB DA 27 7A 1E AE 81 1A 78
1098 *	44 19 DE FC C4 7C 4E 32 44 F7 57 2A 41 A2 85 DC
1099 *	C0 AD 5D 6B 58 FD 2E 75 25 B9 F2 B6 19 82 E5 0E
1100 *	B6 69 0D C1 27 A9 B6 40 A6 50 49 E5 CB 17 98 65
1101 *	88 18 CA E4 1D 2E 20 F7 DE 8E 7D F2 9D A5 6B CD
1102 *
1103 *	D6 79 45 71
1104 *
1105 *	+++ table of 9 things +++
1106 *	01 00 00 00 00 00 00 00 00 00 00 00
1107 *	01 00 00 00 00 00 00 00 00 00 00 00
1108 *	01 00 00 00 00 00 00 00 00 00 00 00
1109 *	01 00 00 00 00 00 00 00 00 00 00 00
1110 *	01 00 00 00 00 00 00 00 00 00 00 00
1111 *	01 00 00 00 00 00 00 00 00 00 00 00
1112 *	01 00 00 00 00 00 00 00 00 00 00 00
1113 *	01 00 00 00 00 00 00 00 00 00 00 00
1114 *	01 00 00 00 00 00 00 00 00 00 00 00
1115 *
1116 *	+++ miscellaneous +++
1117 *	EC 04 00 00 00 00 00 00 15 00 00 00
1118 *	FF FF FF FF FF FF FF FF FF FF FF FF
1119 *	FF FF FF FF FF FF FF FF FF
1120 *
1121 ***********************************************************************
1122 */
1123
1124#define SAMR_SET_USER_INFO_23		23
1125#define SAMR_SET_USER_DATA_SZ		516
1126
1127#define SAMR_MINS_PER_WEEK		10080
1128#define SAMR_HOURS_PER_WEEK		168
1129
1130#define SAMR_HOURS_MAX_SIZE		(SAMR_MINS_PER_WEEK / 8)
1131#define SAMR_HOURS_SET_LEN(LEN)		((LEN) / 8)
1132#define SAMR_SET_USER_HOURS_SZ		21
1133
1134
1135struct samr_sd {
1136	DWORD length;
1137  SIZE_IS(length)
1138	BYTE *data;
1139};
1140
1141
1142/*
1143 * There is some sort of logon bitmap structure in here, which I
1144 * think is a varying and conformant array, i.e.
1145 *
1146 *	struct samr_logon_hours {
1147 *      DWORD size_is;		(0x04ec)
1148 *      DWORD first_is;		(zero)
1149 *      DWORD length_is;	(0xa8)
1150 *      BYTE bitmap[21];
1151 *  };
1152 *
1153 *	struct samr_logon_info {
1154 *		DWORD length;
1155 *	SIZE_IS(length / 8)
1156 *		struct samr_logon_hours *hours;
1157 *	};
1158 *
1159 * There are 10080 minutes/week => 10080/8 = 1260 (0x04EC).
1160 * So size_is is set as some sort of maximum.
1161 *
1162 * There are 168 hours/week => 168/8 = 21 (0xA8). Since there are 21
1163 * bytes (all set to 0xFF), this is is probably the default setting.
1164 *
1165 * ndrgen has a problem with complex [size_is] statements. For now,
1166 * we can try to fake it using two separate components.
1167 */
1168struct samr_logon_hours {
1169	DWORD size;
1170	DWORD first;
1171	DWORD length;
1172	BYTE bitmap[SAMR_SET_USER_HOURS_SZ];
1173};
1174
1175
1176struct samr_logon_info {
1177	DWORD units;
1178	DWORD hours;
1179};
1180
1181
1182struct samr_oem_password {
1183	BYTE password[512];
1184	DWORD length;
1185};
1186
1187
1188struct samr_SetUserInfo23 {
1189	samr_quad_t logon_time;			/* 00 00 00 00 00 00 00 00 */
1190	samr_quad_t logoff_time;		/* 00 00 00 00 00 00 00 00 */
1191	samr_quad_t kickoff_time;		/* 00 00 00 00 00 00 00 00 */
1192	samr_quad_t passwd_last_set_time;	/* 00 00 00 00 00 00 00 00 */
1193	samr_quad_t passwd_can_change_time;	/* 00 00 00 00 00 00 00 00 */
1194	samr_quad_t passwd_must_change_time;	/* 00 00 00 00 00 00 00 00 */
1195
1196	samr_vcbuf_t user_name;			/* 00 00 00 00 00 00 00 00 */
1197	samr_vcbuf_t full_name;			/* 00 00 02 00 D0 04 8A 77 */
1198	samr_vcbuf_t home_dir;			/* 00 00 02 00 D0 04 8A 77 */
1199	samr_vcbuf_t home_drive;		/* 00 00 02 00 D0 04 8A 77 */
1200	samr_vcbuf_t logon_script;		/* 00 00 02 00 D0 04 8A 77 */
1201	samr_vcbuf_t profile_path;		/* 00 00 02 00 D0 04 8A 77 */
1202	samr_vcbuf_t acct_desc;			/* 00 00 02 00 D0 04 8A 77 */
1203	samr_vcbuf_t workstations;		/* 00 00 02 00 D0 04 8A 77 */
1204	samr_vcbuf_t unknown1;			/* 00 00 02 00 D0 04 8A 77 */
1205	samr_vcbuf_t unknown2;			/* 00 00 02 00 D0 04 8A 77 */
1206	samr_vcbuf_t lm_password;		/* 00 00 00 00 00 00 00 00 */
1207	samr_vcbuf_t nt_password;		/* 00 00 00 00 00 00 00 00 */
1208	samr_vcbuf_t unknown3;			/* 00 00 00 00 00 00 00 00 */
1209
1210	struct samr_sd sd;			/* 00 00 00 00 00 00 00 00 */
1211	DWORD user_rid;				/* 00 00 00 00 */
1212	DWORD group_rid;			/* 01 02 00 00 */
1213	DWORD acct_info;			/* 80 00 00 00 */
1214	DWORD flags;				/* FA 27 F8 09 */
1215	struct samr_logon_info logon_info;  /* A8 00 00 00 70 F1 14 00->0xFF */
1216	/*
1217	 * The following 12 bytes are encoded in Ethereal as:
1218	 *
1219	 *	WORD bad_pwd_count;
1220	 *	WORD logon_count;
1221	 *
1222	 *	WORD country;			(default 0)
1223	 *	WORD codepage;
1224	 *
1225	 *	BYTE nt_pwd_set;
1226	 *	BYTE lm_pwd_set;
1227	 *	BYTE expired_flag;
1228	 *	BYTE unknown_char;
1229	 */
1230	DWORD unknown4_zero;			/* 00 00 00 00 */
1231	DWORD unknown5_zero;			/* 00 00 00 00 */
1232	DWORD unknown6_zero;			/* 00 00 00 00 */
1233	BYTE password[SAMR_SET_USER_DATA_SZ];
1234};
1235
1236
1237union samr_SetUserInfo_u {
1238	UNION_INFO_ENT(23,samr_SetUserInfo);
1239	DEFAULT	char *nullptr;
1240};
1241
1242
1243struct samr_SetUserInfo_s {
1244	WORD index;
1245	WORD switch_value;
1246  SWITCH(switch_value)
1247	union samr_SetUserInfo_u ru;
1248};
1249
1250
1251/*
1252	IN	DWORD unknown_04EC;
1253	IN	DWORD unknown_zero;
1254	IN	DWORD logon_bitmap_size;
1255	IN	BYTE logon_bitmap[SAMR_SET_USER_HOURS_SZ];
1256*/
1257OPERATION(SAMR_OPNUM_SetUserInfo)
1258struct samr_SetUserInfo {
1259	IN	samr_handle_t user_handle;
1260	IN	struct samr_SetUserInfo_s info;
1261	IN	struct samr_logon_hours logon_hours;
1262	OUT	DWORD status;
1263};
1264
1265
1266/*
1267 ***********************************************************************
1268 * The SAMR interface definition.
1269 ***********************************************************************
1270 */
1271INTERFACE(0)
1272union samr_interface {
1273	CASE(SAMR_OPNUM_ConnectAnon)
1274		struct samr_ConnectAnon		ConnectAnon;
1275	CASE(SAMR_OPNUM_CloseHandle)
1276		struct samr_CloseHandle		CloseHandle;
1277	CASE(SAMR_OPNUM_LookupDomain)
1278		struct samr_LookupDomain	LookupDomain;
1279	CASE(SAMR_OPNUM_EnumLocalDomains)
1280		struct samr_EnumLocalDomain	EnumLocalDomain;
1281	CASE(SAMR_OPNUM_OpenDomain)
1282		struct samr_OpenDomain		OpenDomain;
1283	CASE(SAMR_OPNUM_QueryDomainInfo)
1284		struct samr_QueryDomainInfo	QueryDomainInfo;
1285	CASE(SAMR_OPNUM_LookupNames)
1286		struct samr_LookupNames		LookupNames;
1287	CASE(SAMR_OPNUM_OpenUser)
1288		struct samr_OpenUser		OpenUser;
1289	CASE(SAMR_OPNUM_DeleteUser)
1290		struct samr_DeleteUser		DeleteUser;
1291	CASE(SAMR_OPNUM_QueryUserInfo)
1292		struct samr_QueryUserInfo	QueryUserInfo;
1293	CASE(SAMR_OPNUM_QueryUserGroups)
1294		struct samr_QueryUserGroups	QueryUserGroups;
1295	CASE(SAMR_OPNUM_OpenGroup)
1296		struct samr_OpenGroup		OpenGroup;
1297	CASE(SAMR_OPNUM_GetUserPwInfo)
1298		struct samr_GetUserPwInfo	GetUserPwInfo;
1299	CASE(SAMR_OPNUM_CreateUser)
1300		struct samr_CreateUser		CreateUser;
1301	CASE(SAMR_OPNUM_ChangeUserPasswd)
1302		struct samr_ChangeUserPasswd	ChangeUserPasswd;
1303	CASE(SAMR_OPNUM_GetDomainPwInfo)
1304		struct samr_GetDomainPwInfo	GetDomainPwInfo;
1305	CASE(SAMR_OPNUM_Connect)
1306		struct samr_Connect		Connect;
1307	CASE(SAMR_OPNUM_SetUserInfo)
1308		struct samr_SetUserInfo		SetUserInfo;
1309	CASE(SAMR_OPNUM_Connect3)
1310		struct samr_Connect3		Connect3;
1311	CASE(SAMR_OPNUM_Connect4)
1312		struct samr_Connect4		Connect4;
1313	CASE(SAMR_OPNUM_QueryDispInfo)
1314		struct samr_QueryDispInfo	QueryDispInfo;
1315	CASE(SAMR_OPNUM_OpenAlias)
1316		struct samr_OpenAlias		OpenAlias;
1317	CASE(SAMR_OPNUM_CreateDomainAlias)
1318		struct samr_CreateDomainAlias	CreateDomainAlias;
1319	CASE(SAMR_OPNUM_SetAliasInfo)
1320		struct samr_SetAliasInfo	SetAliasInfo;
1321	CASE(SAMR_OPNUM_QueryAliasInfo)
1322		struct samr_QueryAliasInfo	QueryAliasInfo;
1323	CASE(SAMR_OPNUM_DeleteDomainAlias)
1324		struct samr_DeleteDomainAlias	DeleteDomainAlias;
1325	CASE(SAMR_OPNUM_EnumDomainAliases)
1326		struct samr_EnumDomainAliases	EnumDomainAliases;
1327	CASE(SAMR_OPNUM_EnumDomainGroups)
1328		struct samr_EnumDomainGroups	EnumDomainGroups;
1329};
1330typedef union samr_interface	samr_interface_t;
1331EXTERNTYPEINFO(samr_interface)
1332
1333#endif /* _MLSVC_SAM_NDL_ */
1334