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 /*
  23  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
  25  */
  26 
  27 #ifndef _MLSVC_SAM_NDL_
  28 #define _MLSVC_SAM_NDL_
  29 
  30 /*
  31  * Security Accounts Manager RPC (SAMR) interface definition.
  32  */
  33 
  34 #include <libmlrpc/ndrtypes.ndl>
  35 
  36 /* Windows NT */
  37 #define SAMR_OPNUM_Connect                      0x00    /* SamrConnect */
  38 #define SAMR_OPNUM_CloseHandle                  0x01
  39 #define SAMR_OPNUM_SetSecObject                 0x02
  40 #define SAMR_OPNUM_QuerySecObject               0x03
  41 #define SAMR_OPNUM_ShutdownSamServer            0x04    /* NotUsedOnWire */
  42 #define SAMR_OPNUM_LookupDomain                 0x05
  43 #define SAMR_OPNUM_EnumLocalDomains             0x06
  44 #define SAMR_OPNUM_OpenDomain                   0x07
  45 #define SAMR_OPNUM_QueryDomainInfo              0x08
  46 #define SAMR_OPNUM_SetDomainInfo                0x09
  47 #define SAMR_OPNUM_CreateDomainGroup            0x0a
  48 #define SAMR_OPNUM_QueryDomainGroups            0x0b
  49 #define SAMR_OPNUM_CreateDomainUser             0x0c
  50 #define SAMR_OPNUM_EnumDomainUsers              0x0d
  51 #define SAMR_OPNUM_CreateDomainAlias            0x0e
  52 #define SAMR_OPNUM_EnumDomainAliases            0x0f
  53 #define SAMR_OPNUM_LookupIds                    0x10    /* GetAliasMembership */
  54 #define SAMR_OPNUM_LookupNames                  0x11
  55 #define SAMR_OPNUM_LookupDomainIds              0x12
  56 #define SAMR_OPNUM_OpenGroup                    0x13
  57 #define SAMR_OPNUM_QueryGroupInfo               0x14
  58 #define SAMR_OPNUM_StoreGroupInfo               0x15
  59 #define SAMR_OPNUM_AddGroupMember               0x16
  60 #define SAMR_OPNUM_DeleteDomainGroup            0x17
  61 #define SAMR_OPNUM_DeleteGroupMember            0x18
  62 #define SAMR_OPNUM_ListGroupMembers             0x19
  63 #define SAMR_OPNUM_SetGroupMemberAttributes     0x1a
  64 #define SAMR_OPNUM_OpenAlias                    0x1b
  65 #define SAMR_OPNUM_QueryAliasInfo               0x1c
  66 #define SAMR_OPNUM_SetAliasInfo                 0x1d
  67 #define SAMR_OPNUM_DeleteDomainAlias            0x1e
  68 #define SAMR_OPNUM_AddAliasMember               0x1f
  69 #define SAMR_OPNUM_DeleteAliasMember            0x20
  70 #define SAMR_OPNUM_ListAliasMembers             0x21
  71 #define SAMR_OPNUM_OpenUser                     0x22
  72 #define SAMR_OPNUM_DeleteUser                   0x23
  73 #define SAMR_OPNUM_QueryUserInfo                0x24
  74 #define SAMR_OPNUM_SetUserInfo0                 0x25    /* SetUserInfo */
  75 #define SAMR_OPNUM_ChangeUserPassword0          0x26    /* ChangeUserPassword */
  76 #define SAMR_OPNUM_QueryUserGroups              0x27
  77 #define SAMR_OPNUM_QueryDispInfo                0x28    /* QueryDispInfo1 */
  78 #define SAMR_OPNUM_GetDisplayEnumIndex          0x29
  79 #define SAMR_OPNUM_TestPrivateDomainFunctions   0x2a    /* NotUsedOnWire */
  80 #define SAMR_OPNUM_TestPrivateUserFunctions     0x2b    /* NotUsedOnWire */
  81 #define SAMR_OPNUM_GetUserPwInfo                0x2c
  82 
  83 /* Windows 2000 */
  84 #define SAMR_OPNUM_RemoveMemberFromForeignDomain        0x2d
  85 #define SAMR_OPNUM_QueryInfoDomain2             0x2e
  86 #define SAMR_OPNUM_QueryInfoUser2               0x2f
  87 #define SAMR_OPNUM_EnumDomainGroups             0x30    /* QueryDispInfo2 */
  88 #define SAMR_OPNUM_GetDisplayEnumIndex2         0x31
  89 #define SAMR_OPNUM_CreateUser                   0x32
  90 #define SAMR_OPNUM_QueryDispInfo4               0x33
  91 #define SAMR_OPNUM_AddMultipleAliasMembers      0x34
  92 #define SAMR_OPNUM_RemoveMultipleAliasMembers   0x35
  93 #define SAMR_OPNUM_ChangeUserOemPassword        0x36
  94 #define SAMR_OPNUM_ChangePasswordUser2          0x37    /* UnicodePasswd */
  95 #define SAMR_OPNUM_GetDomainPwInfo              0x38
  96 #define SAMR_OPNUM_Connect2                     0x39    /* SamrConnect2 */
  97 #define SAMR_OPNUM_SetUserInfo                  0x3a    /* SetInfoUser2 */
  98 #define SAMR_OPNUM_SetBootKeyInformation        0x3b
  99 #define SAMR_OPNUM_GetBootKeyInformation        0x3c
 100 #define SAMR_OPNUM_Connect3                     0x3d    /* NotUsedOnWire */
 101 #define SAMR_OPNUM_Connect4                     0x3e    /* SamrConnect4 */
 102 #define SAMR_OPNUM_ChangeUserUnicodePassword3   0x3f
 103 
 104 /* Windows XP and Windows Server 2003 */
 105 #define SAMR_OPNUM_Connect5                     0x40    /* SamrConnect5 */
 106 #define SAMR_OPNUM_RidToSid                     0x41
 107 #define SAMR_OPNUM_SetDSRMPassword              0x42
 108 #define SAMR_OPNUM_ValidatePassword             0x43
 109 
 110 /* Windows Vista */
 111 #define SAMR_OPNUM_QueryLocalizableAccountsInDomain     0x44
 112 #define SAMR_OPNUM_PerformGenericOperation              0x45
 113 
 114 
 115 /*
 116  * Sam account flags used when creating an account. These flags seem
 117  * to be very similar to the USER_INFO_X flags (UF_XXX) in lmaccess.h
 118  * but the values are different.
 119  */
 120 #define SAMR_AF_ACCOUNTDISABLE                  0x0001
 121 #define SAMR_AF_HOMEDIR_REQUIRED                0x0002
 122 #define SAMR_AF_PASSWD_NOTREQD                  0x0004
 123 #define SAMR_AF_TEMP_DUPLICATE_ACCOUNT          0x0008
 124 #define SAMR_AF_NORMAL_ACCOUNT                  0x0010
 125 #define SAMR_AF_MNS_LOGON_ACCOUNT               0x0020
 126 #define SAMR_AF_INTERDOMAIN_TRUST_ACCOUNT       0x0040
 127 #define SAMR_AF_WORKSTATION_TRUST_ACCOUNT       0x0080
 128 #define SAMR_AF_SERVER_TRUST_ACCOUNT            0x0100
 129 #define SAMR_AF_DONT_EXPIRE_PASSWD              0x0200
 130 #define SAMR_AF_ACCOUNT_AUTOLOCK                0x0400
 131 
 132 
 133 #define SAMR_AF_MACHINE_ACCOUNT_MASK    ( \
 134                                 SAMR_AF_INTERDOMAIN_TRUST_ACCOUNT \
 135                                 | SAMR_AF_WORKSTATION_TRUST_ACCOUNT \
 136                                 | SAMR_AF_SERVER_TRUST_ACCOUNT)
 137 
 138 #define SAMR_AF_ACCOUNT_TYPE_MASK       ( \
 139                                 SAMR_AF_TEMP_DUPLICATE_ACCOUNT \
 140                                 | SAMR_AF_NORMAL_ACCOUNT \
 141                                 | SAMR_AF_INTERDOMAIN_TRUST_ACCOUNT \
 142                                 | SAMR_AF_WORKSTATION_TRUST_ACCOUNT \
 143                                 | SAMR_AF_SERVER_TRUST_ACCOUNT)
 144 
 145 /*
 146  * QueryUserInfo UserAllInformation WhichFields
 147  */
 148 #define SAMR_USER_ALL_USERNAME                  0x00000001
 149 #define SAMR_USER_ALL_FULLNAME                  0x00000002
 150 #define SAMR_USER_ALL_USERID                    0x00000004
 151 #define SAMR_USER_ALL_PRIMARYGROUPID            0x00000008
 152 #define SAMR_USER_ALL_ADMINCOMMENT              0x00000010
 153 #define SAMR_USER_ALL_USERCOMMENT               0x00000020
 154 #define SAMR_USER_ALL_HOMEDIRECTORY             0x00000040
 155 #define SAMR_USER_ALL_HOMEDIRECTORYDRIVE        0x00000080
 156 #define SAMR_USER_ALL_SCRIPTPATH                0x00000100
 157 #define SAMR_USER_ALL_PROFILEPATH               0x00000200
 158 #define SAMR_USER_ALL_WORKSTATIONS              0x00000400
 159 #define SAMR_USER_ALL_LASTLOGON                 0x00000800
 160 #define SAMR_USER_ALL_LASTLOGOFF                0x00001000
 161 #define SAMR_USER_ALL_LOGONHOURS                0x00002000
 162 #define SAMR_USER_ALL_BADPASSWORDCOUNT          0x00004000
 163 #define SAMR_USER_ALL_LOGONCOUNT                0x00008000
 164 #define SAMR_USER_ALL_PASSWORDCANCHANGE         0x00010000
 165 #define SAMR_USER_ALL_PASSWORDMUSTCHANGE        0x00020000
 166 #define SAMR_USER_ALL_PASSWORDLASTSET           0x00040000
 167 #define SAMR_USER_ALL_ACCOUNTEXPIRES            0x00080000
 168 #define SAMR_USER_ALL_USERACCOUNTCONTROL        0x00100000
 169 #define SAMR_USER_ALL_PARAMETERS                0x00200000
 170 #define SAMR_USER_ALL_COUNTRYCODE               0x00400000
 171 #define SAMR_USER_ALL_CODEPAGE                  0x00800000
 172 #define SAMR_USER_ALL_NTPASSWORDPRESENT         0x01000000
 173 #define SAMR_USER_ALL_LMPASSWORDPRESENT         0x02000000
 174 #define SAMR_USER_ALL_PRIVATEDATA               0x04000000
 175 #define SAMR_USER_ALL_PASSWORDEXPIRED           0x08000000
 176 #define SAMR_USER_ALL_SECURITYDESCRIPTOR        0x10000000
 177 #define SAMR_USER_ALL_OWF_PASSWORD              0x20000000
 178 #define SAMR_USER_ALL_UNDEFINED_MASK            0xC0000000
 179 
 180 /*
 181  * Alias Access Mask values for SAMR
 182  * Section 2.2.1.6 of MS-SAMR
 183  */
 184 #define SAMR_ALIAS_ACCESS_EXECUTE               0x00020008
 185 #define SAMR_ALIAS_ACCESS_WRITE                 0x00020013
 186 #define SAMR_ALIAS_ACCESS_READ                  0x00020004
 187 #define SAMR_ALIAS_ACCESS_ALL_ACCESS            0x000F001F
 188 #define SAMR_ALIAS_ACCESS_WRITE_ACCOUNT         0x00000010
 189 #define SAMR_ALIAS_ACCESS_READ_INFO             0x00000008
 190 #define SAMR_ALIAS_ACCESS_LIST_MEMBERS          0x00000004
 191 #define SAMR_ALIAS_ACCESS_REMOVE_MEMBER         0x00000002
 192 #define SAMR_ALIAS_ACCESS_ADD_MEMBER            0x00000001
 193 
 194 #define SAMR_REVISION_1                 1       /* Pre Windows 2000 */
 195 #define SAMR_REVISION_2                 2       /* Windows 2000 */
 196 #define SAMR_REVISION_3                 3       /* Post Windows 2000 */
 197 
 198 /*
 199  * Definition for a SID. The ndl compiler does not allow a typedef of
 200  * a structure containing variable size members.
 201  * Note: cast compatible with smb_sid_t, and code depends on that.
 202  */
 203 struct samr_sid {
 204         BYTE            Revision;
 205         BYTE            SubAuthCount;
 206         BYTE            Authority[6];
 207   SIZE_IS(SubAuthCount)
 208         DWORD           SubAuthority[ANY_SIZE_ARRAY];
 209 };
 210 
 211 
 212 /*
 213  * SAMR definition of a security_descriptor.
 214  */
 215 struct samr_sec_desc {
 216         BYTE Revision;
 217         BYTE Sbz1;
 218         WORD Control;
 219         struct samr_sid *owner;
 220         struct samr_sid *group;
 221         struct samr_sid *sacl;
 222         struct samr_sid *dacl;
 223 };
 224 
 225 struct samr_sd {
 226         DWORD length;
 227   SIZE_IS(length)
 228         BYTE *data;
 229 };
 230 typedef struct samr_sd samr_sd_t;
 231 
 232 /*
 233  * See RPC_STRING in the MS IDL.
 234  * Definition for a string. The length and allosize should be set to
 235  * twice the string length (i.e. strlen(str) * 2). The runtime code
 236  * will perform the appropriate string to a wide-char conversions,
 237  * so str should point to a regular char * string.
 238  */
 239 struct samr_string {
 240         WORD            length;
 241         WORD            allosize;
 242         LPTSTR          str;
 243 };
 244 typedef struct samr_string samr_string_t;
 245 
 246 
 247 /*
 248  * Alternative varying/conformant string definition - for
 249  * non-null terminated strings. This definition must match
 250  * ndr_vcbuf_t.
 251  */
 252 struct samr_vcb {
 253         /*
 254          * size_is (actually a copy of length_is) will
 255          * be inserted here by the marshalling library.
 256          */
 257         DWORD vc_first_is;
 258         DWORD vc_length_is;
 259   SIZE_IS(vc_length_is)
 260         WORD buffer[ANY_SIZE_ARRAY];
 261 };
 262 
 263 struct samr_vcbuf {
 264         WORD wclen;
 265         WORD wcsize;
 266         struct samr_vcb *vcb;
 267 };
 268 typedef struct samr_vcbuf samr_vcbuf_t;
 269 
 270 CONTEXT_HANDLE(samr_handle) samr_handle_t;
 271 
 272 /*
 273  * OLD_LARGE_INTEGER: a 64-bit value.
 274  */
 275 struct samr_quad {
 276         DWORD low;
 277         DWORD high;
 278 };
 279 typedef struct samr_quad samr_quad_t;
 280 
 281 /*
 282  * Blob used for the NT and LM OWF passwords.
 283  * The length and maxlen should be 16.
 284  */
 285 struct samr_short_blob {
 286         WORD    length;
 287         WORD    maxlen;
 288   SIZE_IS(length / 2)
 289         WORD    *buf;
 290 };
 291 
 292 #define DOMAIN_PASSWORD_COMPLEX                 0x00000001
 293 #define DOMAIN_PASSWORD_NO_ANON_CHANGE          0x00000002
 294 #define DOMAIN_PASSWORD_NO_CLEAR_CHANGE         0x00000004
 295 #define DOMAIN_LOCKOUT_ADMINS                   0x00000008
 296 #define DOMAIN_PASSWORD_STORE_CLEARTEXT         0x00000010
 297 #define DOMAIN_REFUSE_PASSWORD_CHANGE           0x00000020
 298 
 299 struct samr_password_info {
 300         WORD    min_length;
 301         DWORD   properties;
 302 };
 303 typedef struct samr_password_info samr_password_info_t;
 304 
 305 /*
 306  * There is some sort of logon bitmap structure in here, which I
 307  * think is a varying and conformant array, i.e.
 308  *
 309  *      struct samr_logon_hours {
 310  *      DWORD size_is;          (1260)
 311  *      DWORD first_is;         (zero)
 312  *      DWORD length_is;        (168)
 313  *      BYTE bitmap[21];
 314  *  };
 315  *
 316  *      struct samr_logon_info {
 317  *              DWORD length;
 318  *      SIZE_IS(length / 8)
 319  *              struct samr_logon_hours *hours;
 320  *      };
 321  *
 322  * There are 10080 minutes/week => 10080/8 = 1260 (0x04EC).
 323  * So size_is is set as some sort of maximum.
 324  *
 325  * There are 168 hours/week => 168/8 = 21 (0xA8). Since there are 21
 326  * bytes (all set to 0xFF), this is is probably the default setting.
 327  */
 328 
 329 #define SAMR_MINS_PER_WEEK              10080
 330 #define SAMR_HOURS_PER_WEEK             168
 331 
 332 #define SAMR_HOURS_MAX_SIZE             (SAMR_MINS_PER_WEEK / 8)
 333 #define SAMR_HOURS_SET_LEN(LEN)         ((LEN) / 8)
 334 #define SAMR_SET_USER_HOURS_SZ          21
 335 
 336 struct samr_logon_hours {
 337         DWORD size;
 338         DWORD first;
 339         DWORD length;
 340         BYTE bitmap[SAMR_SET_USER_HOURS_SZ];
 341 };
 342 
 343 struct samr_logon_info {
 344         DWORD units;
 345         DWORD hours;
 346 };
 347 
 348 struct samr_logon_hours_all {
 349         WORD    units_per_week;
 350   SIZE_IS(units_per_week / 8)
 351         BYTE    *hours;
 352 };
 353 
 354 /*
 355  * SAMPR_USER_PASSWORD (in the MS Net API) or
 356  * struct samr_user_password (internal use) is
 357  * the "clear" form of struct samr_encr_passwd
 358  * (SAMPR_ENCRYPTED_USER_PASSWORD in MS Net).
 359  * It's not used by ndrgen, but is declared here
 360  * to help clarify the relationship between these,
 361  * and for the benefit of our client-side code.
 362  */
 363 #ifndef NDRGEN
 364 #define SAMR_USER_PWLEN 256
 365 struct samr_user_password {
 366         ndr_wchar_t     Buffer[SAMR_USER_PWLEN];
 367         DWORD Length;
 368 };
 369 #endif  /* NDRGEN */
 370 
 371 /* SAMPR_ENCRYPTED_USER_PASSWORD */
 372 #define SAMR_ENCR_PWLEN 516     /* sizeof samr_user_password */
 373 struct samr_encr_passwd {
 374         BYTE data[SAMR_ENCR_PWLEN];
 375 };
 376 
 377 /* ENCRYPTED_NT_OWF_PASSWORD */
 378 #define SAMR_PWHASH_LEN 16
 379 struct samr_encr_hash {
 380         BYTE data[SAMR_PWHASH_LEN];
 381 };
 382 
 383 /*
 384  ***********************************************************************
 385  * SamrConnect.
 386  ***********************************************************************
 387  */
 388 OPERATION(SAMR_OPNUM_Connect)
 389 struct samr_Connect {
 390         IN      DWORD *servername;
 391         IN      DWORD access_mask;
 392         OUT     samr_handle_t handle;
 393         OUT     DWORD status;
 394 };
 395 
 396 
 397 /*
 398  ***********************************************************************
 399  * SamrConnect2.
 400  ***********************************************************************
 401  */
 402 OPERATION(SAMR_OPNUM_Connect2)
 403 struct samr_Connect2 {
 404         IN      LPTSTR servername;
 405         IN      DWORD access_mask;
 406         OUT     samr_handle_t handle;
 407         OUT     DWORD status;
 408 };
 409 
 410 
 411 /*
 412  ***********************************************************************
 413  * SamrConnect4. A new form of connect first seen with Windows 2000.
 414  * A new field has been added to the input request. Value: 0x00000002.
 415  ***********************************************************************
 416  */
 417 OPERATION(SAMR_OPNUM_Connect4)
 418 struct samr_Connect4 {
 419         IN      LPTSTR servername;
 420         IN      DWORD revision;
 421         IN      DWORD access_mask;
 422         OUT     samr_handle_t handle;
 423         OUT     DWORD status;
 424 };
 425 
 426 
 427 /*
 428  ***********************************************************************
 429  * SamrConnect5. A new form of connect first seen with Windows XP.
 430  * The server name is the fully qualified domain name, i.e.
 431  *      \\server.sun.com.
 432  *
 433  * [in]  DWORD   InVersion,
 434  * [in]  [switch_is(InVersion)]    samr_revision_info *InRevisionInfo
 435  * [out] DWORD   *OutVersion
 436  * [out] [switch_is(*OutVersion)] *samr_revision_info *OutRevisionInfo
 437  *
 438  * SupportedFeatures (see notes in [MS-SAMR]
 439  *      0x00000001      RID values returned from the server must not be
 440  *                      concatenated with the domain SID.
 441  *      0x00000002      Reserved
 442  *      0x00000004      Reserved
 443  ***********************************************************************
 444  */
 445 struct samr_revision_info1 {
 446         DWORD revision;
 447         DWORD supported_features;
 448 };
 449 typedef struct samr_revision_info1 samr_revision_info1_t;
 450 
 451 union samr_revision_info {
 452         UNION_INFO_ENT(1,samr_revision_info);
 453         DEFAULT char *nullptr;
 454 };
 455 
 456 OPERATION(SAMR_OPNUM_Connect5)
 457 struct samr_Connect5 {
 458         IN              LPTSTR servername;
 459         IN              DWORD access_mask;
 460         /*
 461          * This should be a union, but instead this is
 462          * done this way because unions are hard to
 463          * express in this RPC implementation.
 464          */
 465         INOUT   DWORD unknown2_00000001;        /* V1 */
 466         INOUT   DWORD unknown3_00000001;        /* V1 */
 467         /* SAMPR_REVISION_INFO_V1 */
 468         INOUT   DWORD unknown4_00000003;        /* Revision */
 469         INOUT   DWORD unknown5_00000000;        /* SupportedFeatures */
 470         OUT             samr_handle_t handle;
 471         OUT             DWORD status;
 472 };
 473 
 474 
 475 /*
 476  ***********************************************************************
 477  * CloseHandle closes an association with the SAM. Using the same
 478  * structure as the LSA seems to work.
 479  ***********************************************************************
 480  */
 481 OPERATION(SAMR_OPNUM_CloseHandle)
 482 struct samr_CloseHandle {
 483         IN      samr_handle_t handle;
 484         OUT     samr_handle_t result_handle;
 485         OUT     DWORD status;
 486 };
 487 
 488 
 489 /*
 490  ***********************************************************************
 491  * LookupDomain: lookup up the domain SID.
 492  ***********************************************************************
 493  */
 494 OPERATION(SAMR_OPNUM_LookupDomain)
 495 struct samr_LookupDomain {
 496         IN      samr_handle_t handle;
 497         IN      samr_string_t domain_name;
 498         OUT struct samr_sid *sid;
 499         OUT     DWORD status;
 500 };
 501 
 502 
 503 /*
 504  ***********************************************************************
 505  * EnumLocalDomain
 506  *
 507  * This looks like a request to get the local domains supported by a
 508  * remote server. NT always seems to return 2 domains: the local
 509  * domain (hostname) and the Builtin domain.
 510  *
 511  * The max_length field is set to 0x2000.
 512  * Enum_context is set to 0 in the request and set to entries_read in
 513  * the reply. Like most of these enums, total_entries is the same as
 514  * entries_read.
 515  ***********************************************************************
 516  */
 517 struct samr_LocalDomainEntry {
 518         DWORD unknown;
 519         samr_string_t name;
 520 };
 521 
 522 struct samr_LocalDomainInfo {
 523         DWORD entries_read;
 524   SIZE_IS(entries_read)
 525         struct samr_LocalDomainEntry *entry;
 526 };
 527 
 528 
 529 OPERATION(SAMR_OPNUM_EnumLocalDomains)
 530 struct samr_EnumLocalDomain {
 531         IN              samr_handle_t handle;
 532         INOUT   DWORD enum_context;
 533         IN              DWORD max_length;
 534         OUT             struct samr_LocalDomainInfo *info;
 535         OUT             DWORD total_entries;
 536         OUT             DWORD status;
 537 };
 538 
 539 
 540 /*
 541  ***********************************************************************
 542  * OpenDomain
 543  * 
 544  * Open a specific domain within the SAM. From this I assume that each
 545  * SAM can handle multiple domains so you need to identify the one with
 546  * which you want to work. Working with a domain handle does appear to
 547  * offer the benefit that you can then use RIDs instead of full SIDs,
 548  * which simplifies things a bit. The domain handle can be used to get
 549  * user and group handles.
 550  ***********************************************************************
 551  */
 552 OPERATION(SAMR_OPNUM_OpenDomain)
 553 struct samr_OpenDomain {
 554         IN      samr_handle_t handle;
 555         IN      DWORD access_mask;
 556         IN REFERENCE struct samr_sid *sid;
 557         OUT     samr_handle_t domain_handle;
 558         OUT     DWORD status;
 559 };
 560 
 561 
 562 /*
 563  ***********************************************************************
 564  * QueryDomainInfo
 565  *
 566  * Windows 95 Server Manager sends requests for levels 6 and 7 when
 567  * the services menu item is selected.
 568  ***********************************************************************
 569  */
 570 #define SAMR_QUERY_DOMAIN_INFO_2                2
 571 #define SAMR_QUERY_DOMAIN_INFO_6                6
 572 #define SAMR_QUERY_DOMAIN_INFO_7                7
 573 
 574 
 575 struct samr_QueryDomainInfo2 {
 576         DWORD unknown1;                 /* 00 00 00 00 */
 577         DWORD unknown2;                 /* 00 00 00 80 */
 578         samr_string_t s1;
 579         samr_string_t domain;
 580         samr_string_t s2;
 581         DWORD sequence_num;             /* 2B 00 00 00 */
 582         DWORD unknown3;                 /* 00 00 00 00 */
 583         DWORD unknown4;                 /* 01 00 00 00 */
 584         DWORD unknown5;                 /* 03 00 00 00 */
 585         DWORD unknown6;                 /* 01 */
 586         DWORD num_users;
 587         DWORD num_groups;
 588         DWORD num_aliases;
 589 };
 590 
 591 
 592 struct samr_QueryDomainInfo6 {
 593         DWORD unknown1;                 /* 00 00 00 00 */
 594         DWORD unknown2;                 /* B0 7F 14 00 */
 595         DWORD unknown3;                 /* 00 00 00 00 */
 596         DWORD unknown4;                 /* 00 00 00 00 */
 597         DWORD unknown5;                 /* 00 00 00 00 */
 598 };
 599 
 600 
 601 struct samr_QueryDomainInfo7 {
 602         DWORD unknown1;                 /* 03 00 00 00 */
 603 };
 604 
 605 
 606 union samr_QueryDomainInfo_ru {
 607         UNION_INFO_ENT(2,samr_QueryDomainInfo);
 608         UNION_INFO_ENT(6,samr_QueryDomainInfo);
 609         UNION_INFO_ENT(7,samr_QueryDomainInfo);
 610         DEFAULT char *nullptr;
 611 };
 612 
 613 struct samr_QueryDomainInfoRes {
 614         WORD switch_value;
 615         SWITCH(switch_value)
 616                 union samr_QueryDomainInfo_ru ru;
 617 };
 618 
 619 OPERATION(SAMR_OPNUM_QueryDomainInfo)
 620 struct samr_QueryDomainInfo {
 621         IN      samr_handle_t domain_handle;
 622         IN      WORD info_level;
 623         OUT     struct samr_QueryDomainInfoRes *info;
 624         OUT     DWORD status;
 625 };
 626 
 627 /*
 628  * Identical to SAMR_OPNUM_QueryDomainInfo.
 629  */
 630 OPERATION(SAMR_OPNUM_QueryInfoDomain2)
 631 struct samr_QueryInfoDomain2 {
 632         IN      samr_handle_t   domain_handle;
 633         IN      WORD            info_level;
 634         OUT     struct samr_QueryDomainInfoRes *info;
 635         OUT     DWORD           status;
 636 };
 637 
 638 #define SAMR_QUERY_ALIAS_INFO_GENERAL           1
 639 #define SAMR_QUERY_ALIAS_INFO_NAME              2
 640 #define SAMR_QUERY_ALIAS_INFO_COMMENT           3
 641 
 642 struct samr_QueryAliasInfoGeneral {
 643         WORD level;
 644         samr_string_t name;
 645         DWORD member_count;
 646         samr_string_t desc;
 647 };
 648 
 649 struct samr_QueryAliasInfoName {
 650         WORD level;
 651         samr_string_t name;
 652 };
 653 
 654 struct samr_QueryAliasInfoComment {
 655         WORD level;
 656         samr_string_t desc;
 657 };
 658 
 659 union samr_QueryAliasInfo_ru {
 660         CASE(1) struct samr_QueryAliasInfoGeneral info1;
 661         CASE(2) struct samr_QueryAliasInfoName    info2;
 662         CASE(3) struct samr_QueryAliasInfoComment info3;
 663         DEFAULT char *nullptr;
 664 };
 665 
 666 struct samr_QueryAliasInfoRes {
 667         DWORD address;
 668         WORD switch_value;
 669         SWITCH(switch_value)
 670                 union samr_QueryAliasInfo_ru ru;
 671 };
 672 
 673 OPERATION(SAMR_OPNUM_QueryAliasInfo)
 674 struct samr_QueryAliasInfo {
 675         IN      samr_handle_t alias_handle;
 676         IN      WORD level;
 677         OUT DWORD address;
 678   SWITCH (level)
 679         OUT     union samr_QueryAliasInfo_ru ru;
 680         OUT     DWORD status;
 681 };
 682 
 683 OPERATION(SAMR_OPNUM_CreateDomainAlias)
 684 struct samr_CreateDomainAlias {
 685         IN      samr_handle_t domain_handle;
 686         IN      samr_string_t alias_name;
 687         IN      DWORD access_mask;
 688         OUT samr_handle_t alias_handle;
 689         OUT     DWORD rid;
 690         OUT     DWORD status;
 691 };
 692 
 693 OPERATION(SAMR_OPNUM_SetAliasInfo)
 694 struct samr_SetAliasInfo {
 695         IN      samr_handle_t alias_handle;
 696         IN      WORD level;
 697         /* TBD */
 698         OUT     DWORD status;
 699 };
 700 
 701 OPERATION(SAMR_OPNUM_DeleteDomainAlias)
 702 struct samr_DeleteDomainAlias {
 703         INOUT   samr_handle_t alias_handle;
 704         OUT     DWORD status;
 705 };
 706 
 707 OPERATION(SAMR_OPNUM_OpenAlias)
 708 struct samr_OpenAlias {
 709         IN      samr_handle_t domain_handle;
 710         IN      DWORD access_mask;
 711         IN      DWORD rid;
 712         OUT samr_handle_t alias_handle;
 713         OUT     DWORD status;
 714 };
 715 
 716 struct name_rid {
 717         DWORD rid;
 718         samr_string_t name;
 719 };
 720 
 721 struct aliases_info {
 722         DWORD count;
 723         DWORD address;
 724         SIZE_IS(count)
 725         struct name_rid info[ANY_SIZE_ARRAY];
 726 };
 727 
 728 OPERATION(SAMR_OPNUM_EnumDomainAliases)
 729 struct samr_EnumDomainAliases {
 730         IN      samr_handle_t domain_handle;
 731         IN      DWORD resume_handle;
 732         IN      DWORD mask;
 733         OUT     DWORD out_resume;
 734         OUT struct aliases_info *aliases;
 735         OUT DWORD entries;
 736         OUT     DWORD status;
 737 };
 738 
 739 struct user_acct_info {
 740         DWORD index;
 741         DWORD rid;
 742         DWORD ctrl;
 743         samr_string_t name;
 744         samr_string_t fullname;
 745         samr_string_t desc;
 746 };
 747 
 748 struct user_disp_info {
 749         OUT DWORD total_size;
 750         OUT DWORD returned_size;
 751         OUT WORD switch_value;
 752         DWORD count;
 753         SIZE_IS(count)
 754         struct user_acct_info *acct;
 755 };
 756 
 757 OPERATION(SAMR_OPNUM_QueryDispInfo)
 758 struct samr_QueryDispInfo {
 759         IN      samr_handle_t domain_handle;
 760         IN      WORD level;
 761         IN      DWORD start_idx;
 762         IN      DWORD max_entries;
 763         IN      DWORD pref_maxsize;
 764         OUT struct user_disp_info users;
 765         OUT     DWORD status;
 766 };
 767 
 768 struct group_acct_info {
 769         DWORD index;
 770         DWORD rid;
 771         DWORD ctrl;
 772         samr_string_t name;
 773         samr_string_t desc;
 774 };
 775 
 776 struct group_disp_info {
 777         DWORD count;
 778         /* right now we just need one entry */
 779         struct group_acct_info acct[1];
 780 };
 781 
 782 OPERATION(SAMR_OPNUM_EnumDomainGroups)
 783 struct samr_EnumDomainGroups {
 784         IN      samr_handle_t domain_handle;
 785         IN      WORD level;
 786         IN      DWORD start_idx;
 787         IN      DWORD max_entries;
 788         IN      DWORD pref_maxsize;
 789         OUT DWORD total_size;
 790         OUT DWORD returned_size;
 791         OUT WORD switch_value;
 792         OUT DWORD count;
 793         OUT struct group_disp_info *groups;
 794         OUT     DWORD status;
 795 };
 796 
 797 /*
 798  ***********************************************************************
 799  * OpenUser
 800  *
 801  * Input must be a domain handle obtained via SAMR_OPNUM_OpenDomain,
 802  * an access mask and the appropriate user rid. The output will be a
 803  * handle for use with the specified user.
 804  ***********************************************************************
 805  */
 806 OPERATION(SAMR_OPNUM_OpenUser)
 807 struct samr_OpenUser {
 808         IN      samr_handle_t handle;
 809         IN      DWORD access_mask;
 810         IN      DWORD rid;
 811         OUT     samr_handle_t user_handle;
 812         OUT     DWORD status;
 813 };
 814 
 815 
 816 /*
 817  ***********************************************************************
 818  * DeleteUser
 819  ***********************************************************************
 820  */
 821 OPERATION(SAMR_OPNUM_DeleteUser)
 822 struct samr_DeleteUser {
 823         INOUT   samr_handle_t user_handle;
 824         OUT     DWORD status;
 825 };
 826 
 827 
 828 /*
 829  ***********************************************************************
 830  * QueryUserInfo
 831  *
 832  * Provides various pieces of information on a specific user (see
 833  * SAM_Q_QUERY_USERINFO and SAM_R_QUERY_USERINFO). The handle must
 834  * be a valid SAM user handle.
 835  *
 836  * QueryUserInfo (
 837  *      IN samr_handle_t user_handle,
 838  *      IN WORD switch_value,
 839  *      OUT union switch(switch_value) {
 840  *              case 1: struct QueryUserInfo1 *info1;
 841  *      } bufptr,
 842  *      OUT DWORD status
 843  * )
 844  *
 845  * typedef enum _USER_INFORMATION_CLASS {
 846  *      UserGeneralInformation          = 1,
 847  *      UserPreferencesInformation      = 2,
 848  *      UserLogonInformation            = 3,
 849  *      UserLogonHoursInformation       = 4,
 850  *      UserAccountInformation          = 5,
 851  *      UserNameInformation             = 6,
 852  *      UserAccountNameInformation      = 7,
 853  *      UserFullNameInformation         = 8,
 854  *      UserPrimaryGroupInformation     = 9,
 855  *      UserHomeInformation             = 10,
 856  *      UserScriptInformation           = 11,
 857  *      UserProfileInformation          = 12,
 858  *      UserAdminCommentInformation     = 13,
 859  *      UserWorkStationsInformation     = 14,
 860  *      UserControlInformation          = 16,
 861  *      UserExpiresInformation          = 17,
 862  *      UserInternal1Information        = 18,
 863  *      UserParametersInformation       = 20,
 864  *      UserAllInformation              = 21,
 865  *      UserInternal4Information        = 23,
 866  *      UserInternal5Information        = 24,
 867  *      UserInternal4InformationNew     = 25,
 868  *      UserInternal5InformationNew     = 26,
 869  * } USER_INFORMATION_CLASS;
 870  *
 871  * 1 = username, fullname, description and some other stuff.
 872  * 3 = large structure containing user rid, group rid, username
 873  *     and fullname.
 874  * 5 = large structure (like 3) containing user rid, group rid,
 875  *     username, fullname and description.
 876  * 6 = username and fullname
 877  * 7 = username
 878  * 8 = fullname
 879  * 9 = group rid
 880  * 16 = used after creating a new account
 881  *
 882  * Due to an ndrgen bug, a function must be provided to to patch the
 883  * offsets used by the unmarshalling code at runtime.  In order to
 884  * simplify things it is useful to use a naming convention that
 885  * indicates the switch value for each structure.
 886  * 
 887  ***********************************************************************
 888  */
 889 
 890 
 891 #define SAMR_QUERY_USER_INFO_1                  1
 892 #define SAMR_QUERY_USER_UNAME_AND_FNAME         6
 893 #define SAMR_QUERY_USER_USERNAME                7
 894 #define SAMR_QUERY_USER_FULLNAME                8
 895 #define SAMR_QUERY_USER_GROUPRID                9
 896 #define SAMR_QUERY_USER_CONTROL_INFO            16
 897 #define SAMR_QUERY_USER_ALL_INFO                21
 898 
 899 
 900 struct samr_QueryUserInfo1 {
 901         samr_string_t username;
 902         samr_string_t fullname;
 903         DWORD group_rid;
 904         samr_string_t description;
 905         samr_string_t unknown;
 906 };
 907 
 908 
 909 struct samr_QueryUserInfo6 {
 910         samr_string_t username;
 911         samr_string_t fullname;
 912 };
 913 
 914 struct samr_QueryUserInfo7 {
 915         samr_string_t username;
 916 };
 917 
 918 
 919 struct samr_QueryUserInfo8 {
 920         samr_string_t fullname;
 921 };
 922 
 923 
 924 struct samr_QueryUserInfo9 {
 925         DWORD group_rid;
 926 };
 927 
 928 
 929 struct samr_QueryUserInfo16 {
 930         DWORD UserAccountControl;
 931 };
 932 
 933 /*
 934  * SAMR_USER_ALL_INFORMATION
 935  */
 936 struct samr_QueryUserInfo21 {
 937         samr_quad_t             LastLogon;
 938         samr_quad_t             LastLogoff;
 939         samr_quad_t             PasswordLastSet;
 940         samr_quad_t             AccountExpires;
 941         samr_quad_t             PasswordCanChange;
 942         samr_quad_t             PasswordMustChange;
 943         samr_string_t           UserName;
 944         samr_string_t           FullName;
 945         samr_string_t           HomeDirectory;
 946         samr_string_t           HomeDirectoryDrive;
 947         samr_string_t           ScriptPath;
 948         samr_string_t           ProfilePath;
 949         samr_string_t           AdminComment;
 950         samr_string_t           WorkStations;
 951         samr_string_t           UserComment;
 952         samr_string_t           Parameters;
 953         struct samr_short_blob  LmOwfPassword;
 954         struct samr_short_blob  NtOwfPassword;
 955         samr_string_t           PrivateData;
 956         samr_sd_t               SecurityDescriptor;
 957         DWORD                   UserId;
 958         DWORD                   PrimaryGroupId;
 959         DWORD                   UserAccountControl;
 960         DWORD                   WhichFields;
 961         struct samr_logon_hours_all     LogonHours;
 962         WORD                    BadPasswordCount;
 963         WORD                    LogonCount;
 964         WORD                    CountryCode;
 965         WORD                    CodePage;
 966         BYTE                    LmPasswordPresent;
 967         BYTE                    NtPasswordPresent;
 968         BYTE                    PasswordExpired;
 969         BYTE                    PrivateDataSensitive;
 970 };
 971 
 972 /* See also: fixup_samr_QueryUserInfo() */
 973 union QueryUserInfo_result_u {
 974         UNION_INFO_ENT(1,samr_QueryUserInfo);
 975         UNION_INFO_ENT(6,samr_QueryUserInfo);
 976         UNION_INFO_ENT(7,samr_QueryUserInfo);
 977         UNION_INFO_ENT(8,samr_QueryUserInfo);
 978         UNION_INFO_ENT(9,samr_QueryUserInfo);
 979         UNION_INFO_ENT(16,samr_QueryUserInfo);
 980         UNION_INFO_ENT(21,samr_QueryUserInfo);
 981         DEFAULT char *nullptr;
 982 };
 983 
 984 
 985 /*
 986  * This structure needs to be declared, even though it can't be used in
 987  * samr_QueryUserInfo, in order to get the appropriate size to calculate
 988  * the correct fixup offsets.  If ndrgen did the right thing,
 989  * QueryUserInfo_result would be one of the out parameters.  However, if
 990  * we do it that way, the switch_value isn't known early enough to do
 991  * the fixup calculation.  So it all has to go in samr_QueryUserInfo.
 992  */
 993 struct QueryUserInfo_result {
 994         DWORD address;
 995         WORD switch_value;
 996         SWITCH(switch_value)
 997                 union QueryUserInfo_result_u ru;
 998 };
 999 
1000 
1001 OPERATION(SAMR_OPNUM_QueryUserInfo)
1002 struct samr_QueryUserInfo {
1003         IN      samr_handle_t user_handle;
1004         IN      WORD switch_value;
1005         /*
1006          * Can't use this form because we need to include members explicitly.
1007          * OUT  struct QueryUserInfo_result result;
1008          */
1009         OUT     DWORD address;
1010         OUT     WORD switch_index;
1011   SWITCH(switch_value)
1012         OUT     union QueryUserInfo_result_u ru;
1013         OUT     DWORD status;
1014 };
1015 
1016 
1017 /*
1018  ***********************************************************************
1019  * QueryUserGroups
1020  ***********************************************************************
1021  */
1022 struct samr_UserGroups {
1023         DWORD rid;
1024         DWORD attr;
1025 };
1026 
1027 
1028 struct samr_UserGroupInfo {
1029         DWORD n_entry;
1030   SIZE_IS(n_entry)
1031         struct samr_UserGroups *groups;
1032 };
1033 
1034 
1035 OPERATION(SAMR_OPNUM_QueryUserGroups)
1036 struct samr_QueryUserGroups {
1037         IN      samr_handle_t user_handle;
1038         OUT struct samr_UserGroupInfo *info;
1039         OUT     DWORD status;
1040 };
1041 
1042 
1043 /*
1044  ***********************************************************************
1045  * LookupName
1046  ***********************************************************************
1047  */
1048 struct samr_LookupNameTable {
1049         DWORD n_entry;
1050   SIZE_IS(n_entry)
1051         samr_string_t names[ANY_SIZE_ARRAY];
1052 };
1053 
1054 
1055 struct samr_LookupRidTable {
1056         DWORD n_entry;
1057   SIZE_IS(n_entry)
1058         DWORD *rid;
1059 };
1060 
1061 struct samr_RidType {
1062         DWORD n_entry;
1063   SIZE_IS(n_entry)
1064         DWORD *rid_type;
1065 };
1066 
1067 
1068 OPERATION(SAMR_OPNUM_LookupNames)
1069 struct samr_LookupNames {
1070         IN      samr_handle_t handle;
1071         IN      DWORD n_entry;
1072         IN      DWORD max_n_entry;
1073         IN      DWORD index;
1074         IN      DWORD total;
1075         IN      samr_string_t name;
1076         OUT     struct samr_LookupRidTable rids;
1077         OUT     struct samr_RidType rid_types;
1078         OUT     DWORD status;
1079 };
1080 
1081 
1082 /*
1083  ***********************************************************************
1084  * OpenGroup
1085  *
1086  * Input must be a domain handle obtained via SAMR_OPNUM_OpenDomain,
1087  * an access mask and the appropriate group rid. The output will be a
1088  * handle for use with the specified group.
1089  ***********************************************************************
1090  */
1091 OPERATION(SAMR_OPNUM_OpenGroup)
1092 struct samr_OpenGroup {
1093         IN      samr_handle_t handle;
1094         IN      DWORD access_mask;
1095         IN      DWORD rid;
1096         OUT     samr_handle_t group_handle;
1097         OUT     DWORD status;
1098 };
1099 
1100 
1101 /*
1102  ***********************************************************************
1103  * QueryGroupInfo
1104  *
1105  * Input must be a group handle obtained via SAMR_OPNUM_OpenGroup,
1106  * an access mask and the appropriate group rid. The output will
1107  * be a handle for use with the specified group.
1108  ***********************************************************************
1109  */
1110 struct samr_QueryGroupInfo1 {
1111         samr_string_t groupname;
1112 };
1113 
1114 
1115 union samr_QueryGroupInfo_result_u {
1116         UNION_INFO_ENT(1,samr_QueryGroupInfo);
1117         DEFAULT char *nullptr;
1118 };
1119 
1120 
1121 struct samr_QueryGroupInfo_result {
1122         DWORD address;
1123         WORD switch_index;
1124   SWITCH(switch_index)
1125         union samr_QueryGroupInfo_result_u ru;
1126 };
1127 
1128 
1129 OPERATION(SAMR_OPNUM_QueryGroupInfo)
1130 struct samr_QueryGroupInfo {
1131         IN      samr_handle_t group_handle;
1132         IN      DWORD switch_value;
1133         OUT     DWORD address;
1134         OUT     WORD switch_index;
1135   SWITCH(switch_index)
1136         OUT     union samr_QueryGroupInfo_result_u ru;
1137         OUT     DWORD status;
1138 };
1139 
1140 
1141 /*
1142  ***********************************************************************
1143  * StoreGroupInfo
1144  *
1145  * This definition is mostly just a place holder in case this is useful
1146  * in the future. Note that it may not be correct. The information is
1147  * from a netmon trace captured when I added a group description. I
1148  * haven't implemented it because we don't have to update anything on
1149  * the PDC. The description should almost certainly be in a separate
1150  * structure.
1151  ***********************************************************************
1152  */
1153 OPERATION(SAMR_OPNUM_StoreGroupInfo)
1154 struct samr_StoreGroupInfo {
1155         IN      samr_handle_t group_handle;
1156         IN      DWORD switch_value;
1157         IN      samr_string_t group_description;
1158         OUT     DWORD status;
1159 };
1160 
1161 /*
1162  * AddAliasMember
1163  */
1164 OPERATION(SAMR_OPNUM_AddAliasMember)
1165 struct samr_AddAliasMember {
1166         IN              samr_handle_t alias_handle;
1167         IN REFERENCE    struct samr_sid *sid;
1168         OUT DWORD       status;
1169 };
1170 
1171 /*
1172  * DeleteAliasMember
1173  */
1174 OPERATION(SAMR_OPNUM_DeleteAliasMember)
1175 struct samr_DeleteAliasMember {
1176         IN              samr_handle_t alias_handle;
1177         IN REFERENCE    struct samr_sid *sid;
1178         OUT DWORD       status;
1179 };
1180 
1181 struct samr_SidList {
1182         struct samr_sid         *sid;
1183 };
1184 
1185 struct samr_SidInfo {
1186         DWORD n_entry;
1187   SIZE_IS(n_entry)
1188         struct samr_SidList     *sidlist;
1189 };
1190 
1191 /*
1192  * ListAliasMembers
1193  */
1194 OPERATION(SAMR_OPNUM_ListAliasMembers)
1195 struct samr_ListAliasMembers {
1196         IN              samr_handle_t alias_handle;
1197         OUT             struct samr_SidInfo info;
1198         OUT DWORD       status;
1199 };
1200 
1201 /*
1202  ***********************************************************************
1203  * GetUserDomainPasswordInformation
1204  ***********************************************************************
1205  */
1206 OPERATION(SAMR_OPNUM_GetUserPwInfo)
1207 struct samr_GetUserPwInfo {
1208         IN              samr_handle_t           user_handle;
1209         OUT REFERENCE   samr_password_info_t    *pwinfo;
1210         OUT             DWORD                   status;
1211 };
1212 
1213 
1214 /*
1215  ***********************************************************************
1216  * CreateUser
1217  *
1218  * Create a user in the domain specified by the domain handle. The
1219  * domain handle is obtained obtained via SAMR_OPNUM_OpenDomain.
1220  * DesiredAccess: 0xe00500b0.
1221  * The output will be a handle for use with the specified user and the
1222  * user's RID. I think the RID may be a unique pointer (it can be null).
1223  ***********************************************************************
1224  */
1225 OPERATION(SAMR_OPNUM_CreateUser)
1226 struct samr_CreateUser {
1227         IN      samr_handle_t handle;
1228         IN      samr_vcbuf_t username;
1229         IN      DWORD account_flags;
1230         IN      DWORD desired_access;
1231         OUT     samr_handle_t user_handle;
1232         OUT     DWORD maybe_ptr;
1233         OUT     DWORD rid;
1234         OUT     DWORD status;
1235 };
1236 
1237 
1238 /*
1239  ***********************************************************************
1240  * ChangePasswordUser2 - See:
1241  * SamrUnicodeChangePasswordUser2 [MS-SAMR 3.1.5.10.3]
1242  ***********************************************************************
1243  */
1244 
1245 OPERATION(SAMR_OPNUM_ChangePasswordUser2)
1246 struct samr_ChangePasswordUser2 {
1247         IN      samr_string_t *servername;
1248         IN REF  samr_string_t *username;
1249         IN      struct samr_encr_passwd *nt_newpw;
1250         IN      struct samr_encr_hash *nt_oldpw;
1251         IN      BYTE lm_present;
1252         IN      struct samr_encr_passwd *lm_newpw;
1253         IN      struct samr_encr_hash *lm_oldpw;
1254         OUT     DWORD status;
1255 };
1256 
1257 
1258 /*
1259  ***********************************************************************
1260  * GetDomainPwInfo
1261  ***********************************************************************
1262  */
1263 OPERATION(SAMR_OPNUM_GetDomainPwInfo)
1264 struct samr_GetDomainPwInfo {
1265         IN              DWORD                   unused;
1266         OUT REFERENCE   samr_password_info_t    *pwinfo;
1267         OUT             DWORD                   status;
1268 };
1269 
1270 
1271 /*
1272  ***********************************************************************
1273  * SetUserInfo
1274  * [MS-SAMR] SamrSetInformationUser2
1275  ***********************************************************************
1276  */
1277 
1278 /* USER_CONTROL_INFORMATION */
1279 struct samr_SetUserInfo16 {
1280         DWORD UserAccountControl;
1281 };
1282 
1283 
1284 /*
1285  * samr_SetUserInfo21, a.k.a
1286  * SAMR_USER_ALL_INFORMATION
1287  *
1288  * We now know this is the same as samr_QueryUserInfo21
1289  * Could merge, except for the samr_vcbuf_t mess.
1290  */
1291 
1292 #define SAMR_SET_USER_INFO_21           21
1293 
1294 struct samr_SetUserInfo21 {
1295         samr_quad_t             LastLogon;
1296         samr_quad_t             LastLogoff;
1297         samr_quad_t             PasswordLastSet;
1298         samr_quad_t             AccountExpires;
1299         samr_quad_t             PasswordCanChange;
1300         samr_quad_t             PasswordMustChange;
1301 
1302         samr_vcbuf_t            UserName;
1303         samr_vcbuf_t            FullName;
1304         samr_vcbuf_t            HomeDirectory;
1305         samr_vcbuf_t            HomeDirectoryDrive;
1306         samr_vcbuf_t            ScriptPath;
1307         samr_vcbuf_t            ProfilePath;
1308         samr_vcbuf_t            AdminComment;
1309         samr_vcbuf_t            WorkStations;
1310         samr_vcbuf_t            UserComment;
1311         samr_vcbuf_t            Parameters;
1312 
1313         struct samr_short_blob  LmOwfPassword;
1314         struct samr_short_blob  NtOwfPassword;
1315         samr_vcbuf_t            PrivateData;
1316         samr_sd_t               SecurityDescriptor;
1317 
1318         DWORD                   UserId; /* RID */
1319         DWORD                   PrimaryGroupId;
1320         DWORD                   UserAccountControl;
1321         DWORD                   WhichFields;
1322 
1323         /*
1324          * This should be samr_logon_hours_all, but apparently
1325          * ndrgen doesn't get that quite right, so instead, the
1326          * client-side code patches this up.
1327          */
1328         struct samr_logon_info  LogonHours;
1329 
1330         WORD                    BadPasswordCount;
1331         WORD                    LogonCount;
1332         WORD                    CountryCode;
1333         WORD                    CodePage;
1334         BYTE                    LmPasswordPresent;
1335         BYTE                    NtPasswordPresent;
1336         BYTE                    PasswordExpired;
1337         BYTE                    PrivateDataSensitive;
1338 };
1339 
1340 /*
1341  *      SAMPR_USER_INTERNAL4_INFORMATION
1342  *      UserInternal4Information (23)
1343  */
1344 #define SAMR_SET_USER_INFO_23           23
1345 struct samr_SetUserInfo23 {
1346         struct samr_SetUserInfo21 info21;
1347         struct samr_encr_passwd encr_pw;
1348 };
1349 
1350 /*
1351  *      SAMPR_USER_INTERNAL5_INFORMATION
1352  *      UserInternal5Information (24)
1353  */
1354 #define SAMR_SET_USER_INFO_24           24
1355 struct samr_SetUserInfo24 {
1356         struct samr_encr_passwd encr_pw;
1357         BYTE password_expired;
1358 };
1359 
1360 
1361 union samr_SetUserInfo_u {
1362         UNION_INFO_ENT(16,samr_SetUserInfo);
1363         UNION_INFO_ENT(21,samr_SetUserInfo);
1364         UNION_INFO_ENT(23,samr_SetUserInfo);
1365         UNION_INFO_ENT(24,samr_SetUserInfo);
1366         DEFAULT  DWORD nothing;
1367 };
1368 
1369 struct samr_SetUserInfo_s {
1370         WORD info_level;
1371         WORD switch_value;
1372   SWITCH(switch_value)
1373         union samr_SetUserInfo_u ru;
1374 };
1375 
1376 OPERATION(SAMR_OPNUM_SetUserInfo)
1377 struct samr_SetUserInfo {
1378         IN      samr_handle_t user_handle;
1379         IN      struct samr_SetUserInfo_s info;
1380         OUT     DWORD status;
1381 };
1382 
1383 
1384 /*
1385  ***********************************************************************
1386  * The SAMR interface definition.
1387  ***********************************************************************
1388  */
1389 INTERFACE(0)
1390 union samr_interface {
1391         CASE(SAMR_OPNUM_Connect)
1392                 struct samr_Connect             Connect;
1393         CASE(SAMR_OPNUM_CloseHandle)
1394                 struct samr_CloseHandle         CloseHandle;
1395         CASE(SAMR_OPNUM_LookupDomain)
1396                 struct samr_LookupDomain        LookupDomain;
1397         CASE(SAMR_OPNUM_EnumLocalDomains)
1398                 struct samr_EnumLocalDomain     EnumLocalDomain;
1399         CASE(SAMR_OPNUM_OpenDomain)
1400                 struct samr_OpenDomain          OpenDomain;
1401         CASE(SAMR_OPNUM_QueryDomainInfo)
1402                 struct samr_QueryDomainInfo     QueryDomainInfo;
1403         CASE(SAMR_OPNUM_QueryInfoDomain2)
1404                 struct samr_QueryInfoDomain2    QueryInfoDomain2;
1405         CASE(SAMR_OPNUM_LookupNames)
1406                 struct samr_LookupNames         LookupNames;
1407         CASE(SAMR_OPNUM_OpenUser)
1408                 struct samr_OpenUser            OpenUser;
1409         CASE(SAMR_OPNUM_DeleteUser)
1410                 struct samr_DeleteUser          DeleteUser;
1411         CASE(SAMR_OPNUM_QueryUserInfo)
1412                 struct samr_QueryUserInfo       QueryUserInfo;
1413         CASE(SAMR_OPNUM_QueryUserGroups)
1414                 struct samr_QueryUserGroups     QueryUserGroups;
1415         CASE(SAMR_OPNUM_OpenGroup)
1416                 struct samr_OpenGroup           OpenGroup;
1417         CASE(SAMR_OPNUM_AddAliasMember)
1418                 struct samr_AddAliasMember      AddAliasMember;
1419         CASE(SAMR_OPNUM_DeleteAliasMember)
1420                 struct samr_DeleteAliasMember   DeleteAliasMember;
1421         CASE(SAMR_OPNUM_ListAliasMembers)
1422                 struct samr_ListAliasMembers    ListAliasMembers;
1423         CASE(SAMR_OPNUM_GetUserPwInfo)
1424                 struct samr_GetUserPwInfo       GetUserPwInfo;
1425         CASE(SAMR_OPNUM_CreateUser)
1426                 struct samr_CreateUser          CreateUser;
1427         CASE(SAMR_OPNUM_ChangePasswordUser2)
1428                 struct samr_ChangePasswordUser2 ChangePasswordUser2;
1429         CASE(SAMR_OPNUM_GetDomainPwInfo)
1430                 struct samr_GetDomainPwInfo     GetDomainPwInfo;
1431         CASE(SAMR_OPNUM_Connect2)
1432                 struct samr_Connect2            Connect2;
1433         CASE(SAMR_OPNUM_SetUserInfo)
1434                 struct samr_SetUserInfo         SetUserInfo;
1435         CASE(SAMR_OPNUM_Connect4)
1436                 struct samr_Connect4            Connect4;
1437         CASE(SAMR_OPNUM_Connect5)
1438                 struct samr_Connect5            Connect5;
1439         CASE(SAMR_OPNUM_QueryDispInfo)
1440                 struct samr_QueryDispInfo       QueryDispInfo;
1441         CASE(SAMR_OPNUM_OpenAlias)
1442                 struct samr_OpenAlias           OpenAlias;
1443         CASE(SAMR_OPNUM_CreateDomainAlias)
1444                 struct samr_CreateDomainAlias   CreateDomainAlias;
1445         CASE(SAMR_OPNUM_SetAliasInfo)
1446                 struct samr_SetAliasInfo        SetAliasInfo;
1447         CASE(SAMR_OPNUM_QueryAliasInfo)
1448                 struct samr_QueryAliasInfo      QueryAliasInfo;
1449         CASE(SAMR_OPNUM_DeleteDomainAlias)
1450                 struct samr_DeleteDomainAlias   DeleteDomainAlias;
1451         CASE(SAMR_OPNUM_EnumDomainAliases)
1452                 struct samr_EnumDomainAliases   EnumDomainAliases;
1453         CASE(SAMR_OPNUM_EnumDomainGroups)
1454                 struct samr_EnumDomainGroups    EnumDomainGroups;
1455 };
1456 typedef union samr_interface    samr_interface_t;
1457 EXTERNTYPEINFO(samr_interface)
1458 
1459 #endif /* _MLSVC_SAM_NDL_ */