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 2017 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  * QuerySecObject
 492  *
 493  * Returns the SecurityDescriptor of the object. Support not complete.
 494  *
 495  * QuerySecObject (
 496  *      IN samr_handle_t obj_handle,
 497  *      IN SECURITY_INFO secinfo,
 498  *      OUT samr_sd_t *sd,
 499  *      OUT DWORD status
 500  * )
 501  *
 502  ***********************************************************************
 503  */
 504 
 505 typedef DWORD SECURITY_INFO;
 506 
 507 OPERATION(SAMR_OPNUM_QuerySecObject)
 508 struct samr_QuerySecObject {
 509         IN      samr_handle_t obj_handle;
 510         IN      SECURITY_INFO secinfo;
 511         OUT     samr_sd_t *sd;
 512         OUT     DWORD status;
 513 };
 514 
 515 
 516 /*
 517  ***********************************************************************
 518  * LookupDomain: lookup up the domain SID.
 519  ***********************************************************************
 520  */
 521 OPERATION(SAMR_OPNUM_LookupDomain)
 522 struct samr_LookupDomain {
 523         IN      samr_handle_t handle;
 524         IN      samr_string_t domain_name;
 525         OUT struct samr_sid *sid;
 526         OUT     DWORD status;
 527 };
 528 
 529 
 530 /*
 531  ***********************************************************************
 532  * EnumLocalDomain
 533  *
 534  * This looks like a request to get the local domains supported by a
 535  * remote server. NT always seems to return 2 domains: the local
 536  * domain (hostname) and the Builtin domain.
 537  *
 538  * The max_length field is set to 0x2000.
 539  * Enum_context is set to 0 in the request and set to entries_read in
 540  * the reply. Like most of these enums, total_entries is the same as
 541  * entries_read.
 542  ***********************************************************************
 543  */
 544 struct samr_LocalDomainEntry {
 545         DWORD unknown;
 546         samr_string_t name;
 547 };
 548 
 549 struct samr_LocalDomainInfo {
 550         DWORD entries_read;
 551   SIZE_IS(entries_read)
 552         struct samr_LocalDomainEntry *entry;
 553 };
 554 
 555 
 556 OPERATION(SAMR_OPNUM_EnumLocalDomains)
 557 struct samr_EnumLocalDomain {
 558         IN              samr_handle_t handle;
 559         INOUT   DWORD enum_context;
 560         IN              DWORD max_length;
 561         OUT             struct samr_LocalDomainInfo *info;
 562         OUT             DWORD total_entries;
 563         OUT             DWORD status;
 564 };
 565 
 566 
 567 /*
 568  ***********************************************************************
 569  * OpenDomain
 570  * 
 571  * Open a specific domain within the SAM. From this I assume that each
 572  * SAM can handle multiple domains so you need to identify the one with
 573  * which you want to work. Working with a domain handle does appear to
 574  * offer the benefit that you can then use RIDs instead of full SIDs,
 575  * which simplifies things a bit. The domain handle can be used to get
 576  * user and group handles.
 577  ***********************************************************************
 578  */
 579 OPERATION(SAMR_OPNUM_OpenDomain)
 580 struct samr_OpenDomain {
 581         IN      samr_handle_t handle;
 582         IN      DWORD access_mask;
 583         IN REFERENCE struct samr_sid *sid;
 584         OUT     samr_handle_t domain_handle;
 585         OUT     DWORD status;
 586 };
 587 
 588 
 589 /*
 590  ***********************************************************************
 591  * QueryDomainInfo
 592  *
 593  * Windows 95 Server Manager sends requests for levels 6 and 7 when
 594  * the services menu item is selected.
 595  ***********************************************************************
 596  */
 597 #define SAMR_QUERY_DOMAIN_INFO_2                2
 598 #define SAMR_QUERY_DOMAIN_INFO_6                6
 599 #define SAMR_QUERY_DOMAIN_INFO_7                7
 600 
 601 
 602 struct samr_QueryDomainInfo2 {
 603         DWORD unknown1;                 /* 00 00 00 00 */
 604         DWORD unknown2;                 /* 00 00 00 80 */
 605         samr_string_t s1;
 606         samr_string_t domain;
 607         samr_string_t s2;
 608         DWORD sequence_num;             /* 2B 00 00 00 */
 609         DWORD unknown3;                 /* 00 00 00 00 */
 610         DWORD unknown4;                 /* 01 00 00 00 */
 611         DWORD unknown5;                 /* 03 00 00 00 */
 612         DWORD unknown6;                 /* 01 */
 613         DWORD num_users;
 614         DWORD num_groups;
 615         DWORD num_aliases;
 616 };
 617 
 618 
 619 struct samr_QueryDomainInfo6 {
 620         DWORD unknown1;                 /* 00 00 00 00 */
 621         DWORD unknown2;                 /* B0 7F 14 00 */
 622         DWORD unknown3;                 /* 00 00 00 00 */
 623         DWORD unknown4;                 /* 00 00 00 00 */
 624         DWORD unknown5;                 /* 00 00 00 00 */
 625 };
 626 
 627 
 628 struct samr_QueryDomainInfo7 {
 629         DWORD unknown1;                 /* 03 00 00 00 */
 630 };
 631 
 632 
 633 union samr_QueryDomainInfo_ru {
 634         UNION_INFO_ENT(2,samr_QueryDomainInfo);
 635         UNION_INFO_ENT(6,samr_QueryDomainInfo);
 636         UNION_INFO_ENT(7,samr_QueryDomainInfo);
 637         DEFAULT char *nullptr;
 638 };
 639 
 640 struct samr_QueryDomainInfoRes {
 641         WORD switch_value;
 642         SWITCH(switch_value)
 643                 union samr_QueryDomainInfo_ru ru;
 644 };
 645 
 646 OPERATION(SAMR_OPNUM_QueryDomainInfo)
 647 struct samr_QueryDomainInfo {
 648         IN      samr_handle_t domain_handle;
 649         IN      WORD info_level;
 650         OUT     struct samr_QueryDomainInfoRes *info;
 651         OUT     DWORD status;
 652 };
 653 
 654 /*
 655  * Identical to SAMR_OPNUM_QueryDomainInfo.
 656  */
 657 OPERATION(SAMR_OPNUM_QueryInfoDomain2)
 658 struct samr_QueryInfoDomain2 {
 659         IN      samr_handle_t   domain_handle;
 660         IN      WORD            info_level;
 661         OUT     struct samr_QueryDomainInfoRes *info;
 662         OUT     DWORD           status;
 663 };
 664 
 665 #define SAMR_QUERY_ALIAS_INFO_GENERAL           1
 666 #define SAMR_QUERY_ALIAS_INFO_NAME              2
 667 #define SAMR_QUERY_ALIAS_INFO_COMMENT           3
 668 
 669 struct samr_QueryAliasInfoGeneral {
 670         WORD level;
 671         samr_string_t name;
 672         DWORD member_count;
 673         samr_string_t desc;
 674 };
 675 
 676 struct samr_QueryAliasInfoName {
 677         WORD level;
 678         samr_string_t name;
 679 };
 680 
 681 struct samr_QueryAliasInfoComment {
 682         WORD level;
 683         samr_string_t desc;
 684 };
 685 
 686 union samr_QueryAliasInfo_ru {
 687         CASE(1) struct samr_QueryAliasInfoGeneral info1;
 688         CASE(2) struct samr_QueryAliasInfoName    info2;
 689         CASE(3) struct samr_QueryAliasInfoComment info3;
 690         DEFAULT char *nullptr;
 691 };
 692 
 693 struct samr_QueryAliasInfoRes {
 694         DWORD address;
 695         WORD switch_value;
 696         SWITCH(switch_value)
 697                 union samr_QueryAliasInfo_ru ru;
 698 };
 699 
 700 OPERATION(SAMR_OPNUM_QueryAliasInfo)
 701 struct samr_QueryAliasInfo {
 702         IN      samr_handle_t alias_handle;
 703         IN      WORD level;
 704         OUT DWORD address;
 705   SWITCH (level)
 706         OUT     union samr_QueryAliasInfo_ru ru;
 707         OUT     DWORD status;
 708 };
 709 
 710 OPERATION(SAMR_OPNUM_CreateDomainAlias)
 711 struct samr_CreateDomainAlias {
 712         IN      samr_handle_t domain_handle;
 713         IN      samr_string_t alias_name;
 714         IN      DWORD access_mask;
 715         OUT samr_handle_t alias_handle;
 716         OUT     DWORD rid;
 717         OUT     DWORD status;
 718 };
 719 
 720 OPERATION(SAMR_OPNUM_SetAliasInfo)
 721 struct samr_SetAliasInfo {
 722         IN      samr_handle_t alias_handle;
 723         IN      WORD level;
 724         /* TBD */
 725         OUT     DWORD status;
 726 };
 727 
 728 OPERATION(SAMR_OPNUM_DeleteDomainAlias)
 729 struct samr_DeleteDomainAlias {
 730         INOUT   samr_handle_t alias_handle;
 731         OUT     DWORD status;
 732 };
 733 
 734 OPERATION(SAMR_OPNUM_OpenAlias)
 735 struct samr_OpenAlias {
 736         IN      samr_handle_t domain_handle;
 737         IN      DWORD access_mask;
 738         IN      DWORD rid;
 739         OUT samr_handle_t alias_handle;
 740         OUT     DWORD status;
 741 };
 742 
 743 struct name_rid {
 744         DWORD rid;
 745         samr_string_t name;
 746 };
 747 
 748 struct aliases_info {
 749         DWORD count;
 750         DWORD address;
 751         SIZE_IS(count)
 752         struct name_rid info[ANY_SIZE_ARRAY];
 753 };
 754 
 755 OPERATION(SAMR_OPNUM_EnumDomainAliases)
 756 struct samr_EnumDomainAliases {
 757         IN      samr_handle_t domain_handle;
 758         IN      DWORD resume_handle;
 759         IN      DWORD mask;
 760         OUT     DWORD out_resume;
 761         OUT struct aliases_info *aliases;
 762         OUT DWORD entries;
 763         OUT     DWORD status;
 764 };
 765 
 766 struct user_acct_info {
 767         DWORD index;
 768         DWORD rid;
 769         DWORD ctrl;
 770         samr_string_t name;
 771         samr_string_t fullname;
 772         samr_string_t desc;
 773 };
 774 
 775 struct user_disp_info {
 776         OUT DWORD total_size;
 777         OUT DWORD returned_size;
 778         OUT WORD switch_value;
 779         DWORD count;
 780         SIZE_IS(count)
 781         struct user_acct_info *acct;
 782 };
 783 
 784 OPERATION(SAMR_OPNUM_QueryDispInfo)
 785 struct samr_QueryDispInfo {
 786         IN      samr_handle_t domain_handle;
 787         IN      WORD level;
 788         IN      DWORD start_idx;
 789         IN      DWORD max_entries;
 790         IN      DWORD pref_maxsize;
 791         OUT struct user_disp_info users;
 792         OUT     DWORD status;
 793 };
 794 
 795 struct group_acct_info {
 796         DWORD index;
 797         DWORD rid;
 798         DWORD ctrl;
 799         samr_string_t name;
 800         samr_string_t desc;
 801 };
 802 
 803 struct group_disp_info {
 804         DWORD count;
 805         /* right now we just need one entry */
 806         struct group_acct_info acct[1];
 807 };
 808 
 809 OPERATION(SAMR_OPNUM_EnumDomainGroups)
 810 struct samr_EnumDomainGroups {
 811         IN      samr_handle_t domain_handle;
 812         IN      WORD level;
 813         IN      DWORD start_idx;
 814         IN      DWORD max_entries;
 815         IN      DWORD pref_maxsize;
 816         OUT DWORD total_size;
 817         OUT DWORD returned_size;
 818         OUT WORD switch_value;
 819         OUT DWORD count;
 820         OUT struct group_disp_info *groups;
 821         OUT     DWORD status;
 822 };
 823 
 824 /*
 825  ***********************************************************************
 826  * OpenUser
 827  *
 828  * Input must be a domain handle obtained via SAMR_OPNUM_OpenDomain,
 829  * an access mask and the appropriate user rid. The output will be a
 830  * handle for use with the specified user.
 831  ***********************************************************************
 832  */
 833 OPERATION(SAMR_OPNUM_OpenUser)
 834 struct samr_OpenUser {
 835         IN      samr_handle_t handle;
 836         IN      DWORD access_mask;
 837         IN      DWORD rid;
 838         OUT     samr_handle_t user_handle;
 839         OUT     DWORD status;
 840 };
 841 
 842 
 843 /*
 844  ***********************************************************************
 845  * DeleteUser
 846  ***********************************************************************
 847  */
 848 OPERATION(SAMR_OPNUM_DeleteUser)
 849 struct samr_DeleteUser {
 850         INOUT   samr_handle_t user_handle;
 851         OUT     DWORD status;
 852 };
 853 
 854 
 855 /*
 856  ***********************************************************************
 857  * QueryUserInfo
 858  *
 859  * Provides various pieces of information on a specific user (see
 860  * SAM_Q_QUERY_USERINFO and SAM_R_QUERY_USERINFO). The handle must
 861  * be a valid SAM user handle.
 862  *
 863  * QueryUserInfo (
 864  *      IN samr_handle_t user_handle,
 865  *      IN WORD switch_value,
 866  *      OUT union switch(switch_value) {
 867  *              case 1: struct QueryUserInfo1 *info1;
 868  *      } bufptr,
 869  *      OUT DWORD status
 870  * )
 871  *
 872  * typedef enum _USER_INFORMATION_CLASS {
 873  *      UserGeneralInformation          = 1,
 874  *      UserPreferencesInformation      = 2,
 875  *      UserLogonInformation            = 3,
 876  *      UserLogonHoursInformation       = 4,
 877  *      UserAccountInformation          = 5,
 878  *      UserNameInformation             = 6,
 879  *      UserAccountNameInformation      = 7,
 880  *      UserFullNameInformation         = 8,
 881  *      UserPrimaryGroupInformation     = 9,
 882  *      UserHomeInformation             = 10,
 883  *      UserScriptInformation           = 11,
 884  *      UserProfileInformation          = 12,
 885  *      UserAdminCommentInformation     = 13,
 886  *      UserWorkStationsInformation     = 14,
 887  *      UserControlInformation          = 16,
 888  *      UserExpiresInformation          = 17,
 889  *      UserInternal1Information        = 18,
 890  *      UserParametersInformation       = 20,
 891  *      UserAllInformation              = 21,
 892  *      UserInternal4Information        = 23,
 893  *      UserInternal5Information        = 24,
 894  *      UserInternal4InformationNew     = 25,
 895  *      UserInternal5InformationNew     = 26,
 896  * } USER_INFORMATION_CLASS;
 897  *
 898  * 1 = username, fullname, description and some other stuff.
 899  * 3 = large structure containing user rid, group rid, username
 900  *     and fullname.
 901  * 5 = large structure (like 3) containing user rid, group rid,
 902  *     username, fullname and description.
 903  * 6 = username and fullname
 904  * 7 = username
 905  * 8 = fullname
 906  * 9 = group rid
 907  * 16 = used after creating a new account
 908  *
 909  * Due to an ndrgen bug, a function must be provided to to patch the
 910  * offsets used by the unmarshalling code at runtime.  In order to
 911  * simplify things it is useful to use a naming convention that
 912  * indicates the switch value for each structure.
 913  * 
 914  ***********************************************************************
 915  */
 916 
 917 
 918 #define SAMR_QUERY_USER_INFO_1                  1
 919 #define SAMR_QUERY_USER_UNAME_AND_FNAME         6
 920 #define SAMR_QUERY_USER_USERNAME                7
 921 #define SAMR_QUERY_USER_FULLNAME                8
 922 #define SAMR_QUERY_USER_GROUPRID                9
 923 #define SAMR_QUERY_USER_CONTROL_INFO            16
 924 #define SAMR_QUERY_USER_ALL_INFO                21
 925 
 926 
 927 struct samr_QueryUserInfo1 {
 928         samr_string_t username;
 929         samr_string_t fullname;
 930         DWORD group_rid;
 931         samr_string_t description;
 932         samr_string_t unknown;
 933 };
 934 
 935 
 936 struct samr_QueryUserInfo6 {
 937         samr_string_t username;
 938         samr_string_t fullname;
 939 };
 940 
 941 struct samr_QueryUserInfo7 {
 942         samr_string_t username;
 943 };
 944 
 945 
 946 struct samr_QueryUserInfo8 {
 947         samr_string_t fullname;
 948 };
 949 
 950 
 951 struct samr_QueryUserInfo9 {
 952         DWORD group_rid;
 953 };
 954 
 955 
 956 struct samr_QueryUserInfo16 {
 957         DWORD UserAccountControl;
 958 };
 959 
 960 /*
 961  * SAMR_USER_ALL_INFORMATION
 962  */
 963 struct samr_QueryUserInfo21 {
 964         samr_quad_t             LastLogon;
 965         samr_quad_t             LastLogoff;
 966         samr_quad_t             PasswordLastSet;
 967         samr_quad_t             AccountExpires;
 968         samr_quad_t             PasswordCanChange;
 969         samr_quad_t             PasswordMustChange;
 970         samr_string_t           UserName;
 971         samr_string_t           FullName;
 972         samr_string_t           HomeDirectory;
 973         samr_string_t           HomeDirectoryDrive;
 974         samr_string_t           ScriptPath;
 975         samr_string_t           ProfilePath;
 976         samr_string_t           AdminComment;
 977         samr_string_t           WorkStations;
 978         samr_string_t           UserComment;
 979         samr_string_t           Parameters;
 980         struct samr_short_blob  LmOwfPassword;
 981         struct samr_short_blob  NtOwfPassword;
 982         samr_string_t           PrivateData;
 983         samr_sd_t               SecurityDescriptor;
 984         DWORD                   UserId;
 985         DWORD                   PrimaryGroupId;
 986         DWORD                   UserAccountControl;
 987         DWORD                   WhichFields;
 988         struct samr_logon_hours_all     LogonHours;
 989         WORD                    BadPasswordCount;
 990         WORD                    LogonCount;
 991         WORD                    CountryCode;
 992         WORD                    CodePage;
 993         BYTE                    LmPasswordPresent;
 994         BYTE                    NtPasswordPresent;
 995         BYTE                    PasswordExpired;
 996         BYTE                    PrivateDataSensitive;
 997 };
 998 
 999 /* See also: fixup_samr_QueryUserInfo() */
1000 union QueryUserInfo_result_u {
1001         UNION_INFO_ENT(1,samr_QueryUserInfo);
1002         UNION_INFO_ENT(6,samr_QueryUserInfo);
1003         UNION_INFO_ENT(7,samr_QueryUserInfo);
1004         UNION_INFO_ENT(8,samr_QueryUserInfo);
1005         UNION_INFO_ENT(9,samr_QueryUserInfo);
1006         UNION_INFO_ENT(16,samr_QueryUserInfo);
1007         UNION_INFO_ENT(21,samr_QueryUserInfo);
1008         DEFAULT char *nullptr;
1009 };
1010 
1011 
1012 /*
1013  * This structure needs to be declared, even though it can't be used in
1014  * samr_QueryUserInfo, in order to get the appropriate size to calculate
1015  * the correct fixup offsets.  If ndrgen did the right thing,
1016  * QueryUserInfo_result would be one of the out parameters.  However, if
1017  * we do it that way, the switch_value isn't known early enough to do
1018  * the fixup calculation.  So it all has to go in samr_QueryUserInfo.
1019  */
1020 struct QueryUserInfo_result {
1021         DWORD address;
1022         WORD switch_value;
1023         SWITCH(switch_value)
1024                 union QueryUserInfo_result_u ru;
1025 };
1026 
1027 
1028 OPERATION(SAMR_OPNUM_QueryUserInfo)
1029 struct samr_QueryUserInfo {
1030         IN      samr_handle_t user_handle;
1031         IN      WORD switch_value;
1032         /*
1033          * Can't use this form because we need to include members explicitly.
1034          * OUT  struct QueryUserInfo_result result;
1035          */
1036         OUT     DWORD address;
1037         OUT     WORD switch_index;
1038   SWITCH(switch_value)
1039         OUT     union QueryUserInfo_result_u ru;
1040         OUT     DWORD status;
1041 };
1042 
1043 
1044 /*
1045  ***********************************************************************
1046  * QueryUserGroups
1047  ***********************************************************************
1048  */
1049 struct samr_UserGroups {
1050         DWORD rid;
1051         DWORD attr;
1052 };
1053 
1054 
1055 struct samr_UserGroupInfo {
1056         DWORD n_entry;
1057   SIZE_IS(n_entry)
1058         struct samr_UserGroups *groups;
1059 };
1060 
1061 
1062 OPERATION(SAMR_OPNUM_QueryUserGroups)
1063 struct samr_QueryUserGroups {
1064         IN      samr_handle_t user_handle;
1065         OUT struct samr_UserGroupInfo *info;
1066         OUT     DWORD status;
1067 };
1068 
1069 
1070 /*
1071  ***********************************************************************
1072  * LookupName
1073  ***********************************************************************
1074  */
1075 struct samr_LookupNameTable {
1076         DWORD n_entry;
1077   SIZE_IS(n_entry)
1078         samr_string_t names[ANY_SIZE_ARRAY];
1079 };
1080 
1081 
1082 struct samr_LookupRidTable {
1083         DWORD n_entry;
1084   SIZE_IS(n_entry)
1085         DWORD *rid;
1086 };
1087 
1088 struct samr_RidType {
1089         DWORD n_entry;
1090   SIZE_IS(n_entry)
1091         DWORD *rid_type;
1092 };
1093 
1094 
1095 OPERATION(SAMR_OPNUM_LookupNames)
1096 struct samr_LookupNames {
1097         IN      samr_handle_t handle;
1098         IN      DWORD n_entry;
1099         IN      DWORD max_n_entry;
1100         IN      DWORD index;
1101         IN      DWORD total;
1102         IN      samr_string_t name;
1103         OUT     struct samr_LookupRidTable rids;
1104         OUT     struct samr_RidType rid_types;
1105         OUT     DWORD status;
1106 };
1107 
1108 
1109 /*
1110  ***********************************************************************
1111  * OpenGroup
1112  *
1113  * Input must be a domain handle obtained via SAMR_OPNUM_OpenDomain,
1114  * an access mask and the appropriate group rid. The output will be a
1115  * handle for use with the specified group.
1116  ***********************************************************************
1117  */
1118 OPERATION(SAMR_OPNUM_OpenGroup)
1119 struct samr_OpenGroup {
1120         IN      samr_handle_t handle;
1121         IN      DWORD access_mask;
1122         IN      DWORD rid;
1123         OUT     samr_handle_t group_handle;
1124         OUT     DWORD status;
1125 };
1126 
1127 
1128 /*
1129  ***********************************************************************
1130  * QueryGroupInfo
1131  *
1132  * Input must be a group handle obtained via SAMR_OPNUM_OpenGroup,
1133  * an access mask and the appropriate group rid. The output will
1134  * be a handle for use with the specified group.
1135  ***********************************************************************
1136  */
1137 struct samr_QueryGroupInfo1 {
1138         samr_string_t groupname;
1139 };
1140 
1141 
1142 union samr_QueryGroupInfo_result_u {
1143         UNION_INFO_ENT(1,samr_QueryGroupInfo);
1144         DEFAULT char *nullptr;
1145 };
1146 
1147 
1148 struct samr_QueryGroupInfo_result {
1149         DWORD address;
1150         WORD switch_index;
1151   SWITCH(switch_index)
1152         union samr_QueryGroupInfo_result_u ru;
1153 };
1154 
1155 
1156 OPERATION(SAMR_OPNUM_QueryGroupInfo)
1157 struct samr_QueryGroupInfo {
1158         IN      samr_handle_t group_handle;
1159         IN      DWORD switch_value;
1160         OUT     DWORD address;
1161         OUT     WORD switch_index;
1162   SWITCH(switch_index)
1163         OUT     union samr_QueryGroupInfo_result_u ru;
1164         OUT     DWORD status;
1165 };
1166 
1167 
1168 /*
1169  ***********************************************************************
1170  * StoreGroupInfo
1171  *
1172  * This definition is mostly just a place holder in case this is useful
1173  * in the future. Note that it may not be correct. The information is
1174  * from a netmon trace captured when I added a group description. I
1175  * haven't implemented it because we don't have to update anything on
1176  * the PDC. The description should almost certainly be in a separate
1177  * structure.
1178  ***********************************************************************
1179  */
1180 OPERATION(SAMR_OPNUM_StoreGroupInfo)
1181 struct samr_StoreGroupInfo {
1182         IN      samr_handle_t group_handle;
1183         IN      DWORD switch_value;
1184         IN      samr_string_t group_description;
1185         OUT     DWORD status;
1186 };
1187 
1188 /*
1189  * AddAliasMember
1190  */
1191 OPERATION(SAMR_OPNUM_AddAliasMember)
1192 struct samr_AddAliasMember {
1193         IN              samr_handle_t alias_handle;
1194         IN REFERENCE    struct samr_sid *sid;
1195         OUT DWORD       status;
1196 };
1197 
1198 /*
1199  * DeleteAliasMember
1200  */
1201 OPERATION(SAMR_OPNUM_DeleteAliasMember)
1202 struct samr_DeleteAliasMember {
1203         IN              samr_handle_t alias_handle;
1204         IN REFERENCE    struct samr_sid *sid;
1205         OUT DWORD       status;
1206 };
1207 
1208 struct samr_SidList {
1209         struct samr_sid         *sid;
1210 };
1211 
1212 struct samr_SidInfo {
1213         DWORD n_entry;
1214   SIZE_IS(n_entry)
1215         struct samr_SidList     *sidlist;
1216 };
1217 
1218 /*
1219  * ListAliasMembers
1220  */
1221 OPERATION(SAMR_OPNUM_ListAliasMembers)
1222 struct samr_ListAliasMembers {
1223         IN              samr_handle_t alias_handle;
1224         OUT             struct samr_SidInfo info;
1225         OUT DWORD       status;
1226 };
1227 
1228 /*
1229  ***********************************************************************
1230  * GetUserDomainPasswordInformation
1231  ***********************************************************************
1232  */
1233 OPERATION(SAMR_OPNUM_GetUserPwInfo)
1234 struct samr_GetUserPwInfo {
1235         IN              samr_handle_t           user_handle;
1236         OUT REFERENCE   samr_password_info_t    *pwinfo;
1237         OUT             DWORD                   status;
1238 };
1239 
1240 
1241 /*
1242  ***********************************************************************
1243  * CreateUser
1244  *
1245  * Create a user in the domain specified by the domain handle. The
1246  * domain handle is obtained obtained via SAMR_OPNUM_OpenDomain.
1247  * DesiredAccess: 0xe00500b0.
1248  * The output will be a handle for use with the specified user and the
1249  * user's RID. I think the RID may be a unique pointer (it can be null).
1250  ***********************************************************************
1251  */
1252 OPERATION(SAMR_OPNUM_CreateUser)
1253 struct samr_CreateUser {
1254         IN      samr_handle_t handle;
1255         IN      samr_vcbuf_t username;
1256         IN      DWORD account_flags;
1257         IN      DWORD desired_access;
1258         OUT     samr_handle_t user_handle;
1259         OUT     DWORD maybe_ptr;
1260         OUT     DWORD rid;
1261         OUT     DWORD status;
1262 };
1263 
1264 
1265 /*
1266  ***********************************************************************
1267  * ChangePasswordUser2 - See:
1268  * SamrUnicodeChangePasswordUser2 [MS-SAMR 3.1.5.10.3]
1269  ***********************************************************************
1270  */
1271 
1272 OPERATION(SAMR_OPNUM_ChangePasswordUser2)
1273 struct samr_ChangePasswordUser2 {
1274         IN      samr_string_t *servername;
1275         IN REF  samr_string_t *username;
1276         IN      struct samr_encr_passwd *nt_newpw;
1277         IN      struct samr_encr_hash *nt_oldpw;
1278         IN      BYTE lm_present;
1279         IN      struct samr_encr_passwd *lm_newpw;
1280         IN      struct samr_encr_hash *lm_oldpw;
1281         OUT     DWORD status;
1282 };
1283 
1284 
1285 /*
1286  ***********************************************************************
1287  * GetDomainPwInfo
1288  ***********************************************************************
1289  */
1290 OPERATION(SAMR_OPNUM_GetDomainPwInfo)
1291 struct samr_GetDomainPwInfo {
1292         IN              DWORD                   unused;
1293         OUT REFERENCE   samr_password_info_t    *pwinfo;
1294         OUT             DWORD                   status;
1295 };
1296 
1297 
1298 /*
1299  ***********************************************************************
1300  * SetUserInfo
1301  * [MS-SAMR] SamrSetInformationUser2
1302  ***********************************************************************
1303  */
1304 
1305 /* USER_CONTROL_INFORMATION */
1306 struct samr_SetUserInfo16 {
1307         DWORD UserAccountControl;
1308 };
1309 
1310 
1311 /*
1312  * samr_SetUserInfo21, a.k.a
1313  * SAMR_USER_ALL_INFORMATION
1314  *
1315  * We now know this is the same as samr_QueryUserInfo21
1316  * Could merge, except for the samr_vcbuf_t mess.
1317  */
1318 
1319 #define SAMR_SET_USER_INFO_21           21
1320 
1321 struct samr_SetUserInfo21 {
1322         samr_quad_t             LastLogon;
1323         samr_quad_t             LastLogoff;
1324         samr_quad_t             PasswordLastSet;
1325         samr_quad_t             AccountExpires;
1326         samr_quad_t             PasswordCanChange;
1327         samr_quad_t             PasswordMustChange;
1328 
1329         samr_vcbuf_t            UserName;
1330         samr_vcbuf_t            FullName;
1331         samr_vcbuf_t            HomeDirectory;
1332         samr_vcbuf_t            HomeDirectoryDrive;
1333         samr_vcbuf_t            ScriptPath;
1334         samr_vcbuf_t            ProfilePath;
1335         samr_vcbuf_t            AdminComment;
1336         samr_vcbuf_t            WorkStations;
1337         samr_vcbuf_t            UserComment;
1338         samr_vcbuf_t            Parameters;
1339 
1340         struct samr_short_blob  LmOwfPassword;
1341         struct samr_short_blob  NtOwfPassword;
1342         samr_vcbuf_t            PrivateData;
1343         samr_sd_t               SecurityDescriptor;
1344 
1345         DWORD                   UserId; /* RID */
1346         DWORD                   PrimaryGroupId;
1347         DWORD                   UserAccountControl;
1348         DWORD                   WhichFields;
1349 
1350         /*
1351          * This should be samr_logon_hours_all, but apparently
1352          * ndrgen doesn't get that quite right, so instead, the
1353          * client-side code patches this up.
1354          */
1355         struct samr_logon_info  LogonHours;
1356 
1357         WORD                    BadPasswordCount;
1358         WORD                    LogonCount;
1359         WORD                    CountryCode;
1360         WORD                    CodePage;
1361         BYTE                    LmPasswordPresent;
1362         BYTE                    NtPasswordPresent;
1363         BYTE                    PasswordExpired;
1364         BYTE                    PrivateDataSensitive;
1365 };
1366 
1367 /*
1368  *      SAMPR_USER_INTERNAL4_INFORMATION
1369  *      UserInternal4Information (23)
1370  */
1371 #define SAMR_SET_USER_INFO_23           23
1372 struct samr_SetUserInfo23 {
1373         struct samr_SetUserInfo21 info21;
1374         struct samr_encr_passwd encr_pw;
1375 };
1376 
1377 /*
1378  *      SAMPR_USER_INTERNAL5_INFORMATION
1379  *      UserInternal5Information (24)
1380  */
1381 #define SAMR_SET_USER_INFO_24           24
1382 struct samr_SetUserInfo24 {
1383         struct samr_encr_passwd encr_pw;
1384         BYTE password_expired;
1385 };
1386 
1387 
1388 union samr_SetUserInfo_u {
1389         UNION_INFO_ENT(16,samr_SetUserInfo);
1390         UNION_INFO_ENT(21,samr_SetUserInfo);
1391         UNION_INFO_ENT(23,samr_SetUserInfo);
1392         UNION_INFO_ENT(24,samr_SetUserInfo);
1393         DEFAULT  DWORD nothing;
1394 };
1395 
1396 struct samr_SetUserInfo_s {
1397         WORD info_level;
1398         WORD switch_value;
1399   SWITCH(switch_value)
1400         union samr_SetUserInfo_u ru;
1401 };
1402 
1403 OPERATION(SAMR_OPNUM_SetUserInfo)
1404 struct samr_SetUserInfo {
1405         IN      samr_handle_t user_handle;
1406         IN      struct samr_SetUserInfo_s info;
1407         OUT     DWORD status;
1408 };
1409 
1410 
1411 /*
1412  ***********************************************************************
1413  * The SAMR interface definition.
1414  ***********************************************************************
1415  */
1416 INTERFACE(0)
1417 union samr_interface {
1418         CASE(SAMR_OPNUM_Connect)
1419                 struct samr_Connect             Connect;
1420         CASE(SAMR_OPNUM_CloseHandle)
1421                 struct samr_CloseHandle         CloseHandle;
1422         CASE(SAMR_OPNUM_QuerySecObject)
1423                 struct samr_QuerySecObject      QuerySecObject;
1424         CASE(SAMR_OPNUM_LookupDomain)
1425                 struct samr_LookupDomain        LookupDomain;
1426         CASE(SAMR_OPNUM_EnumLocalDomains)
1427                 struct samr_EnumLocalDomain     EnumLocalDomain;
1428         CASE(SAMR_OPNUM_OpenDomain)
1429                 struct samr_OpenDomain          OpenDomain;
1430         CASE(SAMR_OPNUM_QueryDomainInfo)
1431                 struct samr_QueryDomainInfo     QueryDomainInfo;
1432         CASE(SAMR_OPNUM_QueryInfoDomain2)
1433                 struct samr_QueryInfoDomain2    QueryInfoDomain2;
1434         CASE(SAMR_OPNUM_LookupNames)
1435                 struct samr_LookupNames         LookupNames;
1436         CASE(SAMR_OPNUM_OpenUser)
1437                 struct samr_OpenUser            OpenUser;
1438         CASE(SAMR_OPNUM_DeleteUser)
1439                 struct samr_DeleteUser          DeleteUser;
1440         CASE(SAMR_OPNUM_QueryUserInfo)
1441                 struct samr_QueryUserInfo       QueryUserInfo;
1442         CASE(SAMR_OPNUM_QueryUserGroups)
1443                 struct samr_QueryUserGroups     QueryUserGroups;
1444         CASE(SAMR_OPNUM_OpenGroup)
1445                 struct samr_OpenGroup           OpenGroup;
1446         CASE(SAMR_OPNUM_AddAliasMember)
1447                 struct samr_AddAliasMember      AddAliasMember;
1448         CASE(SAMR_OPNUM_DeleteAliasMember)
1449                 struct samr_DeleteAliasMember   DeleteAliasMember;
1450         CASE(SAMR_OPNUM_ListAliasMembers)
1451                 struct samr_ListAliasMembers    ListAliasMembers;
1452         CASE(SAMR_OPNUM_GetUserPwInfo)
1453                 struct samr_GetUserPwInfo       GetUserPwInfo;
1454         CASE(SAMR_OPNUM_CreateUser)
1455                 struct samr_CreateUser          CreateUser;
1456         CASE(SAMR_OPNUM_ChangePasswordUser2)
1457                 struct samr_ChangePasswordUser2 ChangePasswordUser2;
1458         CASE(SAMR_OPNUM_GetDomainPwInfo)
1459                 struct samr_GetDomainPwInfo     GetDomainPwInfo;
1460         CASE(SAMR_OPNUM_Connect2)
1461                 struct samr_Connect2            Connect2;
1462         CASE(SAMR_OPNUM_SetUserInfo)
1463                 struct samr_SetUserInfo         SetUserInfo;
1464         CASE(SAMR_OPNUM_Connect4)
1465                 struct samr_Connect4            Connect4;
1466         CASE(SAMR_OPNUM_Connect5)
1467                 struct samr_Connect5            Connect5;
1468         CASE(SAMR_OPNUM_QueryDispInfo)
1469                 struct samr_QueryDispInfo       QueryDispInfo;
1470         CASE(SAMR_OPNUM_OpenAlias)
1471                 struct samr_OpenAlias           OpenAlias;
1472         CASE(SAMR_OPNUM_CreateDomainAlias)
1473                 struct samr_CreateDomainAlias   CreateDomainAlias;
1474         CASE(SAMR_OPNUM_SetAliasInfo)
1475                 struct samr_SetAliasInfo        SetAliasInfo;
1476         CASE(SAMR_OPNUM_QueryAliasInfo)
1477                 struct samr_QueryAliasInfo      QueryAliasInfo;
1478         CASE(SAMR_OPNUM_DeleteDomainAlias)
1479                 struct samr_DeleteDomainAlias   DeleteDomainAlias;
1480         CASE(SAMR_OPNUM_EnumDomainAliases)
1481                 struct samr_EnumDomainAliases   EnumDomainAliases;
1482         CASE(SAMR_OPNUM_EnumDomainGroups)
1483                 struct samr_EnumDomainGroups    EnumDomainGroups;
1484 };
1485 typedef union samr_interface    samr_interface_t;
1486 EXTERNTYPEINFO(samr_interface)
1487 
1488 #endif /* _MLSVC_SAM_NDL_ */