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