root/source4/torture/rpc/samr.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. init_lsa_String
  2. init_lsa_StringLarge
  3. init_lsa_BinaryString
  4. test_samr_handle_Close
  5. test_Shutdown
  6. test_SetDsrmPassword
  7. test_QuerySecurity
  8. test_SetUserInfo
  9. samr_rand_pass_silent
  10. samr_rand_pass
  11. samr_very_rand_pass
  12. samr_rand_pass_fixed_len
  13. test_SetUserPass
  14. test_SetUserPass_23
  15. test_SetUserPassEx
  16. test_SetUserPass_25
  17. test_SetUserPass_18
  18. test_SetUserPass_21
  19. test_SetUserPass_level_ex
  20. test_SetAliasInfo
  21. test_GetGroupsForUser
  22. test_GetDomPwInfo
  23. test_GetUserPwInfo
  24. test_LookupName
  25. test_OpenUser_byname
  26. test_ChangePasswordNT3
  27. test_ChangePasswordUser
  28. test_OemChangePasswordUser2
  29. test_ChangePasswordUser2
  30. test_ChangePasswordUser3
  31. test_ChangePasswordRandomBytes
  32. test_GetMembersInAlias
  33. test_AddMemberToAlias
  34. test_AddMultipleMembersToAlias
  35. test_TestPrivateFunctionsUser
  36. test_QueryUserInfo_pwdlastset
  37. test_SamLogon_Creds
  38. test_SamLogon
  39. test_SamLogon_with_creds
  40. test_SetPassword_level
  41. test_SetPassword_pwdlastset
  42. test_DeleteUser_with_privs
  43. test_user_ops
  44. test_alias_ops
  45. test_DeleteUser
  46. test_DeleteUser_byname
  47. test_DeleteGroup_byname
  48. test_DeleteAlias_byname
  49. test_DeleteAlias
  50. test_CreateAlias
  51. test_ChangePassword
  52. test_CreateUser
  53. test_CreateUser2
  54. test_QueryAliasInfo
  55. test_QueryGroupInfo
  56. test_QueryGroupMember
  57. test_SetGroupInfo
  58. test_QueryUserInfo
  59. test_QueryUserInfo2
  60. test_OpenUser
  61. test_OpenGroup
  62. test_OpenAlias
  63. check_mask
  64. test_EnumDomainUsers_all
  65. test_EnumDomainUsers_async
  66. test_EnumDomainGroups_all
  67. test_EnumDomainAliases_all
  68. test_GetDisplayEnumerationIndex
  69. test_GetDisplayEnumerationIndex2
  70. test_each_DisplayInfo_user
  71. test_QueryDisplayInfo
  72. test_QueryDisplayInfo2
  73. test_QueryDisplayInfo3
  74. test_QueryDisplayInfo_continue
  75. test_QueryDomainInfo
  76. test_QueryDomainInfo2
  77. test_GroupList
  78. test_DeleteDomainGroup
  79. test_TestPrivateFunctionsDomain
  80. test_RidToSid
  81. test_GetBootKeyInformation
  82. test_AddGroupMember
  83. test_CreateDomainGroup
  84. test_RemoveMemberFromForeignDomain
  85. test_EnumDomainUsers
  86. test_EnumDomainGroups
  87. test_EnumDomainAliases
  88. test_ManyObjects
  89. test_OpenDomain
  90. test_LookupDomain
  91. test_EnumDomains
  92. test_Connect
  93. torture_rpc_samr
  94. torture_rpc_samr_users
  95. torture_rpc_samr_passwords
  96. torture_rpc_samr_pwdlastset
  97. torture_rpc_samr_passwords_pwdlastset
  98. torture_rpc_samr_users_privileges_delete_user
  99. torture_rpc_samr_user_privileges
  100. torture_rpc_samr_many_accounts
  101. torture_rpc_samr_many_groups
  102. torture_rpc_samr_many_aliases
  103. torture_rpc_samr_large_dc

   1 /*
   2    Unix SMB/CIFS implementation.
   3    test suite for samr rpc operations
   4 
   5    Copyright (C) Andrew Tridgell 2003
   6    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
   7    Copyright (C) Guenther Deschner 2008,2009
   8 
   9    This program is free software; you can redistribute it and/or modify
  10    it under the terms of the GNU General Public License as published by
  11    the Free Software Foundation; either version 3 of the License, or
  12    (at your option) any later version.
  13 
  14    This program is distributed in the hope that it will be useful,
  15    but WITHOUT ANY WARRANTY; without even the implied warranty of
  16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17    GNU General Public License for more details.
  18 
  19    You should have received a copy of the GNU General Public License
  20    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  21 */
  22 
  23 #include "includes.h"
  24 #include "torture/torture.h"
  25 #include "system/time.h"
  26 #include "librpc/gen_ndr/lsa.h"
  27 #include "librpc/gen_ndr/ndr_netlogon.h"
  28 #include "librpc/gen_ndr/ndr_netlogon_c.h"
  29 #include "librpc/gen_ndr/ndr_samr_c.h"
  30 #include "librpc/gen_ndr/ndr_lsa_c.h"
  31 #include "../lib/crypto/crypto.h"
  32 #include "libcli/auth/libcli_auth.h"
  33 #include "libcli/security/security.h"
  34 #include "torture/rpc/rpc.h"
  35 #include "param/param.h"
  36 
  37 #include <unistd.h>
  38 
  39 #define TEST_ACCOUNT_NAME "samrtorturetest"
  40 #define TEST_ACCOUNT_NAME_PWD "samrpwdlastset"
  41 #define TEST_ALIASNAME "samrtorturetestalias"
  42 #define TEST_GROUPNAME "samrtorturetestgroup"
  43 #define TEST_MACHINENAME "samrtestmach$"
  44 #define TEST_DOMAINNAME "samrtestdom$"
  45 
  46 enum torture_samr_choice {
  47         TORTURE_SAMR_PASSWORDS,
  48         TORTURE_SAMR_PASSWORDS_PWDLASTSET,
  49         TORTURE_SAMR_USER_ATTRIBUTES,
  50         TORTURE_SAMR_USER_PRIVILEGES,
  51         TORTURE_SAMR_OTHER,
  52         TORTURE_SAMR_MANY_ACCOUNTS,
  53         TORTURE_SAMR_MANY_GROUPS,
  54         TORTURE_SAMR_MANY_ALIASES
  55 };
  56 
  57 static bool test_QueryUserInfo(struct dcerpc_pipe *p,
  58                                struct torture_context *tctx,
  59                                struct policy_handle *handle);
  60 
  61 static bool test_QueryUserInfo2(struct dcerpc_pipe *p,
  62                                 struct torture_context *tctx,
  63                                 struct policy_handle *handle);
  64 
  65 static bool test_QueryAliasInfo(struct dcerpc_pipe *p,
  66                                 struct torture_context *tctx,
  67                                 struct policy_handle *handle);
  68 
  69 static bool test_ChangePassword(struct dcerpc_pipe *p,
  70                                 struct torture_context *tctx,
  71                                 const char *acct_name,
  72                                 struct policy_handle *domain_handle, char **password);
  73 
  74 static void init_lsa_String(struct lsa_String *string, const char *s)
     /* [<][>][^][v][top][bottom][index][help] */
  75 {
  76         string->string = s;
  77 }
  78 
  79 static void init_lsa_StringLarge(struct lsa_StringLarge *string, const char *s)
     /* [<][>][^][v][top][bottom][index][help] */
  80 {
  81         string->string = s;
  82 }
  83 
  84 static void init_lsa_BinaryString(struct lsa_BinaryString *string, const char *s, uint32_t length)
     /* [<][>][^][v][top][bottom][index][help] */
  85 {
  86         string->length = length;
  87         string->size = length;
  88         string->array = (uint16_t *)discard_const(s);
  89 }
  90 
  91 bool test_samr_handle_Close(struct dcerpc_pipe *p, struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
  92                                    struct policy_handle *handle)
  93 {
  94         NTSTATUS status;
  95         struct samr_Close r;
  96 
  97         r.in.handle = handle;
  98         r.out.handle = handle;
  99 
 100         status = dcerpc_samr_Close(p, tctx, &r);
 101         torture_assert_ntstatus_ok(tctx, status, "Close");
 102 
 103         return true;
 104 }
 105 
 106 static bool test_Shutdown(struct dcerpc_pipe *p, struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
 107                        struct policy_handle *handle)
 108 {
 109         NTSTATUS status;
 110         struct samr_Shutdown r;
 111 
 112         if (!torture_setting_bool(tctx, "dangerous", false)) {
 113                 torture_skip(tctx, "samr_Shutdown disabled - enable dangerous tests to use\n");
 114                 return true;
 115         }
 116 
 117         r.in.connect_handle = handle;
 118 
 119         torture_comment(tctx, "testing samr_Shutdown\n");
 120 
 121         status = dcerpc_samr_Shutdown(p, tctx, &r);
 122         torture_assert_ntstatus_ok(tctx, status, "samr_Shutdown");
 123 
 124         return true;
 125 }
 126 
 127 static bool test_SetDsrmPassword(struct dcerpc_pipe *p, struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
 128                                  struct policy_handle *handle)
 129 {
 130         NTSTATUS status;
 131         struct samr_SetDsrmPassword r;
 132         struct lsa_String string;
 133         struct samr_Password hash;
 134 
 135         if (!torture_setting_bool(tctx, "dangerous", false)) {
 136                 torture_skip(tctx, "samr_SetDsrmPassword disabled - enable dangerous tests to use");
 137         }
 138 
 139         E_md4hash("TeSTDSRM123", hash.hash);
 140 
 141         init_lsa_String(&string, "Administrator");
 142 
 143         r.in.name = &string;
 144         r.in.unknown = 0;
 145         r.in.hash = &hash;
 146 
 147         torture_comment(tctx, "testing samr_SetDsrmPassword\n");
 148 
 149         status = dcerpc_samr_SetDsrmPassword(p, tctx, &r);
 150         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_SUPPORTED, "samr_SetDsrmPassword");
 151 
 152         return true;
 153 }
 154 
 155 
 156 static bool test_QuerySecurity(struct dcerpc_pipe *p,
     /* [<][>][^][v][top][bottom][index][help] */
 157                                struct torture_context *tctx,
 158                                struct policy_handle *handle)
 159 {
 160         NTSTATUS status;
 161         struct samr_QuerySecurity r;
 162         struct samr_SetSecurity s;
 163         struct sec_desc_buf *sdbuf = NULL;
 164 
 165         r.in.handle = handle;
 166         r.in.sec_info = 7;
 167         r.out.sdbuf = &sdbuf;
 168 
 169         status = dcerpc_samr_QuerySecurity(p, tctx, &r);
 170         torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
 171 
 172         torture_assert(tctx, sdbuf != NULL, "sdbuf is NULL");
 173 
 174         s.in.handle = handle;
 175         s.in.sec_info = 7;
 176         s.in.sdbuf = sdbuf;
 177 
 178         if (torture_setting_bool(tctx, "samba4", false)) {
 179                 torture_skip(tctx, "skipping SetSecurity test against Samba4\n");
 180         }
 181 
 182         status = dcerpc_samr_SetSecurity(p, tctx, &s);
 183         torture_assert_ntstatus_ok(tctx, status, "SetSecurity");
 184 
 185         status = dcerpc_samr_QuerySecurity(p, tctx, &r);
 186         torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
 187 
 188         return true;
 189 }
 190 
 191 
 192 static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
 193                              struct policy_handle *handle, uint32_t base_acct_flags,
 194                              const char *base_account_name)
 195 {
 196         NTSTATUS status;
 197         struct samr_SetUserInfo s;
 198         struct samr_SetUserInfo2 s2;
 199         struct samr_QueryUserInfo q;
 200         struct samr_QueryUserInfo q0;
 201         union samr_UserInfo u;
 202         union samr_UserInfo *info;
 203         bool ret = true;
 204         const char *test_account_name;
 205 
 206         uint32_t user_extra_flags = 0;
 207 
 208         if (!torture_setting_bool(tctx, "samba3", false)) {
 209                 if (base_acct_flags == ACB_NORMAL) {
 210                         /* When created, accounts are expired by default */
 211                         user_extra_flags = ACB_PW_EXPIRED;
 212                 }
 213         }
 214 
 215         s.in.user_handle = handle;
 216         s.in.info = &u;
 217 
 218         s2.in.user_handle = handle;
 219         s2.in.info = &u;
 220 
 221         q.in.user_handle = handle;
 222         q.out.info = &info;
 223         q0 = q;
 224 
 225 #define TESTCALL(call, r) \
 226                 status = dcerpc_samr_ ##call(p, tctx, &r); \
 227                 if (!NT_STATUS_IS_OK(status)) { \
 228                         torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
 229                                r.in.level, nt_errstr(status), __location__); \
 230                         ret = false; \
 231                         break; \
 232                 }
 233 
 234 #define STRING_EQUAL(s1, s2, field) \
 235                 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
 236                         torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
 237                                #field, s2, __location__); \
 238                         ret = false; \
 239                         break; \
 240                 }
 241 
 242 #define MEM_EQUAL(s1, s2, length, field) \
 243                 if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
 244                         torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
 245                                #field, (const char *)s2, __location__); \
 246                         ret = false; \
 247                         break; \
 248                 }
 249 
 250 #define INT_EQUAL(i1, i2, field) \
 251                 if (i1 != i2) { \
 252                         torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
 253                                #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
 254                         ret = false; \
 255                         break; \
 256                 }
 257 
 258 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
 259                 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
 260                 q.in.level = lvl1; \
 261                 TESTCALL(QueryUserInfo, q) \
 262                 s.in.level = lvl1; \
 263                 s2.in.level = lvl1; \
 264                 u = *info; \
 265                 if (lvl1 == 21) { \
 266                         ZERO_STRUCT(u.info21); \
 267                         u.info21.fields_present = fpval; \
 268                 } \
 269                 init_lsa_String(&u.info ## lvl1.field1, value); \
 270                 TESTCALL(SetUserInfo, s) \
 271                 TESTCALL(SetUserInfo2, s2) \
 272                 init_lsa_String(&u.info ## lvl1.field1, ""); \
 273                 TESTCALL(QueryUserInfo, q); \
 274                 u = *info; \
 275                 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
 276                 q.in.level = lvl2; \
 277                 TESTCALL(QueryUserInfo, q) \
 278                 u = *info; \
 279                 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
 280         } while (0)
 281 
 282 #define TEST_USERINFO_BINARYSTRING(lvl1, field1, lvl2, field2, value, fpval) do { \
 283                 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
 284                 q.in.level = lvl1; \
 285                 TESTCALL(QueryUserInfo, q) \
 286                 s.in.level = lvl1; \
 287                 s2.in.level = lvl1; \
 288                 u = *info; \
 289                 if (lvl1 == 21) { \
 290                         ZERO_STRUCT(u.info21); \
 291                         u.info21.fields_present = fpval; \
 292                 } \
 293                 init_lsa_BinaryString(&u.info ## lvl1.field1, value, strlen(value)); \
 294                 TESTCALL(SetUserInfo, s) \
 295                 TESTCALL(SetUserInfo2, s2) \
 296                 init_lsa_BinaryString(&u.info ## lvl1.field1, "", 1); \
 297                 TESTCALL(QueryUserInfo, q); \
 298                 u = *info; \
 299                 MEM_EQUAL(u.info ## lvl1.field1.array, value, strlen(value), field1); \
 300                 q.in.level = lvl2; \
 301                 TESTCALL(QueryUserInfo, q) \
 302                 u = *info; \
 303                 MEM_EQUAL(u.info ## lvl2.field2.array, value, strlen(value), field2); \
 304         } while (0)
 305 
 306 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
 307                 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
 308                 q.in.level = lvl1; \
 309                 TESTCALL(QueryUserInfo, q) \
 310                 s.in.level = lvl1; \
 311                 s2.in.level = lvl1; \
 312                 u = *info; \
 313                 if (lvl1 == 21) { \
 314                         uint8_t *bits = u.info21.logon_hours.bits; \
 315                         ZERO_STRUCT(u.info21); \
 316                         if (fpval == SAMR_FIELD_LOGON_HOURS) { \
 317                                 u.info21.logon_hours.units_per_week = 168; \
 318                                 u.info21.logon_hours.bits = bits; \
 319                         } \
 320                         u.info21.fields_present = fpval; \
 321                 } \
 322                 u.info ## lvl1.field1 = value; \
 323                 TESTCALL(SetUserInfo, s) \
 324                 TESTCALL(SetUserInfo2, s2) \
 325                 u.info ## lvl1.field1 = 0; \
 326                 TESTCALL(QueryUserInfo, q); \
 327                 u = *info; \
 328                 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
 329                 q.in.level = lvl2; \
 330                 TESTCALL(QueryUserInfo, q) \
 331                 u = *info; \
 332                 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
 333         } while (0)
 334 
 335 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
 336         TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
 337         } while (0)
 338 
 339         q0.in.level = 12;
 340         do { TESTCALL(QueryUserInfo, q0) } while (0);
 341 
 342         /* Samba 3 cannot store comment fields atm. - gd */
 343         if (!torture_setting_bool(tctx, "samba3", false)) {
 344                 TEST_USERINFO_STRING(2, comment,  1, comment, "xx2-1 comment", 0);
 345                 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
 346                 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
 347                                    SAMR_FIELD_COMMENT);
 348         }
 349 
 350         test_account_name = talloc_asprintf(tctx, "%sxx7-1", base_account_name);
 351         TEST_USERINFO_STRING(7, account_name,  1, account_name, base_account_name, 0);
 352         test_account_name = talloc_asprintf(tctx, "%sxx7-3", base_account_name);
 353         TEST_USERINFO_STRING(7, account_name,  3, account_name, base_account_name, 0);
 354         test_account_name = talloc_asprintf(tctx, "%sxx7-5", base_account_name);
 355         TEST_USERINFO_STRING(7, account_name,  5, account_name, base_account_name, 0);
 356         test_account_name = talloc_asprintf(tctx, "%sxx7-6", base_account_name);
 357         TEST_USERINFO_STRING(7, account_name,  6, account_name, base_account_name, 0);
 358         test_account_name = talloc_asprintf(tctx, "%sxx7-7", base_account_name);
 359         TEST_USERINFO_STRING(7, account_name,  7, account_name, base_account_name, 0);
 360         test_account_name = talloc_asprintf(tctx, "%sxx7-21", base_account_name);
 361         TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
 362         test_account_name = base_account_name;
 363         TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
 364                            SAMR_FIELD_ACCOUNT_NAME);
 365 
 366         TEST_USERINFO_STRING(6, full_name,  1, full_name, "xx6-1 full_name", 0);
 367         TEST_USERINFO_STRING(6, full_name,  3, full_name, "xx6-3 full_name", 0);
 368         TEST_USERINFO_STRING(6, full_name,  5, full_name, "xx6-5 full_name", 0);
 369         TEST_USERINFO_STRING(6, full_name,  6, full_name, "xx6-6 full_name", 0);
 370         TEST_USERINFO_STRING(6, full_name,  8, full_name, "xx6-8 full_name", 0);
 371         TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
 372         TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
 373         TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
 374                            SAMR_FIELD_FULL_NAME);
 375 
 376         TEST_USERINFO_STRING(6, full_name,  1, full_name, "", 0);
 377         TEST_USERINFO_STRING(6, full_name,  3, full_name, "", 0);
 378         TEST_USERINFO_STRING(6, full_name,  5, full_name, "", 0);
 379         TEST_USERINFO_STRING(6, full_name,  6, full_name, "", 0);
 380         TEST_USERINFO_STRING(6, full_name,  8, full_name, "", 0);
 381         TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
 382         TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
 383         TEST_USERINFO_STRING(21, full_name, 21, full_name, "",
 384                            SAMR_FIELD_FULL_NAME);
 385 
 386         TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
 387         TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
 388         TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
 389         TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
 390                            SAMR_FIELD_LOGON_SCRIPT);
 391 
 392         TEST_USERINFO_STRING(12, profile_path,  3, profile_path, "xx12-3 profile_path", 0);
 393         TEST_USERINFO_STRING(12, profile_path,  5, profile_path, "xx12-5 profile_path", 0);
 394         TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
 395         TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
 396                            SAMR_FIELD_PROFILE_PATH);
 397 
 398         TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
 399         TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
 400         TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
 401         TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
 402                              SAMR_FIELD_HOME_DIRECTORY);
 403         TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
 404                              SAMR_FIELD_HOME_DIRECTORY);
 405 
 406         TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
 407         TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
 408         TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
 409         TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
 410                              SAMR_FIELD_HOME_DRIVE);
 411         TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
 412                              SAMR_FIELD_HOME_DRIVE);
 413 
 414         TEST_USERINFO_STRING(13, description,  1, description, "xx13-1 description", 0);
 415         TEST_USERINFO_STRING(13, description,  5, description, "xx13-5 description", 0);
 416         TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
 417         TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
 418                            SAMR_FIELD_DESCRIPTION);
 419 
 420         TEST_USERINFO_STRING(14, workstations,  3, workstations, "14workstation3", 0);
 421         TEST_USERINFO_STRING(14, workstations,  5, workstations, "14workstation4", 0);
 422         TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
 423         TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
 424                            SAMR_FIELD_WORKSTATIONS);
 425         TEST_USERINFO_STRING(21, workstations, 3, workstations, "21workstation3",
 426                            SAMR_FIELD_WORKSTATIONS);
 427         TEST_USERINFO_STRING(21, workstations, 5, workstations, "21workstation5",
 428                            SAMR_FIELD_WORKSTATIONS);
 429         TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14",
 430                            SAMR_FIELD_WORKSTATIONS);
 431 
 432         TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
 433         TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "xx21-21 parameters",
 434                            SAMR_FIELD_PARAMETERS);
 435         TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "xx21-20 parameters",
 436                            SAMR_FIELD_PARAMETERS);
 437         /* also empty user parameters are allowed */
 438         TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "", 0);
 439         TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "",
 440                            SAMR_FIELD_PARAMETERS);
 441         TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "",
 442                            SAMR_FIELD_PARAMETERS);
 443 
 444         /* Samba 3 cannot store country_code and copy_page atm. - gd */
 445         if (!torture_setting_bool(tctx, "samba3", false)) {
 446                 TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
 447                 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
 448                 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
 449                                   SAMR_FIELD_COUNTRY_CODE);
 450                 TEST_USERINFO_INT(21, country_code, 2, country_code, __LINE__,
 451                                   SAMR_FIELD_COUNTRY_CODE);
 452 
 453                 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
 454                 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
 455                                   SAMR_FIELD_CODE_PAGE);
 456                 TEST_USERINFO_INT(21, code_page, 2, code_page, __LINE__,
 457                                   SAMR_FIELD_CODE_PAGE);
 458         }
 459 
 460         if (!torture_setting_bool(tctx, "samba3", false)) {
 461                 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
 462                 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
 463                 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__,
 464                                   SAMR_FIELD_ACCT_EXPIRY);
 465                 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, __LINE__,
 466                                   SAMR_FIELD_ACCT_EXPIRY);
 467                 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, __LINE__,
 468                                   SAMR_FIELD_ACCT_EXPIRY);
 469         } else {
 470                 /* Samba 3 can only store seconds / time_t in passdb - gd */
 471                 NTTIME nt;
 472                 unix_to_nt_time(&nt, time(NULL) + __LINE__);
 473                 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, nt, 0);
 474                 unix_to_nt_time(&nt, time(NULL) + __LINE__);
 475                 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, nt, 0);
 476                 unix_to_nt_time(&nt, time(NULL) + __LINE__);
 477                 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
 478                 unix_to_nt_time(&nt, time(NULL) + __LINE__);
 479                 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
 480                 unix_to_nt_time(&nt, time(NULL) + __LINE__);
 481                 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
 482         }
 483 
 484         TEST_USERINFO_INT(4, logon_hours.bits[3],  3, logon_hours.bits[3], 1, 0);
 485         TEST_USERINFO_INT(4, logon_hours.bits[3],  5, logon_hours.bits[3], 2, 0);
 486         TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
 487         TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
 488                           SAMR_FIELD_LOGON_HOURS);
 489 
 490         TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
 491                               (base_acct_flags  | ACB_DISABLED | ACB_HOMDIRREQ),
 492                               (base_acct_flags  | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
 493                               0);
 494         TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
 495                               (base_acct_flags  | ACB_DISABLED),
 496                               (base_acct_flags  | ACB_DISABLED | user_extra_flags),
 497                               0);
 498 
 499         /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
 500         TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
 501                               (base_acct_flags  | ACB_DISABLED | ACB_PWNOEXP),
 502                               (base_acct_flags  | ACB_DISABLED | ACB_PWNOEXP),
 503                               0);
 504         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
 505                               (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
 506                               (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
 507                               0);
 508 
 509 
 510         /* The 'autolock' flag doesn't stick - check this */
 511         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
 512                               (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
 513                               (base_acct_flags | ACB_DISABLED | user_extra_flags),
 514                               0);
 515 #if 0
 516         /* Removing the 'disabled' flag doesn't stick - check this */
 517         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
 518                               (base_acct_flags),
 519                               (base_acct_flags | ACB_DISABLED | user_extra_flags),
 520                               0);
 521 #endif
 522 
 523         /* Samba3 cannot store these atm */
 524         if (!torture_setting_bool(tctx, "samba3", false)) {
 525         /* The 'store plaintext' flag does stick */
 526         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
 527                               (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
 528                               (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
 529                               0);
 530         /* The 'use DES' flag does stick */
 531         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
 532                               (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
 533                               (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
 534                               0);
 535         /* The 'don't require kerberos pre-authentication flag does stick */
 536         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
 537                               (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
 538                               (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
 539                               0);
 540         /* The 'no kerberos PAC required' flag sticks */
 541         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
 542                               (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
 543                               (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
 544                               0);
 545         }
 546         TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
 547                               (base_acct_flags | ACB_DISABLED),
 548                               (base_acct_flags | ACB_DISABLED | user_extra_flags),
 549                               SAMR_FIELD_ACCT_FLAGS);
 550 
 551 #if 0
 552         /* these fail with win2003 - it appears you can't set the primary gid?
 553            the set succeeds, but the gid isn't changed. Very weird! */
 554         TEST_USERINFO_INT(9, primary_gid,  1, primary_gid, 513);
 555         TEST_USERINFO_INT(9, primary_gid,  3, primary_gid, 513);
 556         TEST_USERINFO_INT(9, primary_gid,  5, primary_gid, 513);
 557         TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
 558 #endif
 559 
 560         return ret;
 561 }
 562 
 563 /*
 564   generate a random password for password change tests
 565 */
 566 static char *samr_rand_pass_silent(TALLOC_CTX *mem_ctx, int min_len)
     /* [<][>][^][v][top][bottom][index][help] */
 567 {
 568         size_t len = MAX(8, min_len) + (random() % 6);
 569         char *s = generate_random_str(mem_ctx, len);
 570         return s;
 571 }
 572 
 573 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
     /* [<][>][^][v][top][bottom][index][help] */
 574 {
 575         char *s = samr_rand_pass_silent(mem_ctx, min_len);
 576         printf("Generated password '%s'\n", s);
 577         return s;
 578 
 579 }
 580 
 581 /*
 582   generate a random password for password change tests
 583 */
 584 static DATA_BLOB samr_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
     /* [<][>][^][v][top][bottom][index][help] */
 585 {
 586         int i;
 587         DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
 588         generate_random_buffer(password.data, password.length);
 589 
 590         for (i=0; i < len; i++) {
 591                 if (((uint16_t *)password.data)[i] == 0) {
 592                         ((uint16_t *)password.data)[i] = 1;
 593                 }
 594         }
 595 
 596         return password;
 597 }
 598 
 599 /*
 600   generate a random password for password change tests (fixed length)
 601 */
 602 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
     /* [<][>][^][v][top][bottom][index][help] */
 603 {
 604         char *s = generate_random_str(mem_ctx, len);
 605         printf("Generated password '%s'\n", s);
 606         return s;
 607 }
 608 
 609 static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
 610                              struct policy_handle *handle, char **password)
 611 {
 612         NTSTATUS status;
 613         struct samr_SetUserInfo s;
 614         union samr_UserInfo u;
 615         bool ret = true;
 616         DATA_BLOB session_key;
 617         char *newpass;
 618         struct samr_GetUserPwInfo pwp;
 619         struct samr_PwInfo info;
 620         int policy_min_pw_len = 0;
 621         pwp.in.user_handle = handle;
 622         pwp.out.info = &info;
 623 
 624         status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
 625         if (NT_STATUS_IS_OK(status)) {
 626                 policy_min_pw_len = pwp.out.info->min_password_length;
 627         }
 628         newpass = samr_rand_pass(tctx, policy_min_pw_len);
 629 
 630         s.in.user_handle = handle;
 631         s.in.info = &u;
 632         s.in.level = 24;
 633 
 634         encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
 635         u.info24.password_expired = 0;
 636 
 637         status = dcerpc_fetch_session_key(p, &session_key);
 638         if (!NT_STATUS_IS_OK(status)) {
 639                 printf("SetUserInfo level %u - no session key - %s\n",
 640                        s.in.level, nt_errstr(status));
 641                 return false;
 642         }
 643 
 644         arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
 645 
 646         torture_comment(tctx, "Testing SetUserInfo level 24 (set password)\n");
 647 
 648         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
 649         if (!NT_STATUS_IS_OK(status)) {
 650                 printf("SetUserInfo level %u failed - %s\n",
 651                        s.in.level, nt_errstr(status));
 652                 ret = false;
 653         } else {
 654                 *password = newpass;
 655         }
 656 
 657         return ret;
 658 }
 659 
 660 
 661 static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
 662                                 struct policy_handle *handle, uint32_t fields_present,
 663                                 char **password)
 664 {
 665         NTSTATUS status;
 666         struct samr_SetUserInfo s;
 667         union samr_UserInfo u;
 668         bool ret = true;
 669         DATA_BLOB session_key;
 670         char *newpass;
 671         struct samr_GetUserPwInfo pwp;
 672         struct samr_PwInfo info;
 673         int policy_min_pw_len = 0;
 674         pwp.in.user_handle = handle;
 675         pwp.out.info = &info;
 676 
 677         status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
 678         if (NT_STATUS_IS_OK(status)) {
 679                 policy_min_pw_len = pwp.out.info->min_password_length;
 680         }
 681         newpass = samr_rand_pass(tctx, policy_min_pw_len);
 682 
 683         s.in.user_handle = handle;
 684         s.in.info = &u;
 685         s.in.level = 23;
 686 
 687         ZERO_STRUCT(u);
 688 
 689         u.info23.info.fields_present = fields_present;
 690 
 691         encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
 692 
 693         status = dcerpc_fetch_session_key(p, &session_key);
 694         if (!NT_STATUS_IS_OK(status)) {
 695                 printf("SetUserInfo level %u - no session key - %s\n",
 696                        s.in.level, nt_errstr(status));
 697                 return false;
 698         }
 699 
 700         arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
 701 
 702         torture_comment(tctx, "Testing SetUserInfo level 23 (set password)\n");
 703 
 704         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
 705         if (!NT_STATUS_IS_OK(status)) {
 706                 printf("SetUserInfo level %u failed - %s\n",
 707                        s.in.level, nt_errstr(status));
 708                 ret = false;
 709         } else {
 710                 *password = newpass;
 711         }
 712 
 713         encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
 714 
 715         status = dcerpc_fetch_session_key(p, &session_key);
 716         if (!NT_STATUS_IS_OK(status)) {
 717                 printf("SetUserInfo level %u - no session key - %s\n",
 718                        s.in.level, nt_errstr(status));
 719                 return false;
 720         }
 721 
 722         /* This should break the key nicely */
 723         session_key.length--;
 724         arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
 725 
 726         torture_comment(tctx, "Testing SetUserInfo level 23 (set password) with wrong password\n");
 727 
 728         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
 729         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
 730                 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
 731                        s.in.level, nt_errstr(status));
 732                 ret = false;
 733         }
 734 
 735         return ret;
 736 }
 737 
 738 
 739 static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
 740                                struct policy_handle *handle, bool makeshort,
 741                                char **password)
 742 {
 743         NTSTATUS status;
 744         struct samr_SetUserInfo s;
 745         union samr_UserInfo u;
 746         bool ret = true;
 747         DATA_BLOB session_key;
 748         DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
 749         uint8_t confounder[16];
 750         char *newpass;
 751         struct MD5Context ctx;
 752         struct samr_GetUserPwInfo pwp;
 753         struct samr_PwInfo info;
 754         int policy_min_pw_len = 0;
 755         pwp.in.user_handle = handle;
 756         pwp.out.info = &info;
 757 
 758         status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
 759         if (NT_STATUS_IS_OK(status)) {
 760                 policy_min_pw_len = pwp.out.info->min_password_length;
 761         }
 762         if (makeshort && policy_min_pw_len) {
 763                 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len - 1);
 764         } else {
 765                 newpass = samr_rand_pass(tctx, policy_min_pw_len);
 766         }
 767 
 768         s.in.user_handle = handle;
 769         s.in.info = &u;
 770         s.in.level = 26;
 771 
 772         encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
 773         u.info26.password_expired = 0;
 774 
 775         status = dcerpc_fetch_session_key(p, &session_key);
 776         if (!NT_STATUS_IS_OK(status)) {
 777                 printf("SetUserInfo level %u - no session key - %s\n",
 778                        s.in.level, nt_errstr(status));
 779                 return false;
 780         }
 781 
 782         generate_random_buffer((uint8_t *)confounder, 16);
 783 
 784         MD5Init(&ctx);
 785         MD5Update(&ctx, confounder, 16);
 786         MD5Update(&ctx, session_key.data, session_key.length);
 787         MD5Final(confounded_session_key.data, &ctx);
 788 
 789         arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
 790         memcpy(&u.info26.password.data[516], confounder, 16);
 791 
 792         torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex)\n");
 793 
 794         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
 795         if (!NT_STATUS_IS_OK(status)) {
 796                 printf("SetUserInfo level %u failed - %s\n",
 797                        s.in.level, nt_errstr(status));
 798                 ret = false;
 799         } else {
 800                 *password = newpass;
 801         }
 802 
 803         /* This should break the key nicely */
 804         confounded_session_key.data[0]++;
 805 
 806         arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
 807         memcpy(&u.info26.password.data[516], confounder, 16);
 808 
 809         torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
 810 
 811         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
 812         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
 813                 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
 814                        s.in.level, nt_errstr(status));
 815                 ret = false;
 816         } else {
 817                 *password = newpass;
 818         }
 819 
 820         return ret;
 821 }
 822 
 823 static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
 824                                 struct policy_handle *handle, uint32_t fields_present,
 825                                 char **password)
 826 {
 827         NTSTATUS status;
 828         struct samr_SetUserInfo s;
 829         union samr_UserInfo u;
 830         bool ret = true;
 831         DATA_BLOB session_key;
 832         DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
 833         struct MD5Context ctx;
 834         uint8_t confounder[16];
 835         char *newpass;
 836         struct samr_GetUserPwInfo pwp;
 837         struct samr_PwInfo info;
 838         int policy_min_pw_len = 0;
 839         pwp.in.user_handle = handle;
 840         pwp.out.info = &info;
 841 
 842         status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
 843         if (NT_STATUS_IS_OK(status)) {
 844                 policy_min_pw_len = pwp.out.info->min_password_length;
 845         }
 846         newpass = samr_rand_pass(tctx, policy_min_pw_len);
 847 
 848         s.in.user_handle = handle;
 849         s.in.info = &u;
 850         s.in.level = 25;
 851 
 852         ZERO_STRUCT(u);
 853 
 854         u.info25.info.fields_present = fields_present;
 855 
 856         encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
 857 
 858         status = dcerpc_fetch_session_key(p, &session_key);
 859         if (!NT_STATUS_IS_OK(status)) {
 860                 printf("SetUserInfo level %u - no session key - %s\n",
 861                        s.in.level, nt_errstr(status));
 862                 return false;
 863         }
 864 
 865         generate_random_buffer((uint8_t *)confounder, 16);
 866 
 867         MD5Init(&ctx);
 868         MD5Update(&ctx, confounder, 16);
 869         MD5Update(&ctx, session_key.data, session_key.length);
 870         MD5Final(confounded_session_key.data, &ctx);
 871 
 872         arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
 873         memcpy(&u.info25.password.data[516], confounder, 16);
 874 
 875         torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex)\n");
 876 
 877         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
 878         if (!NT_STATUS_IS_OK(status)) {
 879                 printf("SetUserInfo level %u failed - %s\n",
 880                        s.in.level, nt_errstr(status));
 881                 ret = false;
 882         } else {
 883                 *password = newpass;
 884         }
 885 
 886         /* This should break the key nicely */
 887         confounded_session_key.data[0]++;
 888 
 889         arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
 890         memcpy(&u.info25.password.data[516], confounder, 16);
 891 
 892         torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
 893 
 894         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
 895         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
 896                 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
 897                        s.in.level, nt_errstr(status));
 898                 ret = false;
 899         }
 900 
 901         return ret;
 902 }
 903 
 904 static bool test_SetUserPass_18(struct dcerpc_pipe *p, struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
 905                                 struct policy_handle *handle, char **password)
 906 {
 907         NTSTATUS status;
 908         struct samr_SetUserInfo s;
 909         union samr_UserInfo u;
 910         bool ret = true;
 911         DATA_BLOB session_key;
 912         char *newpass;
 913         struct samr_GetUserPwInfo pwp;
 914         struct samr_PwInfo info;
 915         int policy_min_pw_len = 0;
 916         uint8_t lm_hash[16], nt_hash[16];
 917 
 918         pwp.in.user_handle = handle;
 919         pwp.out.info = &info;
 920 
 921         status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
 922         if (NT_STATUS_IS_OK(status)) {
 923                 policy_min_pw_len = pwp.out.info->min_password_length;
 924         }
 925         newpass = samr_rand_pass(tctx, policy_min_pw_len);
 926 
 927         s.in.user_handle = handle;
 928         s.in.info = &u;
 929         s.in.level = 18;
 930 
 931         ZERO_STRUCT(u);
 932 
 933         u.info18.nt_pwd_active = true;
 934         u.info18.lm_pwd_active = true;
 935 
 936         E_md4hash(newpass, nt_hash);
 937         E_deshash(newpass, lm_hash);
 938 
 939         status = dcerpc_fetch_session_key(p, &session_key);
 940         if (!NT_STATUS_IS_OK(status)) {
 941                 printf("SetUserInfo level %u - no session key - %s\n",
 942                        s.in.level, nt_errstr(status));
 943                 return false;
 944         }
 945 
 946         {
 947                 DATA_BLOB in,out;
 948                 in = data_blob_const(nt_hash, 16);
 949                 out = data_blob_talloc_zero(tctx, 16);
 950                 sess_crypt_blob(&out, &in, &session_key, true);
 951                 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
 952         }
 953         {
 954                 DATA_BLOB in,out;
 955                 in = data_blob_const(lm_hash, 16);
 956                 out = data_blob_talloc_zero(tctx, 16);
 957                 sess_crypt_blob(&out, &in, &session_key, true);
 958                 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
 959         }
 960 
 961         torture_comment(tctx, "Testing SetUserInfo level 18 (set password hash)\n");
 962 
 963         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
 964         if (!NT_STATUS_IS_OK(status)) {
 965                 printf("SetUserInfo level %u failed - %s\n",
 966                        s.in.level, nt_errstr(status));
 967                 ret = false;
 968         } else {
 969                 *password = newpass;
 970         }
 971 
 972         return ret;
 973 }
 974 
 975 static bool test_SetUserPass_21(struct dcerpc_pipe *p, struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
 976                                 struct policy_handle *handle, uint32_t fields_present,
 977                                 char **password)
 978 {
 979         NTSTATUS status;
 980         struct samr_SetUserInfo s;
 981         union samr_UserInfo u;
 982         bool ret = true;
 983         DATA_BLOB session_key;
 984         char *newpass;
 985         struct samr_GetUserPwInfo pwp;
 986         struct samr_PwInfo info;
 987         int policy_min_pw_len = 0;
 988         uint8_t lm_hash[16], nt_hash[16];
 989 
 990         pwp.in.user_handle = handle;
 991         pwp.out.info = &info;
 992 
 993         status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
 994         if (NT_STATUS_IS_OK(status)) {
 995                 policy_min_pw_len = pwp.out.info->min_password_length;
 996         }
 997         newpass = samr_rand_pass(tctx, policy_min_pw_len);
 998 
 999         s.in.user_handle = handle;
1000         s.in.info = &u;
1001         s.in.level = 21;
1002 
1003         E_md4hash(newpass, nt_hash);
1004         E_deshash(newpass, lm_hash);
1005 
1006         ZERO_STRUCT(u);
1007 
1008         u.info21.fields_present = fields_present;
1009 
1010         if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1011                 u.info21.lm_owf_password.length = 16;
1012                 u.info21.lm_owf_password.size = 16;
1013                 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
1014                 u.info21.lm_password_set = true;
1015         }
1016 
1017         if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1018                 u.info21.nt_owf_password.length = 16;
1019                 u.info21.nt_owf_password.size = 16;
1020                 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1021                 u.info21.nt_password_set = true;
1022         }
1023 
1024         status = dcerpc_fetch_session_key(p, &session_key);
1025         if (!NT_STATUS_IS_OK(status)) {
1026                 printf("SetUserInfo level %u - no session key - %s\n",
1027                        s.in.level, nt_errstr(status));
1028                 return false;
1029         }
1030 
1031         if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1032                 DATA_BLOB in,out;
1033                 in = data_blob_const(u.info21.lm_owf_password.array,
1034                                      u.info21.lm_owf_password.length);
1035                 out = data_blob_talloc_zero(tctx, 16);
1036                 sess_crypt_blob(&out, &in, &session_key, true);
1037                 u.info21.lm_owf_password.array = (uint16_t *)out.data;
1038         }
1039 
1040         if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1041                 DATA_BLOB in,out;
1042                 in = data_blob_const(u.info21.nt_owf_password.array,
1043                                      u.info21.nt_owf_password.length);
1044                 out = data_blob_talloc_zero(tctx, 16);
1045                 sess_crypt_blob(&out, &in, &session_key, true);
1046                 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1047         }
1048 
1049         torture_comment(tctx, "Testing SetUserInfo level 21 (set password hash)\n");
1050 
1051         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1052         if (!NT_STATUS_IS_OK(status)) {
1053                 printf("SetUserInfo level %u failed - %s\n",
1054                        s.in.level, nt_errstr(status));
1055                 ret = false;
1056         } else {
1057                 *password = newpass;
1058         }
1059 
1060         /* try invalid length */
1061         if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1062 
1063                 u.info21.nt_owf_password.length++;
1064 
1065                 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1066 
1067                 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1068                         printf("SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1069                                s.in.level, nt_errstr(status));
1070                         ret = false;
1071                 }
1072         }
1073 
1074         if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1075 
1076                 u.info21.lm_owf_password.length++;
1077 
1078                 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1079 
1080                 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1081                         printf("SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1082                                s.in.level, nt_errstr(status));
1083                         ret = false;
1084                 }
1085         }
1086 
1087         return ret;
1088 }
1089 
1090 static bool test_SetUserPass_level_ex(struct dcerpc_pipe *p,
     /* [<][>][^][v][top][bottom][index][help] */
1091                                       struct torture_context *tctx,
1092                                       struct policy_handle *handle,
1093                                       uint16_t level,
1094                                       uint32_t fields_present,
1095                                       char **password, uint8_t password_expired,
1096                                       bool use_setinfo2,
1097                                       bool *matched_expected_error)
1098 {
1099         NTSTATUS status;
1100         NTSTATUS expected_error = NT_STATUS_OK;
1101         struct samr_SetUserInfo s;
1102         struct samr_SetUserInfo2 s2;
1103         union samr_UserInfo u;
1104         bool ret = true;
1105         DATA_BLOB session_key;
1106         DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
1107         struct MD5Context ctx;
1108         uint8_t confounder[16];
1109         char *newpass;
1110         struct samr_GetUserPwInfo pwp;
1111         struct samr_PwInfo info;
1112         int policy_min_pw_len = 0;
1113         const char *comment = NULL;
1114         uint8_t lm_hash[16], nt_hash[16];
1115 
1116         pwp.in.user_handle = handle;
1117         pwp.out.info = &info;
1118 
1119         status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1120         if (NT_STATUS_IS_OK(status)) {
1121                 policy_min_pw_len = pwp.out.info->min_password_length;
1122         }
1123         newpass = samr_rand_pass_silent(tctx, policy_min_pw_len);
1124 
1125         if (use_setinfo2) {
1126                 s2.in.user_handle = handle;
1127                 s2.in.info = &u;
1128                 s2.in.level = level;
1129         } else {
1130                 s.in.user_handle = handle;
1131                 s.in.info = &u;
1132                 s.in.level = level;
1133         }
1134 
1135         if (fields_present & SAMR_FIELD_COMMENT) {
1136                 comment = talloc_asprintf(tctx, "comment: %ld\n", time(NULL));
1137         }
1138 
1139         ZERO_STRUCT(u);
1140 
1141         switch (level) {
1142         case 18:
1143                 E_md4hash(newpass, nt_hash);
1144                 E_deshash(newpass, lm_hash);
1145 
1146                 u.info18.nt_pwd_active = true;
1147                 u.info18.lm_pwd_active = true;
1148                 u.info18.password_expired = password_expired;
1149 
1150                 memcpy(u.info18.lm_pwd.hash, lm_hash, 16);
1151                 memcpy(u.info18.nt_pwd.hash, nt_hash, 16);
1152 
1153                 break;
1154         case 21:
1155                 E_md4hash(newpass, nt_hash);
1156                 E_deshash(newpass, lm_hash);
1157 
1158                 u.info21.fields_present = fields_present;
1159                 u.info21.password_expired = password_expired;
1160                 u.info21.comment.string = comment;
1161 
1162                 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1163                         u.info21.lm_owf_password.length = 16;
1164                         u.info21.lm_owf_password.size = 16;
1165                         u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
1166                         u.info21.lm_password_set = true;
1167                 }
1168 
1169                 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1170                         u.info21.nt_owf_password.length = 16;
1171                         u.info21.nt_owf_password.size = 16;
1172                         u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1173                         u.info21.nt_password_set = true;
1174                 }
1175 
1176                 break;
1177         case 23:
1178                 u.info23.info.fields_present = fields_present;
1179                 u.info23.info.password_expired = password_expired;
1180                 u.info23.info.comment.string = comment;
1181 
1182                 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
1183 
1184                 break;
1185         case 24:
1186                 u.info24.password_expired = password_expired;
1187 
1188                 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
1189 
1190                 break;
1191         case 25:
1192                 u.info25.info.fields_present = fields_present;
1193                 u.info25.info.password_expired = password_expired;
1194                 u.info25.info.comment.string = comment;
1195 
1196                 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
1197 
1198                 break;
1199         case 26:
1200                 u.info26.password_expired = password_expired;
1201 
1202                 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
1203 
1204                 break;
1205         }
1206 
1207         status = dcerpc_fetch_session_key(p, &session_key);
1208         if (!NT_STATUS_IS_OK(status)) {
1209                 printf("SetUserInfo level %u - no session key - %s\n",
1210                        s.in.level, nt_errstr(status));
1211                 return false;
1212         }
1213 
1214         generate_random_buffer((uint8_t *)confounder, 16);
1215 
1216         MD5Init(&ctx);
1217         MD5Update(&ctx, confounder, 16);
1218         MD5Update(&ctx, session_key.data, session_key.length);
1219         MD5Final(confounded_session_key.data, &ctx);
1220 
1221         switch (level) {
1222         case 18:
1223                 {
1224                         DATA_BLOB in,out;
1225                         in = data_blob_const(u.info18.nt_pwd.hash, 16);
1226                         out = data_blob_talloc_zero(tctx, 16);
1227                         sess_crypt_blob(&out, &in, &session_key, true);
1228                         memcpy(u.info18.nt_pwd.hash, out.data, out.length);
1229                 }
1230                 {
1231                         DATA_BLOB in,out;
1232                         in = data_blob_const(u.info18.lm_pwd.hash, 16);
1233                         out = data_blob_talloc_zero(tctx, 16);
1234                         sess_crypt_blob(&out, &in, &session_key, true);
1235                         memcpy(u.info18.lm_pwd.hash, out.data, out.length);
1236                 }
1237 
1238                 break;
1239         case 21:
1240                 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1241                         DATA_BLOB in,out;
1242                         in = data_blob_const(u.info21.lm_owf_password.array,
1243                                              u.info21.lm_owf_password.length);
1244                         out = data_blob_talloc_zero(tctx, 16);
1245                         sess_crypt_blob(&out, &in, &session_key, true);
1246                         u.info21.lm_owf_password.array = (uint16_t *)out.data;
1247                 }
1248                 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1249                         DATA_BLOB in,out;
1250                         in = data_blob_const(u.info21.nt_owf_password.array,
1251                                              u.info21.nt_owf_password.length);
1252                         out = data_blob_talloc_zero(tctx, 16);
1253                         sess_crypt_blob(&out, &in, &session_key, true);
1254                         u.info21.nt_owf_password.array = (uint16_t *)out.data;
1255                 }
1256                 break;
1257         case 23:
1258                 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
1259                 break;
1260         case 24:
1261                 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
1262                 break;
1263         case 25:
1264                 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
1265                 memcpy(&u.info25.password.data[516], confounder, 16);
1266                 break;
1267         case 26:
1268                 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
1269                 memcpy(&u.info26.password.data[516], confounder, 16);
1270                 break;
1271         }
1272 
1273         if (use_setinfo2) {
1274                 status = dcerpc_samr_SetUserInfo2(p, tctx, &s2);
1275         } else {
1276                 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1277         }
1278 
1279         if (!NT_STATUS_IS_OK(status)) {
1280                 if (fields_present == 0) {
1281                         expected_error = NT_STATUS_INVALID_PARAMETER;
1282                 }
1283                 if (fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
1284                         expected_error = NT_STATUS_ACCESS_DENIED;
1285                 }
1286         }
1287 
1288         if (!NT_STATUS_IS_OK(expected_error)) {
1289                 if (use_setinfo2) {
1290                         torture_assert_ntstatus_equal(tctx,
1291                                 s2.out.result,
1292                                 expected_error, "SetUserInfo2 failed");
1293                 } else {
1294                         torture_assert_ntstatus_equal(tctx,
1295                                 s.out.result,
1296                                 expected_error, "SetUserInfo failed");
1297                 }
1298                 *matched_expected_error = true;
1299                 return true;
1300         }
1301 
1302         if (!NT_STATUS_IS_OK(status)) {
1303                 printf("SetUserInfo%s level %u failed - %s\n",
1304                        use_setinfo2 ? "2":"", level, nt_errstr(status));
1305                 ret = false;
1306         } else {
1307                 *password = newpass;
1308         }
1309 
1310         return ret;
1311 }
1312 
1313 static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
1314                                struct policy_handle *handle)
1315 {
1316         NTSTATUS status;
1317         struct samr_SetAliasInfo r;
1318         struct samr_QueryAliasInfo q;
1319         union samr_AliasInfo *info;
1320         uint16_t levels[] = {2, 3};
1321         int i;
1322         bool ret = true;
1323 
1324         /* Ignoring switch level 1, as that includes the number of members for the alias
1325          * and setting this to a wrong value might have negative consequences
1326          */
1327 
1328         for (i=0;i<ARRAY_SIZE(levels);i++) {
1329                 torture_comment(tctx, "Testing SetAliasInfo level %u\n", levels[i]);
1330 
1331                 r.in.alias_handle = handle;
1332                 r.in.level = levels[i];
1333                 r.in.info  = talloc(tctx, union samr_AliasInfo);
1334                 switch (r.in.level) {
1335                     case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
1336                     case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
1337                                 "Test Description, should test I18N as well"); break;
1338                     case ALIASINFOALL: printf("ALIASINFOALL ignored\n"); break;
1339                 }
1340 
1341                 status = dcerpc_samr_SetAliasInfo(p, tctx, &r);
1342                 if (!NT_STATUS_IS_OK(status)) {
1343                         printf("SetAliasInfo level %u failed - %s\n",
1344                                levels[i], nt_errstr(status));
1345                         ret = false;
1346                 }
1347 
1348                 q.in.alias_handle = handle;
1349                 q.in.level = levels[i];
1350                 q.out.info = &info;
1351 
1352                 status = dcerpc_samr_QueryAliasInfo(p, tctx, &q);
1353                 if (!NT_STATUS_IS_OK(status)) {
1354                         printf("QueryAliasInfo level %u failed - %s\n",
1355                                levels[i], nt_errstr(status));
1356                         ret = false;
1357                 }
1358         }
1359 
1360         return ret;
1361 }
1362 
1363 static bool test_GetGroupsForUser(struct dcerpc_pipe *p, struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
1364                                   struct policy_handle *user_handle)
1365 {
1366         struct samr_GetGroupsForUser r;
1367         struct samr_RidWithAttributeArray *rids = NULL;
1368         NTSTATUS status;
1369 
1370         torture_comment(tctx, "testing GetGroupsForUser\n");
1371 
1372         r.in.user_handle = user_handle;
1373         r.out.rids = &rids;
1374 
1375         status = dcerpc_samr_GetGroupsForUser(p, tctx, &r);
1376         torture_assert_ntstatus_ok(tctx, status, "GetGroupsForUser");
1377 
1378         return true;
1379 
1380 }
1381 
1382 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
1383                               struct lsa_String *domain_name)
1384 {
1385         NTSTATUS status;
1386         struct samr_GetDomPwInfo r;
1387         struct samr_PwInfo info;
1388 
1389         r.in.domain_name = domain_name;
1390         r.out.info = &info;
1391 
1392         torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1393 
1394         status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1395         torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1396 
1397         r.in.domain_name->string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1398         torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1399 
1400         status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1401         torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1402 
1403         r.in.domain_name->string = "\\\\__NONAME__";
1404         torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1405 
1406         status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1407         torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1408 
1409         r.in.domain_name->string = "\\\\Builtin";
1410         torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1411 
1412         status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1413         torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1414 
1415         return true;
1416 }
1417 
1418 static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
1419                                struct policy_handle *handle)
1420 {
1421         NTSTATUS status;
1422         struct samr_GetUserPwInfo r;
1423         struct samr_PwInfo info;
1424 
1425         torture_comment(tctx, "Testing GetUserPwInfo\n");
1426 
1427         r.in.user_handle = handle;
1428         r.out.info = &info;
1429 
1430         status = dcerpc_samr_GetUserPwInfo(p, tctx, &r);
1431         torture_assert_ntstatus_ok(tctx, status, "GetUserPwInfo");
1432 
1433         return true;
1434 }
1435 
1436 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
1437                                 struct policy_handle *domain_handle, const char *name,
1438                                 uint32_t *rid)
1439 {
1440         NTSTATUS status;
1441         struct samr_LookupNames n;
1442         struct lsa_String sname[2];
1443         struct samr_Ids rids, types;
1444 
1445         init_lsa_String(&sname[0], name);
1446 
1447         n.in.domain_handle = domain_handle;
1448         n.in.num_names = 1;
1449         n.in.names = sname;
1450         n.out.rids = &rids;
1451         n.out.types = &types;
1452         status = dcerpc_samr_LookupNames(p, tctx, &n);
1453         if (NT_STATUS_IS_OK(status)) {
1454                 *rid = n.out.rids->ids[0];
1455         } else {
1456                 return status;
1457         }
1458 
1459         init_lsa_String(&sname[1], "xxNONAMExx");
1460         n.in.num_names = 2;
1461         status = dcerpc_samr_LookupNames(p, tctx, &n);
1462         if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
1463                 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
1464                 if (NT_STATUS_IS_OK(status)) {
1465                         return NT_STATUS_UNSUCCESSFUL;
1466                 }
1467                 return status;
1468         }
1469 
1470         n.in.num_names = 0;
1471         status = dcerpc_samr_LookupNames(p, tctx, &n);
1472         if (!NT_STATUS_IS_OK(status)) {
1473                 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
1474                 return status;
1475         }
1476 
1477         init_lsa_String(&sname[0], "xxNONAMExx");
1478         n.in.num_names = 1;
1479         status = dcerpc_samr_LookupNames(p, tctx, &n);
1480         if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1481                 printf("LookupNames[1 bad name] failed - %s\n", nt_errstr(status));
1482                 if (NT_STATUS_IS_OK(status)) {
1483                         return NT_STATUS_UNSUCCESSFUL;
1484                 }
1485                 return status;
1486         }
1487 
1488         init_lsa_String(&sname[0], "xxNONAMExx");
1489         init_lsa_String(&sname[1], "xxNONAME2xx");
1490         n.in.num_names = 2;
1491         status = dcerpc_samr_LookupNames(p, tctx, &n);
1492         if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1493                 printf("LookupNames[2 bad names] failed - %s\n", nt_errstr(status));
1494                 if (NT_STATUS_IS_OK(status)) {
1495                         return NT_STATUS_UNSUCCESSFUL;
1496                 }
1497                 return status;
1498         }
1499 
1500         return NT_STATUS_OK;
1501 }
1502 
1503 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p,
     /* [<][>][^][v][top][bottom][index][help] */
1504                                      struct torture_context *tctx,
1505                                      struct policy_handle *domain_handle,
1506                                      const char *name, struct policy_handle *user_handle)
1507 {
1508         NTSTATUS status;
1509         struct samr_OpenUser r;
1510         uint32_t rid;
1511 
1512         status = test_LookupName(p, tctx, domain_handle, name, &rid);
1513         if (!NT_STATUS_IS_OK(status)) {
1514                 return status;
1515         }
1516 
1517         r.in.domain_handle = domain_handle;
1518         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1519         r.in.rid = rid;
1520         r.out.user_handle = user_handle;
1521         status = dcerpc_samr_OpenUser(p, tctx, &r);
1522         if (!NT_STATUS_IS_OK(status)) {
1523                 printf("OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1524         }
1525 
1526         return status;
1527 }
1528 
1529 #if 0
1530 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p,
     /* [<][>][^][v][top][bottom][index][help] */
1531                                    struct torture_context *tctx,
1532                                    struct policy_handle *handle)
1533 {
1534         NTSTATUS status;
1535         struct samr_ChangePasswordUser r;
1536         bool ret = true;
1537         struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1538         struct policy_handle user_handle;
1539         char *oldpass = "test";
1540         char *newpass = "test2";
1541         uint8_t old_nt_hash[16], new_nt_hash[16];
1542         uint8_t old_lm_hash[16], new_lm_hash[16];
1543 
1544         status = test_OpenUser_byname(p, tctx, handle, "testuser", &user_handle);
1545         if (!NT_STATUS_IS_OK(status)) {
1546                 return false;
1547         }
1548 
1549         printf("Testing ChangePasswordUser for user 'testuser'\n");
1550 
1551         printf("old password: %s\n", oldpass);
1552         printf("new password: %s\n", newpass);
1553 
1554         E_md4hash(oldpass, old_nt_hash);
1555         E_md4hash(newpass, new_nt_hash);
1556         E_deshash(oldpass, old_lm_hash);
1557         E_deshash(newpass, new_lm_hash);
1558 
1559         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1560         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1561         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1562         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1563         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1564         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1565 
1566         r.in.handle = &user_handle;
1567         r.in.lm_present = 1;
1568         r.in.old_lm_crypted = &hash1;
1569         r.in.new_lm_crypted = &hash2;
1570         r.in.nt_present = 1;
1571         r.in.old_nt_crypted = &hash3;
1572         r.in.new_nt_crypted = &hash4;
1573         r.in.cross1_present = 1;
1574         r.in.nt_cross = &hash5;
1575         r.in.cross2_present = 1;
1576         r.in.lm_cross = &hash6;
1577 
1578         status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1579         if (!NT_STATUS_IS_OK(status)) {
1580                 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1581                 ret = false;
1582         }
1583 
1584         if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1585                 ret = false;
1586         }
1587 
1588         return ret;
1589 }
1590 #endif
1591 
1592 static bool test_ChangePasswordUser(struct dcerpc_pipe *p, struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
1593                                     const char *acct_name,
1594                                     struct policy_handle *handle, char **password)
1595 {
1596         NTSTATUS status;
1597         struct samr_ChangePasswordUser r;
1598         bool ret = true;
1599         struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1600         struct policy_handle user_handle;
1601         char *oldpass;
1602         uint8_t old_nt_hash[16], new_nt_hash[16];
1603         uint8_t old_lm_hash[16], new_lm_hash[16];
1604         bool changed = true;
1605 
1606         char *newpass;
1607         struct samr_GetUserPwInfo pwp;
1608         struct samr_PwInfo info;
1609         int policy_min_pw_len = 0;
1610 
1611         status = test_OpenUser_byname(p, tctx, handle, acct_name, &user_handle);
1612         if (!NT_STATUS_IS_OK(status)) {
1613                 return false;
1614         }
1615         pwp.in.user_handle = &user_handle;
1616         pwp.out.info = &info;
1617 
1618         status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1619         if (NT_STATUS_IS_OK(status)) {
1620                 policy_min_pw_len = pwp.out.info->min_password_length;
1621         }
1622         newpass = samr_rand_pass(tctx, policy_min_pw_len);
1623 
1624         torture_comment(tctx, "Testing ChangePasswordUser\n");
1625 
1626         torture_assert(tctx, *password != NULL,
1627                                    "Failing ChangePasswordUser as old password was NULL.  Previous test failed?");
1628 
1629         oldpass = *password;
1630 
1631         E_md4hash(oldpass, old_nt_hash);
1632         E_md4hash(newpass, new_nt_hash);
1633         E_deshash(oldpass, old_lm_hash);
1634         E_deshash(newpass, new_lm_hash);
1635 
1636         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1637         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1638         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1639         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1640         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1641         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1642 
1643         r.in.user_handle = &user_handle;
1644         r.in.lm_present = 1;
1645         /* Break the LM hash */
1646         hash1.hash[0]++;
1647         r.in.old_lm_crypted = &hash1;
1648         r.in.new_lm_crypted = &hash2;
1649         r.in.nt_present = 1;
1650         r.in.old_nt_crypted = &hash3;
1651         r.in.new_nt_crypted = &hash4;
1652         r.in.cross1_present = 1;
1653         r.in.nt_cross = &hash5;
1654         r.in.cross2_present = 1;
1655         r.in.lm_cross = &hash6;
1656 
1657         status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1658         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1659                 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1660 
1661         /* Unbreak the LM hash */
1662         hash1.hash[0]--;
1663 
1664         r.in.user_handle = &user_handle;
1665         r.in.lm_present = 1;
1666         r.in.old_lm_crypted = &hash1;
1667         r.in.new_lm_crypted = &hash2;
1668         /* Break the NT hash */
1669         hash3.hash[0]--;
1670         r.in.nt_present = 1;
1671         r.in.old_nt_crypted = &hash3;
1672         r.in.new_nt_crypted = &hash4;
1673         r.in.cross1_present = 1;
1674         r.in.nt_cross = &hash5;
1675         r.in.cross2_present = 1;
1676         r.in.lm_cross = &hash6;
1677 
1678         status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1679         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1680                 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1681 
1682         /* Unbreak the NT hash */
1683         hash3.hash[0]--;
1684 
1685         r.in.user_handle = &user_handle;
1686         r.in.lm_present = 1;
1687         r.in.old_lm_crypted = &hash1;
1688         r.in.new_lm_crypted = &hash2;
1689         r.in.nt_present = 1;
1690         r.in.old_nt_crypted = &hash3;
1691         r.in.new_nt_crypted = &hash4;
1692         r.in.cross1_present = 1;
1693         r.in.nt_cross = &hash5;
1694         r.in.cross2_present = 1;
1695         /* Break the LM cross */
1696         hash6.hash[0]++;
1697         r.in.lm_cross = &hash6;
1698 
1699         status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1700         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1701                 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1702                 ret = false;
1703         }
1704 
1705         /* Unbreak the LM cross */
1706         hash6.hash[0]--;
1707 
1708         r.in.user_handle = &user_handle;
1709         r.in.lm_present = 1;
1710         r.in.old_lm_crypted = &hash1;
1711         r.in.new_lm_crypted = &hash2;
1712         r.in.nt_present = 1;
1713         r.in.old_nt_crypted = &hash3;
1714         r.in.new_nt_crypted = &hash4;
1715         r.in.cross1_present = 1;
1716         /* Break the NT cross */
1717         hash5.hash[0]++;
1718         r.in.nt_cross = &hash5;
1719         r.in.cross2_present = 1;
1720         r.in.lm_cross = &hash6;
1721 
1722         status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1723         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1724                 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1725                 ret = false;
1726         }
1727 
1728         /* Unbreak the NT cross */
1729         hash5.hash[0]--;
1730 
1731 
1732         /* Reset the hashes to not broken values */
1733         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1734         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1735         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1736         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1737         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1738         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1739 
1740         r.in.user_handle = &user_handle;
1741         r.in.lm_present = 1;
1742         r.in.old_lm_crypted = &hash1;
1743         r.in.new_lm_crypted = &hash2;
1744         r.in.nt_present = 1;
1745         r.in.old_nt_crypted = &hash3;
1746         r.in.new_nt_crypted = &hash4;
1747         r.in.cross1_present = 1;
1748         r.in.nt_cross = &hash5;
1749         r.in.cross2_present = 0;
1750         r.in.lm_cross = NULL;
1751 
1752         status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1753         if (NT_STATUS_IS_OK(status)) {
1754                 changed = true;
1755                 *password = newpass;
1756         } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1757                 printf("ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1758                 ret = false;
1759         }
1760 
1761         oldpass = newpass;
1762         newpass = samr_rand_pass(tctx, policy_min_pw_len);
1763 
1764         E_md4hash(oldpass, old_nt_hash);
1765         E_md4hash(newpass, new_nt_hash);
1766         E_deshash(oldpass, old_lm_hash);
1767         E_deshash(newpass, new_lm_hash);
1768 
1769 
1770         /* Reset the hashes to not broken values */
1771         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1772         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1773         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1774         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1775         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1776         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1777 
1778         r.in.user_handle = &user_handle;
1779         r.in.lm_present = 1;
1780         r.in.old_lm_crypted = &hash1;
1781         r.in.new_lm_crypted = &hash2;
1782         r.in.nt_present = 1;
1783         r.in.old_nt_crypted = &hash3;
1784         r.in.new_nt_crypted = &hash4;
1785         r.in.cross1_present = 0;
1786         r.in.nt_cross = NULL;
1787         r.in.cross2_present = 1;
1788         r.in.lm_cross = &hash6;
1789 
1790         status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1791         if (NT_STATUS_IS_OK(status)) {
1792                 changed = true;
1793                 *password = newpass;
1794         } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1795                 printf("ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1796                 ret = false;
1797         }
1798 
1799         oldpass = newpass;
1800         newpass = samr_rand_pass(tctx, policy_min_pw_len);
1801 
1802         E_md4hash(oldpass, old_nt_hash);
1803         E_md4hash(newpass, new_nt_hash);
1804         E_deshash(oldpass, old_lm_hash);
1805         E_deshash(newpass, new_lm_hash);
1806 
1807 
1808         /* Reset the hashes to not broken values */
1809         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1810         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1811         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1812         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1813         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1814         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1815 
1816         r.in.user_handle = &user_handle;
1817         r.in.lm_present = 1;
1818         r.in.old_lm_crypted = &hash1;
1819         r.in.new_lm_crypted = &hash2;
1820         r.in.nt_present = 1;
1821         r.in.old_nt_crypted = &hash3;
1822         r.in.new_nt_crypted = &hash4;
1823         r.in.cross1_present = 1;
1824         r.in.nt_cross = &hash5;
1825         r.in.cross2_present = 1;
1826         r.in.lm_cross = &hash6;
1827 
1828         status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1829         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1830                 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1831         } else  if (!NT_STATUS_IS_OK(status)) {
1832                 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1833                 ret = false;
1834         } else {
1835                 changed = true;
1836                 *password = newpass;
1837         }
1838 
1839         r.in.user_handle = &user_handle;
1840         r.in.lm_present = 1;
1841         r.in.old_lm_crypted = &hash1;
1842         r.in.new_lm_crypted = &hash2;
1843         r.in.nt_present = 1;
1844         r.in.old_nt_crypted = &hash3;
1845         r.in.new_nt_crypted = &hash4;
1846         r.in.cross1_present = 1;
1847         r.in.nt_cross = &hash5;
1848         r.in.cross2_present = 1;
1849         r.in.lm_cross = &hash6;
1850 
1851         if (changed) {
1852                 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1853                 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1854                         printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1855                 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1856                         printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1857                         ret = false;
1858                 }
1859         }
1860 
1861 
1862         if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1863                 ret = false;
1864         }
1865 
1866         return ret;
1867 }
1868 
1869 
1870 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
1871                                         const char *acct_name,
1872                                         struct policy_handle *handle, char **password)
1873 {
1874         NTSTATUS status;
1875         struct samr_OemChangePasswordUser2 r;
1876         bool ret = true;
1877         struct samr_Password lm_verifier;
1878         struct samr_CryptPassword lm_pass;
1879         struct lsa_AsciiString server, account, account_bad;
1880         char *oldpass;
1881         char *newpass;
1882         uint8_t old_lm_hash[16], new_lm_hash[16];
1883 
1884         struct samr_GetDomPwInfo dom_pw_info;
1885         struct samr_PwInfo info;
1886         int policy_min_pw_len = 0;
1887 
1888         struct lsa_String domain_name;
1889 
1890         domain_name.string = "";
1891         dom_pw_info.in.domain_name = &domain_name;
1892         dom_pw_info.out.info = &info;
1893 
1894         torture_comment(tctx, "Testing OemChangePasswordUser2\n");
1895 
1896         torture_assert(tctx, *password != NULL,
1897                                    "Failing OemChangePasswordUser2 as old password was NULL.  Previous test failed?");
1898 
1899         oldpass = *password;
1900 
1901         status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1902         if (NT_STATUS_IS_OK(status)) {
1903                 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1904         }
1905 
1906         newpass = samr_rand_pass(tctx, policy_min_pw_len);
1907 
1908         server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1909         account.string = acct_name;
1910 
1911         E_deshash(oldpass, old_lm_hash);
1912         E_deshash(newpass, new_lm_hash);
1913 
1914         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1915         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1916         E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1917 
1918         r.in.server = &server;
1919         r.in.account = &account;
1920         r.in.password = &lm_pass;
1921         r.in.hash = &lm_verifier;
1922 
1923         /* Break the verification */
1924         lm_verifier.hash[0]++;
1925 
1926         status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1927 
1928         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1929             && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1930                 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1931                         nt_errstr(status));
1932                 ret = false;
1933         }
1934 
1935         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1936         /* Break the old password */
1937         old_lm_hash[0]++;
1938         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1939         /* unbreak it for the next operation */
1940         old_lm_hash[0]--;
1941         E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1942 
1943         r.in.server = &server;
1944         r.in.account = &account;
1945         r.in.password = &lm_pass;
1946         r.in.hash = &lm_verifier;
1947 
1948         status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1949 
1950         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1951             && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1952                 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1953                         nt_errstr(status));
1954                 ret = false;
1955         }
1956 
1957         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1958         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1959 
1960         r.in.server = &server;
1961         r.in.account = &account;
1962         r.in.password = &lm_pass;
1963         r.in.hash = NULL;
1964 
1965         status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1966 
1967         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1968             && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1969                 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1970                         nt_errstr(status));
1971                 ret = false;
1972         }
1973 
1974         /* This shouldn't be a valid name */
1975         account_bad.string = TEST_ACCOUNT_NAME "XX";
1976         r.in.account = &account_bad;
1977 
1978         status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1979 
1980         if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1981                 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1982                         nt_errstr(status));
1983                 ret = false;
1984         }
1985 
1986         /* This shouldn't be a valid name */
1987         account_bad.string = TEST_ACCOUNT_NAME "XX";
1988         r.in.account = &account_bad;
1989         r.in.password = &lm_pass;
1990         r.in.hash = &lm_verifier;
1991 
1992         status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1993 
1994         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1995                 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1996                         nt_errstr(status));
1997                 ret = false;
1998         }
1999 
2000         /* This shouldn't be a valid name */
2001         account_bad.string = TEST_ACCOUNT_NAME "XX";
2002         r.in.account = &account_bad;
2003         r.in.password = NULL;
2004         r.in.hash = &lm_verifier;
2005 
2006         status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
2007 
2008         if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
2009                 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
2010                         nt_errstr(status));
2011                 ret = false;
2012         }
2013 
2014         E_deshash(oldpass, old_lm_hash);
2015         E_deshash(newpass, new_lm_hash);
2016 
2017         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
2018         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2019         E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
2020 
2021         r.in.server = &server;
2022         r.in.account = &account;
2023         r.in.password = &lm_pass;
2024         r.in.hash = &lm_verifier;
2025 
2026         status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
2027         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2028                 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
2029         } else if (!NT_STATUS_IS_OK(status)) {
2030                 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
2031                 ret = false;
2032         } else {
2033                 *password = newpass;
2034         }
2035 
2036         return ret;
2037 }
2038 
2039 
2040 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
2041                                      const char *acct_name,
2042                                      char **password,
2043                                      char *newpass, bool allow_password_restriction)
2044 {
2045         NTSTATUS status;
2046         struct samr_ChangePasswordUser2 r;
2047         bool ret = true;
2048         struct lsa_String server, account;
2049         struct samr_CryptPassword nt_pass, lm_pass;
2050         struct samr_Password nt_verifier, lm_verifier;
2051         char *oldpass;
2052         uint8_t old_nt_hash[16], new_nt_hash[16];
2053         uint8_t old_lm_hash[16], new_lm_hash[16];
2054 
2055         struct samr_GetDomPwInfo dom_pw_info;
2056         struct samr_PwInfo info;
2057 
2058         struct lsa_String domain_name;
2059 
2060         domain_name.string = "";
2061         dom_pw_info.in.domain_name = &domain_name;
2062         dom_pw_info.out.info = &info;
2063 
2064         torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
2065 
2066         torture_assert(tctx, *password != NULL,
2067                                    "Failing ChangePasswordUser2 as old password was NULL.  Previous test failed?");
2068         oldpass = *password;
2069 
2070         if (!newpass) {
2071                 int policy_min_pw_len = 0;
2072                 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
2073                 if (NT_STATUS_IS_OK(status)) {
2074                         policy_min_pw_len = dom_pw_info.out.info->min_password_length;
2075                 }
2076 
2077                 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2078         }
2079 
2080         server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2081         init_lsa_String(&account, acct_name);
2082 
2083         E_md4hash(oldpass, old_nt_hash);
2084         E_md4hash(newpass, new_nt_hash);
2085 
2086         E_deshash(oldpass, old_lm_hash);
2087         E_deshash(newpass, new_lm_hash);
2088 
2089         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
2090         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2091         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2092 
2093         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2094         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2095         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2096 
2097         r.in.server = &server;
2098         r.in.account = &account;
2099         r.in.nt_password = &nt_pass;
2100         r.in.nt_verifier = &nt_verifier;
2101         r.in.lm_change = 1;
2102         r.in.lm_password = &lm_pass;
2103         r.in.lm_verifier = &lm_verifier;
2104 
2105         status = dcerpc_samr_ChangePasswordUser2(p, tctx, &r);
2106         if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2107                 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
2108         } else if (!NT_STATUS_IS_OK(status)) {
2109                 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
2110                 ret = false;
2111         } else {
2112                 *password = newpass;
2113         }
2114 
2115         return ret;
2116 }
2117 
2118 
2119 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
2120                               const char *account_string,
2121                               int policy_min_pw_len,
2122                               char **password,
2123                               const char *newpass,
2124                               NTTIME last_password_change,
2125                               bool handle_reject_reason)
2126 {
2127         NTSTATUS status;
2128         struct samr_ChangePasswordUser3 r;
2129         bool ret = true;
2130         struct lsa_String server, account, account_bad;
2131         struct samr_CryptPassword nt_pass, lm_pass;
2132         struct samr_Password nt_verifier, lm_verifier;
2133         char *oldpass;
2134         uint8_t old_nt_hash[16], new_nt_hash[16];
2135         uint8_t old_lm_hash[16], new_lm_hash[16];
2136         NTTIME t;
2137         struct samr_DomInfo1 *dominfo = NULL;
2138         struct samr_ChangeReject *reject = NULL;
2139 
2140         torture_comment(tctx, "Testing ChangePasswordUser3\n");
2141 
2142         if (newpass == NULL) {
2143                 do {
2144                         if (policy_min_pw_len == 0) {
2145                                 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2146                         } else {
2147                                 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
2148                         }
2149                 } while (check_password_quality(newpass) == false);
2150         } else {
2151                 torture_comment(tctx, "Using password '%s'\n", newpass);
2152         }
2153 
2154         torture_assert(tctx, *password != NULL,
2155                                    "Failing ChangePasswordUser3 as old password was NULL.  Previous test failed?");
2156 
2157         oldpass = *password;
2158         server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2159         init_lsa_String(&account, account_string);
2160 
2161         E_md4hash(oldpass, old_nt_hash);
2162         E_md4hash(newpass, new_nt_hash);
2163 
2164         E_deshash(oldpass, old_lm_hash);
2165         E_deshash(newpass, new_lm_hash);
2166 
2167         encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2168         arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2169         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2170 
2171         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2172         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2173         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2174 
2175         /* Break the verification */
2176         nt_verifier.hash[0]++;
2177 
2178         r.in.server = &server;
2179         r.in.account = &account;
2180         r.in.nt_password = &nt_pass;
2181         r.in.nt_verifier = &nt_verifier;
2182         r.in.lm_change = 1;
2183         r.in.lm_password = &lm_pass;
2184         r.in.lm_verifier = &lm_verifier;
2185         r.in.password3 = NULL;
2186         r.out.dominfo = &dominfo;
2187         r.out.reject = &reject;
2188 
2189         status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2190         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
2191             (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
2192                 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2193                         nt_errstr(status));
2194                 ret = false;
2195         }
2196 
2197         encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2198         arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2199         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2200 
2201         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2202         /* Break the NT hash */
2203         old_nt_hash[0]++;
2204         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2205         /* Unbreak it again */
2206         old_nt_hash[0]--;
2207         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2208 
2209         r.in.server = &server;
2210         r.in.account = &account;
2211         r.in.nt_password = &nt_pass;
2212         r.in.nt_verifier = &nt_verifier;
2213         r.in.lm_change = 1;
2214         r.in.lm_password = &lm_pass;
2215         r.in.lm_verifier = &lm_verifier;
2216         r.in.password3 = NULL;
2217         r.out.dominfo = &dominfo;
2218         r.out.reject = &reject;
2219 
2220         status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2221         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
2222             (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
2223                 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2224                         nt_errstr(status));
2225                 ret = false;
2226         }
2227 
2228         /* This shouldn't be a valid name */
2229         init_lsa_String(&account_bad, talloc_asprintf(tctx, "%sXX", account_string));
2230 
2231         r.in.account = &account_bad;
2232         status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2233         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
2234                 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
2235                         nt_errstr(status));
2236                 ret = false;
2237         }
2238 
2239         E_md4hash(oldpass, old_nt_hash);
2240         E_md4hash(newpass, new_nt_hash);
2241 
2242         E_deshash(oldpass, old_lm_hash);
2243         E_deshash(newpass, new_lm_hash);
2244 
2245         encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2246         arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2247         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2248 
2249         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2250         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2251         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2252 
2253         r.in.server = &server;
2254         r.in.account = &account;
2255         r.in.nt_password = &nt_pass;
2256         r.in.nt_verifier = &nt_verifier;
2257         r.in.lm_change = 1;
2258         r.in.lm_password = &lm_pass;
2259         r.in.lm_verifier = &lm_verifier;
2260         r.in.password3 = NULL;
2261         r.out.dominfo = &dominfo;
2262         r.out.reject = &reject;
2263 
2264         unix_to_nt_time(&t, time(NULL));
2265 
2266         status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2267 
2268         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
2269             && dominfo
2270             && reject
2271             && handle_reject_reason
2272             && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
2273                 if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
2274 
2275                         if (reject && (reject->reason != SAMR_REJECT_OTHER)) {
2276                                 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2277                                         SAMR_REJECT_OTHER, reject->reason);
2278                                 return false;
2279                         }
2280                 }
2281 
2282                 /* We tested the order of precendence which is as follows:
2283 
2284                 * pwd min_age
2285                 * pwd length
2286                 * pwd complexity
2287                 * pwd history
2288 
2289                 Guenther */
2290 
2291                 if ((dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
2292                            (last_password_change + dominfo->min_password_age > t)) {
2293 
2294                         if (reject->reason != SAMR_REJECT_OTHER) {
2295                                 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2296                                         SAMR_REJECT_OTHER, reject->reason);
2297                                 return false;
2298                         }
2299 
2300                 } else if ((dominfo->min_password_length > 0) &&
2301                            (strlen(newpass) < dominfo->min_password_length)) {
2302 
2303                         if (reject->reason != SAMR_REJECT_TOO_SHORT) {
2304                                 printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n",
2305                                         SAMR_REJECT_TOO_SHORT, reject->reason);
2306                                 return false;
2307                         }
2308 
2309                 } else if ((dominfo->password_history_length > 0) &&
2310                             strequal(oldpass, newpass)) {
2311 
2312                         if (reject->reason != SAMR_REJECT_IN_HISTORY) {
2313                                 printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n",
2314                                         SAMR_REJECT_IN_HISTORY, reject->reason);
2315                                 return false;
2316                         }
2317                 } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
2318 
2319                         if (reject->reason != SAMR_REJECT_COMPLEXITY) {
2320                                 printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n",
2321                                         SAMR_REJECT_COMPLEXITY, reject->reason);
2322                                 return false;
2323                         }
2324 
2325                 }
2326 
2327                 if (reject->reason == SAMR_REJECT_TOO_SHORT) {
2328                         /* retry with adjusted size */
2329                         return test_ChangePasswordUser3(p, tctx, account_string,
2330                                                         dominfo->min_password_length,
2331                                                         password, NULL, 0, false);
2332 
2333                 }
2334 
2335         } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2336                 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2337                         printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2338                                SAMR_REJECT_OTHER, reject->reason);
2339                         return false;
2340                 }
2341                 /* Perhaps the server has a 'min password age' set? */
2342 
2343         } else {
2344                 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3");
2345                 *password = talloc_strdup(tctx, newpass);
2346         }
2347 
2348         return ret;
2349 }
2350 
2351 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
2352                                     const char *account_string,
2353                                     struct policy_handle *handle,
2354                                     char **password)
2355 {
2356         NTSTATUS status;
2357         struct samr_ChangePasswordUser3 r;
2358         struct samr_SetUserInfo s;
2359         union samr_UserInfo u;
2360         DATA_BLOB session_key;
2361         DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
2362         uint8_t confounder[16];
2363         struct MD5Context ctx;
2364 
2365         bool ret = true;
2366         struct lsa_String server, account;
2367         struct samr_CryptPassword nt_pass;
2368         struct samr_Password nt_verifier;
2369         DATA_BLOB new_random_pass;
2370         char *newpass;
2371         char *oldpass;
2372         uint8_t old_nt_hash[16], new_nt_hash[16];
2373         NTTIME t;
2374         struct samr_DomInfo1 *dominfo = NULL;
2375         struct samr_ChangeReject *reject = NULL;
2376 
2377         new_random_pass = samr_very_rand_pass(tctx, 128);
2378 
2379         torture_assert(tctx, *password != NULL,
2380                                    "Failing ChangePasswordUser3 as old password was NULL.  Previous test failed?");
2381 
2382         oldpass = *password;
2383         server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2384         init_lsa_String(&account, account_string);
2385 
2386         s.in.user_handle = handle;
2387         s.in.info = &u;
2388         s.in.level = 25;
2389 
2390         ZERO_STRUCT(u);
2391 
2392         u.info25.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT;
2393 
2394         set_pw_in_buffer(u.info25.password.data, &new_random_pass);
2395 
2396         status = dcerpc_fetch_session_key(p, &session_key);
2397         if (!NT_STATUS_IS_OK(status)) {
2398                 printf("SetUserInfo level %u - no session key - %s\n",
2399                        s.in.level, nt_errstr(status));
2400                 return false;
2401         }
2402 
2403         generate_random_buffer((uint8_t *)confounder, 16);
2404 
2405         MD5Init(&ctx);
2406         MD5Update(&ctx, confounder, 16);
2407         MD5Update(&ctx, session_key.data, session_key.length);
2408         MD5Final(confounded_session_key.data, &ctx);
2409 
2410         arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
2411         memcpy(&u.info25.password.data[516], confounder, 16);
2412 
2413         torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
2414 
2415         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
2416         if (!NT_STATUS_IS_OK(status)) {
2417                 printf("SetUserInfo level %u failed - %s\n",
2418                        s.in.level, nt_errstr(status));
2419                 ret = false;
2420         }
2421 
2422         torture_comment(tctx, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
2423 
2424         mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2425 
2426         new_random_pass = samr_very_rand_pass(tctx, 128);
2427 
2428         mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
2429 
2430         set_pw_in_buffer(nt_pass.data, &new_random_pass);
2431         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2432         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2433 
2434         r.in.server = &server;
2435         r.in.account = &account;
2436         r.in.nt_password = &nt_pass;
2437         r.in.nt_verifier = &nt_verifier;
2438         r.in.lm_change = 0;
2439         r.in.lm_password = NULL;
2440         r.in.lm_verifier = NULL;
2441         r.in.password3 = NULL;
2442         r.out.dominfo = &dominfo;
2443         r.out.reject = &reject;
2444 
2445         unix_to_nt_time(&t, time(NULL));
2446 
2447         status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2448 
2449         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2450                 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2451                         printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2452                                SAMR_REJECT_OTHER, reject->reason);
2453                         return false;
2454                 }
2455                 /* Perhaps the server has a 'min password age' set? */
2456 
2457         } else if (!NT_STATUS_IS_OK(status)) {
2458                 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
2459                 ret = false;
2460         }
2461 
2462         newpass = samr_rand_pass(tctx, 128);
2463 
2464         mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2465 
2466         E_md4hash(newpass, new_nt_hash);
2467 
2468         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2469         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2470         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2471 
2472         r.in.server = &server;
2473         r.in.account = &account;
2474         r.in.nt_password = &nt_pass;
2475         r.in.nt_verifier = &nt_verifier;
2476         r.in.lm_change = 0;
2477         r.in.lm_password = NULL;
2478         r.in.lm_verifier = NULL;
2479         r.in.password3 = NULL;
2480         r.out.dominfo = &dominfo;
2481         r.out.reject = &reject;
2482 
2483         unix_to_nt_time(&t, time(NULL));
2484 
2485         status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2486 
2487         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2488                 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2489                         printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2490                                SAMR_REJECT_OTHER, reject->reason);
2491                         return false;
2492                 }
2493                 /* Perhaps the server has a 'min password age' set? */
2494 
2495         } else {
2496                 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3 (on second random password)");
2497                 *password = talloc_strdup(tctx, newpass);
2498         }
2499 
2500         return ret;
2501 }
2502 
2503 
2504 static bool test_GetMembersInAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
2505                                   struct policy_handle *alias_handle)
2506 {
2507         struct samr_GetMembersInAlias r;
2508         struct lsa_SidArray sids;
2509         NTSTATUS status;
2510 
2511         torture_comment(tctx, "Testing GetMembersInAlias\n");
2512 
2513         r.in.alias_handle = alias_handle;
2514         r.out.sids = &sids;
2515 
2516         status = dcerpc_samr_GetMembersInAlias(p, tctx, &r);
2517         torture_assert_ntstatus_ok(tctx, status, "GetMembersInAlias");
2518 
2519         return true;
2520 }
2521 
2522 static bool test_AddMemberToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
2523                                   struct policy_handle *alias_handle,
2524                                   const struct dom_sid *domain_sid)
2525 {
2526         struct samr_AddAliasMember r;
2527         struct samr_DeleteAliasMember d;
2528         NTSTATUS status;
2529         struct dom_sid *sid;
2530 
2531         sid = dom_sid_add_rid(tctx, domain_sid, 512);
2532 
2533         torture_comment(tctx, "testing AddAliasMember\n");
2534         r.in.alias_handle = alias_handle;
2535         r.in.sid = sid;
2536 
2537         status = dcerpc_samr_AddAliasMember(p, tctx, &r);
2538         torture_assert_ntstatus_ok(tctx, status, "AddAliasMember");
2539 
2540         d.in.alias_handle = alias_handle;
2541         d.in.sid = sid;
2542 
2543         status = dcerpc_samr_DeleteAliasMember(p, tctx, &d);
2544         torture_assert_ntstatus_ok(tctx, status, "DelAliasMember");
2545 
2546         return true;
2547 }
2548 
2549 static bool test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
2550                                            struct policy_handle *alias_handle)
2551 {
2552         struct samr_AddMultipleMembersToAlias a;
2553         struct samr_RemoveMultipleMembersFromAlias r;
2554         NTSTATUS status;
2555         struct lsa_SidArray sids;
2556 
2557         torture_comment(tctx, "testing AddMultipleMembersToAlias\n");
2558         a.in.alias_handle = alias_handle;
2559         a.in.sids = &sids;
2560 
2561         sids.num_sids = 3;
2562         sids.sids = talloc_array(tctx, struct lsa_SidPtr, 3);
2563 
2564         sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2565         sids.sids[1].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-2");
2566         sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-3");
2567 
2568         status = dcerpc_samr_AddMultipleMembersToAlias(p, tctx, &a);
2569         torture_assert_ntstatus_ok(tctx, status, "AddMultipleMembersToAlias");
2570 
2571 
2572         torture_comment(tctx, "testing RemoveMultipleMembersFromAlias\n");
2573         r.in.alias_handle = alias_handle;
2574         r.in.sids = &sids;
2575 
2576         status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2577         torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2578 
2579         /* strange! removing twice doesn't give any error */
2580         status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2581         torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2582 
2583         /* but removing an alias that isn't there does */
2584         sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-4");
2585 
2586         status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2587         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, "RemoveMultipleMembersFromAlias");
2588 
2589         return true;
2590 }
2591 
2592 static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
2593                                             struct policy_handle *user_handle)
2594 {
2595         struct samr_TestPrivateFunctionsUser r;
2596         NTSTATUS status;
2597 
2598         torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
2599 
2600         r.in.user_handle = user_handle;
2601 
2602         status = dcerpc_samr_TestPrivateFunctionsUser(p, tctx, &r);
2603         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
2604 
2605         return true;
2606 }
2607 
2608 static bool test_QueryUserInfo_pwdlastset(struct dcerpc_pipe *p,
     /* [<][>][^][v][top][bottom][index][help] */
2609                                           struct torture_context *tctx,
2610                                           struct policy_handle *handle,
2611                                           bool use_info2,
2612                                           NTTIME *pwdlastset)
2613 {
2614         NTSTATUS status;
2615         uint16_t levels[] = { /* 3, */ 5, 21 };
2616         int i;
2617         NTTIME pwdlastset3 = 0;
2618         NTTIME pwdlastset5 = 0;
2619         NTTIME pwdlastset21 = 0;
2620 
2621         torture_comment(tctx, "Testing QueryUserInfo%s level 5 and 21 call ",
2622                         use_info2 ? "2":"");
2623 
2624         for (i=0; i<ARRAY_SIZE(levels); i++) {
2625 
2626                 struct samr_QueryUserInfo r;
2627                 struct samr_QueryUserInfo2 r2;
2628                 union samr_UserInfo *info;
2629 
2630                 if (use_info2) {
2631                         r2.in.user_handle = handle;
2632                         r2.in.level = levels[i];
2633                         r2.out.info = &info;
2634                         status = dcerpc_samr_QueryUserInfo2(p, tctx, &r2);
2635 
2636                 } else {
2637                         r.in.user_handle = handle;
2638                         r.in.level = levels[i];
2639                         r.out.info = &info;
2640                         status = dcerpc_samr_QueryUserInfo(p, tctx, &r);
2641                 }
2642 
2643                 if (!NT_STATUS_IS_OK(status) &&
2644                     !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
2645                         printf("QueryUserInfo%s level %u failed - %s\n",
2646                                use_info2 ? "2":"", levels[i], nt_errstr(status));
2647                         return false;
2648                 }
2649 
2650                 switch (levels[i]) {
2651                 case 3:
2652                         pwdlastset3 = info->info3.last_password_change;
2653                         break;
2654                 case 5:
2655                         pwdlastset5 = info->info5.last_password_change;
2656                         break;
2657                 case 21:
2658                         pwdlastset21 = info->info21.last_password_change;
2659                         break;
2660                 default:
2661                         return false;
2662                 }
2663         }
2664         /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
2665                                     "pwdlastset mixup"); */
2666         torture_assert_int_equal(tctx, pwdlastset5, pwdlastset21,
2667                                  "pwdlastset mixup");
2668 
2669         *pwdlastset = pwdlastset21;
2670 
2671         torture_comment(tctx, "(pwdlastset: %lld)\n", *pwdlastset);
2672 
2673         return true;
2674 }
2675 
2676 static bool test_SamLogon_Creds(struct dcerpc_pipe *p, struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
2677                                 struct cli_credentials *machine_credentials,
2678                                 struct cli_credentials *test_credentials,
2679                                 struct creds_CredentialState *creds,
2680                                 NTSTATUS expected_result)
2681 {
2682         NTSTATUS status;
2683         struct netr_LogonSamLogon r;
2684         struct netr_Authenticator auth, auth2;
2685         union netr_LogonLevel logon;
2686         union netr_Validation validation;
2687         uint8_t authoritative;
2688         struct netr_NetworkInfo ninfo;
2689         DATA_BLOB names_blob, chal, lm_resp, nt_resp;
2690         int flags = CLI_CRED_NTLM_AUTH;
2691 
2692         if (lp_client_lanman_auth(tctx->lp_ctx)) {
2693                 flags |= CLI_CRED_LANMAN_AUTH;
2694         }
2695 
2696         if (lp_client_ntlmv2_auth(tctx->lp_ctx)) {
2697                 flags |= CLI_CRED_NTLMv2_AUTH;
2698         }
2699 
2700         cli_credentials_get_ntlm_username_domain(test_credentials, tctx,
2701                                                  &ninfo.identity_info.account_name.string,
2702                                                  &ninfo.identity_info.domain_name.string);
2703 
2704         generate_random_buffer(ninfo.challenge,
2705                                sizeof(ninfo.challenge));
2706         chal = data_blob_const(ninfo.challenge,
2707                                sizeof(ninfo.challenge));
2708 
2709         names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(machine_credentials),
2710                                                 cli_credentials_get_domain(machine_credentials));
2711 
2712         status = cli_credentials_get_ntlm_response(test_credentials, tctx,
2713                                                    &flags,
2714                                                    chal,
2715                                                    names_blob,
2716                                                    &lm_resp, &nt_resp,
2717                                                    NULL, NULL);
2718         torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
2719 
2720         ninfo.lm.data = lm_resp.data;
2721         ninfo.lm.length = lm_resp.length;
2722 
2723         ninfo.nt.data = nt_resp.data;
2724         ninfo.nt.length = nt_resp.length;
2725 
2726         ninfo.identity_info.parameter_control =
2727                 MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT |
2728                 MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
2729         ninfo.identity_info.logon_id_low = 0;
2730         ninfo.identity_info.logon_id_high = 0;
2731         ninfo.identity_info.workstation.string = cli_credentials_get_workstation(machine_credentials);
2732 
2733         logon.network = &ninfo;
2734 
2735         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2736         r.in.computer_name = cli_credentials_get_workstation(machine_credentials);
2737         r.in.credential = &auth;
2738         r.in.return_authenticator = &auth2;
2739         r.in.logon_level = 2;
2740         r.in.logon = &logon;
2741         r.out.validation = &validation;
2742         r.out.authoritative = &authoritative;
2743 
2744         d_printf("Testing LogonSamLogon with name %s\n", ninfo.identity_info.account_name.string);
2745 
2746         ZERO_STRUCT(auth2);
2747         creds_client_authenticator(creds, &auth);
2748 
2749         r.in.validation_level = 2;
2750 
2751         status = dcerpc_netr_LogonSamLogon(p, tctx, &r);
2752         if (!NT_STATUS_IS_OK(status)) {
2753                 torture_assert_ntstatus_equal(tctx, status, expected_result, "LogonSamLogon failed");
2754                 return true;
2755         } else {
2756                 torture_assert_ntstatus_ok(tctx, status, "LogonSamLogon failed");
2757         }
2758 
2759         torture_assert(tctx, creds_client_check(creds, &r.out.return_authenticator->cred),
2760                         "Credential chaining failed");
2761 
2762         return true;
2763 }
2764 
2765 static bool test_SamLogon(struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
2766                           struct dcerpc_pipe *p,
2767                           struct cli_credentials *machine_credentials,
2768                           struct cli_credentials *test_credentials,
2769                           NTSTATUS expected_result)
2770 {
2771         struct creds_CredentialState *creds;
2772 
2773         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
2774                 return false;
2775         }
2776 
2777         return test_SamLogon_Creds(p, tctx, machine_credentials, test_credentials,
2778                                    creds, expected_result);
2779 }
2780 
2781 static bool test_SamLogon_with_creds(struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
2782                                      struct dcerpc_pipe *p,
2783                                      struct cli_credentials *machine_creds,
2784                                      const char *acct_name,
2785                                      char *password,
2786                                      NTSTATUS expected_samlogon_result)
2787 {
2788         bool ret = true;
2789         struct cli_credentials *test_credentials;
2790 
2791         test_credentials = cli_credentials_init(tctx);
2792 
2793         cli_credentials_set_workstation(test_credentials,
2794                                         TEST_ACCOUNT_NAME_PWD, CRED_SPECIFIED);
2795         cli_credentials_set_domain(test_credentials,
2796                                    lp_workgroup(tctx->lp_ctx), CRED_SPECIFIED);
2797         cli_credentials_set_username(test_credentials,
2798                                      acct_name, CRED_SPECIFIED);
2799         cli_credentials_set_password(test_credentials,
2800                                      password, CRED_SPECIFIED);
2801         cli_credentials_set_secure_channel_type(test_credentials, SEC_CHAN_BDC);
2802 
2803         printf("testing samlogon as %s@%s password: %s\n",
2804                 acct_name, TEST_ACCOUNT_NAME_PWD, password);
2805 
2806         if (!test_SamLogon(tctx, p, machine_creds, test_credentials,
2807                            expected_samlogon_result)) {
2808                 torture_warning(tctx, "new password did not work\n");
2809                 ret = false;
2810         }
2811 
2812         return ret;
2813 }
2814 
2815 static bool test_SetPassword_level(struct dcerpc_pipe *p,
     /* [<][>][^][v][top][bottom][index][help] */
2816                                    struct dcerpc_pipe *np,
2817                                    struct torture_context *tctx,
2818                                    struct policy_handle *handle,
2819                                    uint16_t level,
2820                                    uint32_t fields_present,
2821                                    uint8_t password_expired,
2822                                    bool *matched_expected_error,
2823                                    bool use_setinfo2,
2824                                    const char *acct_name,
2825                                    char **password,
2826                                    struct cli_credentials *machine_creds,
2827                                    bool use_queryinfo2,
2828                                    NTTIME *pwdlastset,
2829                                    NTSTATUS expected_samlogon_result)
2830 {
2831         const char *fields = NULL;
2832         bool ret = true;
2833 
2834         switch (level) {
2835         case 21:
2836         case 23:
2837         case 25:
2838                 fields = talloc_asprintf(tctx, "(fields_present: 0x%08x)",
2839                                          fields_present);
2840                 break;
2841         default:
2842                 break;
2843         }
2844 
2845         torture_comment(tctx, "Testing SetUserInfo%s level %d call "
2846                 "(password_expired: %d) %s\n",
2847                 use_setinfo2 ? "2":"", level, password_expired,
2848                 fields ? fields : "");
2849 
2850         if (!test_SetUserPass_level_ex(p, tctx, handle, level,
2851                                        fields_present,
2852                                        password,
2853                                        password_expired,
2854                                        use_setinfo2,
2855                                        matched_expected_error)) {
2856                 ret = false;
2857         }
2858 
2859         if (!test_QueryUserInfo_pwdlastset(p, tctx, handle,
2860                                            use_queryinfo2,
2861                                            pwdlastset)) {
2862                 ret = false;
2863         }
2864 
2865         if (*matched_expected_error == true) {
2866                 return ret;
2867         }
2868 
2869         if (!test_SamLogon_with_creds(tctx, np,
2870                                       machine_creds,
2871                                       acct_name,
2872                                       *password,
2873                                       expected_samlogon_result)) {
2874                 ret = false;
2875         }
2876 
2877         return ret;
2878 }
2879 
2880 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
     /* [<][>][^][v][top][bottom][index][help] */
2881                                         struct torture_context *tctx,
2882                                         uint32_t acct_flags,
2883                                         const char *acct_name,
2884                                         struct policy_handle *handle,
2885                                         char **password,
2886                                         struct cli_credentials *machine_credentials)
2887 {
2888         int s = 0, q = 0, f = 0, l = 0, z = 0;
2889         bool ret = true;
2890         int delay = 500000;
2891         bool set_levels[] = { false, true };
2892         bool query_levels[] = { false, true };
2893         uint32_t levels[] = { 18, 21, 23, 24, 25, 26 };
2894         uint32_t nonzeros[] = { 1, 24 };
2895         uint32_t fields_present[] = {
2896                 0,
2897                 SAMR_FIELD_EXPIRED_FLAG,
2898                 SAMR_FIELD_LAST_PWD_CHANGE,
2899                 SAMR_FIELD_EXPIRED_FLAG | SAMR_FIELD_LAST_PWD_CHANGE,
2900                 SAMR_FIELD_COMMENT,
2901                 SAMR_FIELD_NT_PASSWORD_PRESENT,
2902                 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
2903                 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
2904                 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
2905                 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
2906                 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
2907                 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE | SAMR_FIELD_EXPIRED_FLAG
2908         };
2909         NTSTATUS status;
2910         struct dcerpc_pipe *np = NULL;
2911 
2912         if (torture_setting_bool(tctx, "samba3", false)) {
2913                 delay = 999999;
2914                 printf("Samba3 has second granularity, setting delay to: %d\n",
2915                         delay);
2916         }
2917 
2918         status = torture_rpc_connection(tctx, &np, &ndr_table_netlogon);
2919         if (!NT_STATUS_IS_OK(status)) {
2920                 return false;
2921         }
2922 
2923         /* set to 1 to enable testing for all possible opcode
2924            (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
2925            combinations */
2926 #if 0
2927 #define TEST_SET_LEVELS 1
2928 #define TEST_QUERY_LEVELS 1
2929 #endif
2930         for (l=0; l<ARRAY_SIZE(levels); l++) {
2931         for (z=0; z<ARRAY_SIZE(nonzeros); z++) {
2932         for (f=0; f<ARRAY_SIZE(fields_present); f++) {
2933 #ifdef TEST_SET_LEVELS
2934         for (s=0; s<ARRAY_SIZE(set_levels); s++) {
2935 #endif
2936 #ifdef TEST_QUERY_LEVELS
2937         for (q=0; q<ARRAY_SIZE(query_levels); q++) {
2938 #endif
2939                 NTTIME pwdlastset_old = 0;
2940                 NTTIME pwdlastset_new = 0;
2941                 bool matched_expected_error = false;
2942                 NTSTATUS expected_samlogon_result = NT_STATUS_ACCOUNT_DISABLED;
2943 
2944                 torture_comment(tctx, "------------------------------\n"
2945                                 "Testing pwdLastSet attribute for flags: 0x%08x "
2946                                 "(s: %d (l: %d), q: %d)\n",
2947                                 acct_flags, s, levels[l], q);
2948 
2949                 switch (levels[l]) {
2950                 case 21:
2951                 case 23:
2952                 case 25:
2953                         if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
2954                               (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT))) {
2955                                 expected_samlogon_result = NT_STATUS_WRONG_PASSWORD;
2956                         }
2957                         break;
2958                 }
2959 
2960 
2961                 /* set #1 */
2962 
2963                 /* set a password and force password change (pwdlastset 0) by
2964                  * setting the password expired flag to a non-0 value */
2965 
2966                 if (!test_SetPassword_level(p, np, tctx, handle,
2967                                             levels[l],
2968                                             fields_present[f],
2969                                             nonzeros[z],
2970                                             &matched_expected_error,
2971                                             set_levels[s],
2972                                             acct_name,
2973                                             password,
2974                                             machine_credentials,
2975                                             query_levels[q],
2976                                             &pwdlastset_old,
2977                                             expected_samlogon_result)) {
2978                         ret = false;
2979                 }
2980 
2981                 if (matched_expected_error == true) {
2982                         /* skipping on expected failure */
2983                         continue;
2984                 }
2985 
2986                 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
2987                  * set without the SAMR_FIELD_EXPIRED_FLAG */
2988 
2989                 switch (levels[l]) {
2990                 case 21:
2991                 case 23:
2992                 case 25:
2993                         if ((pwdlastset_new != 0) &&
2994                             !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
2995                                 torture_comment(tctx, "not considering a non-0 "
2996                                         "pwdLastSet as a an error as the "
2997                                         "SAMR_FIELD_EXPIRED_FLAG has not "
2998                                         "been set\n");
2999                                 break;
3000                         }
3001                 default:
3002                         if (pwdlastset_new != 0) {
3003                                 torture_warning(tctx, "pwdLastSet test failed: "
3004                                         "expected pwdLastSet 0 but got %lld\n",
3005                                         pwdlastset_old);
3006                                 ret = false;
3007                         }
3008                         break;
3009                 }
3010 
3011                 switch (levels[l]) {
3012                 case 21:
3013                 case 23:
3014                 case 25:
3015                         if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3016                              (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3017                              (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3018                              (pwdlastset_old >= pwdlastset_new)) {
3019                                 torture_warning(tctx, "pwdlastset not increasing\n");
3020                                 ret = false;
3021                         }
3022                         break;
3023                 default:
3024                         if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3025                             (pwdlastset_old >= pwdlastset_new)) {
3026                                 torture_warning(tctx, "pwdlastset not increasing\n");
3027                                 ret = false;
3028                         }
3029                         break;
3030                 }
3031 
3032                 usleep(delay);
3033 
3034                 /* set #2 */
3035 
3036                 /* set a password, pwdlastset needs to get updated (increased
3037                  * value), password_expired value used here is 0 */
3038 
3039                 if (!test_SetPassword_level(p, np, tctx, handle,
3040                                             levels[l],
3041                                             fields_present[f],
3042                                             0,
3043                                             &matched_expected_error,
3044                                             set_levels[s],
3045                                             acct_name,
3046                                             password,
3047                                             machine_credentials,
3048                                             query_levels[q],
3049                                             &pwdlastset_new,
3050                                             expected_samlogon_result)) {
3051                         ret = false;
3052                 }
3053 
3054                 /* when a password has been changed, pwdlastset must not be 0 afterwards
3055                  * and must be larger then the old value */
3056 
3057                 switch (levels[l]) {
3058                 case 21:
3059                 case 23:
3060                 case 25:
3061 
3062                         /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3063                          * password has been changed, old and new pwdlastset
3064                          * need to be the same value */
3065 
3066                         if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3067                             !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3068                               (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3069                         {
3070                                 torture_assert_int_equal(tctx, pwdlastset_old,
3071                                         pwdlastset_new, "pwdlastset must be equal");
3072                                 break;
3073                         }
3074                 default:
3075                         if (pwdlastset_old >= pwdlastset_new) {
3076                                 torture_warning(tctx, "pwdLastSet test failed: "
3077                                         "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3078                                         pwdlastset_old, pwdlastset_new);
3079                                 ret = false;
3080                         }
3081                         if (pwdlastset_new == 0) {
3082                                 torture_warning(tctx, "pwdLastSet test failed: "
3083                                         "expected non-0 pwdlastset, got: %lld\n",
3084                                         pwdlastset_new);
3085                                 ret = false;
3086                         }
3087                 }
3088 
3089                 switch (levels[l]) {
3090                 case 21:
3091                 case 23:
3092                 case 25:
3093                         if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3094                              (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3095                              (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3096                              (pwdlastset_old >= pwdlastset_new)) {
3097                                 torture_warning(tctx, "pwdlastset not increasing\n");
3098                                 ret = false;
3099                         }
3100                         break;
3101                 default:
3102                         if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3103                             (pwdlastset_old >= pwdlastset_new)) {
3104                                 torture_warning(tctx, "pwdlastset not increasing\n");
3105                                 ret = false;
3106                         }
3107                         break;
3108                 }
3109 
3110                 pwdlastset_old = pwdlastset_new;
3111 
3112                 usleep(delay);
3113 
3114                 /* set #2b */
3115 
3116                 /* set a password, pwdlastset needs to get updated (increased
3117                  * value), password_expired value used here is 0 */
3118 
3119                 if (!test_SetPassword_level(p, np, tctx, handle,
3120                                             levels[l],
3121                                             fields_present[f],
3122                                             0,
3123                                             &matched_expected_error,
3124                                             set_levels[s],
3125                                             acct_name,
3126                                             password,
3127                                             machine_credentials,
3128                                             query_levels[q],
3129                                             &pwdlastset_new,
3130                                             expected_samlogon_result)) {
3131                         ret = false;
3132                 }
3133 
3134                 /* when a password has been changed, pwdlastset must not be 0 afterwards
3135                  * and must be larger then the old value */
3136 
3137                 switch (levels[l]) {
3138                 case 21:
3139                 case 23:
3140                 case 25:
3141 
3142                         /* if no password has been changed, old and new pwdlastset
3143                          * need to be the same value */
3144 
3145                         if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3146                               (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3147                         {
3148                                 torture_assert_int_equal(tctx, pwdlastset_old,
3149                                         pwdlastset_new, "pwdlastset must be equal");
3150                                 break;
3151                         }
3152                 default:
3153                         if (pwdlastset_old >= pwdlastset_new) {
3154                                 torture_warning(tctx, "pwdLastSet test failed: "
3155                                         "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3156                                         pwdlastset_old, pwdlastset_new);
3157                                 ret = false;
3158                         }
3159                         if (pwdlastset_new == 0) {
3160                                 torture_warning(tctx, "pwdLastSet test failed: "
3161                                         "expected non-0 pwdlastset, got: %lld\n",
3162                                         pwdlastset_new);
3163                                 ret = false;
3164                         }
3165                 }
3166 
3167                 /* set #3 */
3168 
3169                 /* set a password and force password change (pwdlastset 0) by
3170                  * setting the password expired flag to a non-0 value */
3171 
3172                 if (!test_SetPassword_level(p, np, tctx, handle,
3173                                             levels[l],
3174                                             fields_present[f],
3175                                             nonzeros[z],
3176                                             &matched_expected_error,
3177                                             set_levels[s],
3178                                             acct_name,
3179                                             password,
3180                                             machine_credentials,
3181                                             query_levels[q],
3182                                             &pwdlastset_new,
3183                                             expected_samlogon_result)) {
3184                         ret = false;
3185                 }
3186 
3187                 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3188                  * set without the SAMR_FIELD_EXPIRED_FLAG */
3189 
3190                 switch (levels[l]) {
3191                 case 21:
3192                 case 23:
3193                 case 25:
3194                         if ((pwdlastset_new != 0) &&
3195                             !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
3196                                 torture_comment(tctx, "not considering a non-0 "
3197                                         "pwdLastSet as a an error as the "
3198                                         "SAMR_FIELD_EXPIRED_FLAG has not "
3199                                         "been set\n");
3200                                 break;
3201                         }
3202 
3203                         /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3204                          * password has been changed, old and new pwdlastset
3205                          * need to be the same value */
3206 
3207                         if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3208                             !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3209                               (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3210                         {
3211                                 torture_assert_int_equal(tctx, pwdlastset_old,
3212                                         pwdlastset_new, "pwdlastset must be equal");
3213                                 break;
3214                         }
3215                 default:
3216 
3217                         if (pwdlastset_old == pwdlastset_new) {
3218                                 torture_warning(tctx, "pwdLastSet test failed: "
3219                                         "expected last pwdlastset (%lld) != new pwdlastset (%lld)\n",
3220                                         pwdlastset_old, pwdlastset_new);
3221                                 ret = false;
3222                         }
3223 
3224                         if (pwdlastset_new != 0) {
3225                                 torture_warning(tctx, "pwdLastSet test failed: "
3226                                         "expected pwdLastSet 0, got %lld\n",
3227                                         pwdlastset_old);
3228                                 ret = false;
3229                         }
3230                         break;
3231                 }
3232 
3233                 switch (levels[l]) {
3234                 case 21:
3235                 case 23:
3236                 case 25:
3237                         if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3238                              (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3239                              (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3240                              (pwdlastset_old >= pwdlastset_new)) {
3241                                 torture_warning(tctx, "pwdlastset not increasing\n");
3242                                 ret = false;
3243                         }
3244                         break;
3245                 default:
3246                         if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3247                             (pwdlastset_old >= pwdlastset_new)) {
3248                                 torture_warning(tctx, "pwdlastset not increasing\n");
3249                                 ret = false;
3250                         }
3251                         break;
3252                 }
3253 
3254                 /* if the level we are testing does not have a fields_present
3255                  * field, skip all fields present tests by setting f to to
3256                  * arraysize */
3257                 switch (levels[l]) {
3258                 case 18:
3259                 case 24:
3260                 case 26:
3261                         f = ARRAY_SIZE(fields_present);
3262                         break;
3263                 }
3264 
3265 #ifdef TEST_QUERY_LEVELS
3266         }
3267 #endif
3268 #ifdef TEST_SET_LEVELS
3269         }
3270 #endif
3271         } /* fields present */
3272         } /* nonzeros */
3273         } /* levels */
3274 
3275 #undef TEST_SET_LEVELS
3276 #undef TEST_QUERY_LEVELS
3277 
3278         return ret;
3279 }
3280 
3281 static bool test_DeleteUser_with_privs(struct dcerpc_pipe *p,
     /* [<][>][^][v][top][bottom][index][help] */
3282                                        struct dcerpc_pipe *lp,
3283                                        struct torture_context *tctx,
3284                                        struct policy_handle *domain_handle,
3285                                        struct policy_handle *lsa_handle,
3286                                        struct policy_handle *user_handle,
3287                                        const struct dom_sid *domain_sid,
3288                                        uint32_t rid,
3289                                        struct cli_credentials *machine_credentials)
3290 {
3291         NTSTATUS status;
3292         bool ret = true;
3293 
3294         struct policy_handle lsa_acct_handle;
3295         struct dom_sid *user_sid;
3296 
3297         user_sid = dom_sid_add_rid(tctx, domain_sid, rid);
3298 
3299         {
3300                 struct lsa_EnumAccountRights r;
3301                 struct lsa_RightSet rights;
3302 
3303                 printf("Testing LSA EnumAccountRights\n");
3304 
3305                 r.in.handle = lsa_handle;
3306                 r.in.sid = user_sid;
3307                 r.out.rights = &rights;
3308 
3309                 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
3310                 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3311                         "Expected enum rights for account to fail");
3312         }
3313 
3314         {
3315                 struct lsa_RightSet rights;
3316                 struct lsa_StringLarge names[2];
3317                 struct lsa_AddAccountRights r;
3318 
3319                 printf("Testing LSA AddAccountRights\n");
3320 
3321                 init_lsa_StringLarge(&names[0], "SeMachineAccountPrivilege");
3322                 init_lsa_StringLarge(&names[1], NULL);
3323 
3324                 rights.count = 1;
3325                 rights.names = names;
3326 
3327                 r.in.handle = lsa_handle;
3328                 r.in.sid = user_sid;
3329                 r.in.rights = &rights;
3330 
3331                 status = dcerpc_lsa_AddAccountRights(lp, tctx, &r);
3332                 torture_assert_ntstatus_ok(tctx, status,
3333                         "Failed to add privileges");
3334         }
3335 
3336         {
3337                 struct lsa_EnumAccounts r;
3338                 uint32_t resume_handle = 0;
3339                 struct lsa_SidArray lsa_sid_array;
3340                 int i;
3341                 bool found_sid = false;
3342 
3343                 printf("Testing LSA EnumAccounts\n");
3344 
3345                 r.in.handle = lsa_handle;
3346                 r.in.num_entries = 0x1000;
3347                 r.in.resume_handle = &resume_handle;
3348                 r.out.sids = &lsa_sid_array;
3349                 r.out.resume_handle = &resume_handle;
3350 
3351                 status = dcerpc_lsa_EnumAccounts(lp, tctx, &r);
3352                 torture_assert_ntstatus_ok(tctx, status,
3353                         "Failed to enum accounts");
3354 
3355                 for (i=0; i < lsa_sid_array.num_sids; i++) {
3356                         if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
3357                                 found_sid = true;
3358                         }
3359                 }
3360 
3361                 torture_assert(tctx, found_sid,
3362                         "failed to list privileged account");
3363         }
3364 
3365         {
3366                 struct lsa_EnumAccountRights r;
3367                 struct lsa_RightSet user_rights;
3368 
3369                 printf("Testing LSA EnumAccountRights\n");
3370 
3371                 r.in.handle = lsa_handle;
3372                 r.in.sid = user_sid;
3373                 r.out.rights = &user_rights;
3374 
3375                 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
3376                 torture_assert_ntstatus_ok(tctx, status,
3377                         "Failed to enum rights for account");
3378 
3379                 if (user_rights.count < 1) {
3380                         torture_warning(tctx, "failed to find newly added rights");
3381                         return false;
3382                 }
3383         }
3384 
3385         {
3386                 struct lsa_OpenAccount r;
3387 
3388                 printf("Testing LSA OpenAccount\n");
3389 
3390                 r.in.handle = lsa_handle;
3391                 r.in.sid = user_sid;
3392                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3393                 r.out.acct_handle = &lsa_acct_handle;
3394 
3395                 status = dcerpc_lsa_OpenAccount(lp, tctx, &r);
3396                 torture_assert_ntstatus_ok(tctx, status,
3397                         "Failed to open lsa account");
3398         }
3399 
3400         {
3401                 struct lsa_GetSystemAccessAccount r;
3402                 uint32_t access_mask;
3403 
3404                 printf("Testing LSA GetSystemAccessAccount\n");
3405 
3406                 r.in.handle = &lsa_acct_handle;
3407                 r.out.access_mask = &access_mask;
3408 
3409                 status = dcerpc_lsa_GetSystemAccessAccount(lp, tctx, &r);
3410                 torture_assert_ntstatus_ok(tctx, status,
3411                         "Failed to get lsa system access account");
3412         }
3413 
3414         {
3415                 struct lsa_Close r;
3416 
3417                 printf("Testing LSA Close\n");
3418 
3419                 r.in.handle = &lsa_acct_handle;
3420                 r.out.handle = &lsa_acct_handle;
3421 
3422                 status = dcerpc_lsa_Close(lp, tctx, &r);
3423                 torture_assert_ntstatus_ok(tctx, status,
3424                         "Failed to close lsa");
3425         }
3426 
3427         {
3428                 struct samr_DeleteUser r;
3429 
3430                 printf("Testing SAMR DeleteUser\n");
3431 
3432                 r.in.user_handle = user_handle;
3433                 r.out.user_handle = user_handle;
3434 
3435                 status = dcerpc_samr_DeleteUser(p, tctx, &r);
3436                 torture_assert_ntstatus_ok(tctx, status, "Delete User failed");
3437         }
3438 
3439         {
3440                 struct lsa_EnumAccounts r;
3441                 uint32_t resume_handle = 0;
3442                 struct lsa_SidArray lsa_sid_array;
3443                 int i;
3444                 bool found_sid = false;
3445 
3446                 printf("Testing LSA EnumAccounts\n");
3447 
3448                 r.in.handle = lsa_handle;
3449                 r.in.num_entries = 0x1000;
3450                 r.in.resume_handle = &resume_handle;
3451                 r.out.sids = &lsa_sid_array;
3452                 r.out.resume_handle = &resume_handle;
3453 
3454                 status = dcerpc_lsa_EnumAccounts(lp, tctx, &r);
3455                 torture_assert_ntstatus_ok(tctx, status,
3456                         "Failed to enum accounts");
3457 
3458                 for (i=0; i < lsa_sid_array.num_sids; i++) {
3459                         if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
3460                                 found_sid = true;
3461                         }
3462                 }
3463 
3464                 torture_assert(tctx, found_sid,
3465                         "failed to list privileged account");
3466         }
3467 
3468         {
3469                 struct lsa_EnumAccountRights r;
3470                 struct lsa_RightSet user_rights;
3471 
3472                 printf("Testing LSA EnumAccountRights\n");
3473 
3474                 r.in.handle = lsa_handle;
3475                 r.in.sid = user_sid;
3476                 r.out.rights = &user_rights;
3477 
3478                 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
3479                 torture_assert_ntstatus_ok(tctx, status,
3480                         "Failed to enum rights for account");
3481 
3482                 if (user_rights.count < 1) {
3483                         torture_warning(tctx, "failed to find newly added rights");
3484                         return false;
3485                 }
3486         }
3487 
3488         {
3489                 struct lsa_OpenAccount r;
3490 
3491                 printf("Testing LSA OpenAccount\n");
3492 
3493                 r.in.handle = lsa_handle;
3494                 r.in.sid = user_sid;
3495                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3496                 r.out.acct_handle = &lsa_acct_handle;
3497 
3498                 status = dcerpc_lsa_OpenAccount(lp, tctx, &r);
3499                 torture_assert_ntstatus_ok(tctx, status,
3500                         "Failed to open lsa account");
3501         }
3502 
3503         {
3504                 struct lsa_GetSystemAccessAccount r;
3505                 uint32_t access_mask;
3506 
3507                 printf("Testing LSA GetSystemAccessAccount\n");
3508 
3509                 r.in.handle = &lsa_acct_handle;
3510                 r.out.access_mask = &access_mask;
3511 
3512                 status = dcerpc_lsa_GetSystemAccessAccount(lp, tctx, &r);
3513                 torture_assert_ntstatus_ok(tctx, status,
3514                         "Failed to get lsa system access account");
3515         }
3516 
3517         {
3518                 struct lsa_DeleteObject r;
3519 
3520                 printf("Testing LSA DeleteObject\n");
3521 
3522                 r.in.handle = &lsa_acct_handle;
3523                 r.out.handle = &lsa_acct_handle;
3524 
3525                 status = dcerpc_lsa_DeleteObject(lp, tctx, &r);
3526                 torture_assert_ntstatus_ok(tctx, status,
3527                         "Failed to delete object");
3528         }
3529 
3530         {
3531                 struct lsa_EnumAccounts r;
3532                 uint32_t resume_handle = 0;
3533                 struct lsa_SidArray lsa_sid_array;
3534                 int i;
3535                 bool found_sid = false;
3536 
3537                 printf("Testing LSA EnumAccounts\n");
3538 
3539                 r.in.handle = lsa_handle;
3540                 r.in.num_entries = 0x1000;
3541                 r.in.resume_handle = &resume_handle;
3542                 r.out.sids = &lsa_sid_array;
3543                 r.out.resume_handle = &resume_handle;
3544 
3545                 status = dcerpc_lsa_EnumAccounts(lp, tctx, &r);
3546                 torture_assert_ntstatus_ok(tctx, status,
3547                         "Failed to enum accounts");
3548 
3549                 for (i=0; i < lsa_sid_array.num_sids; i++) {
3550                         if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
3551                                 found_sid = true;
3552                         }
3553                 }
3554 
3555                 torture_assert(tctx, !found_sid,
3556                         "should not have listed privileged account");
3557         }
3558 
3559         {
3560                 struct lsa_EnumAccountRights r;
3561                 struct lsa_RightSet user_rights;
3562 
3563                 printf("Testing LSA EnumAccountRights\n");
3564 
3565                 r.in.handle = lsa_handle;
3566                 r.in.sid = user_sid;
3567                 r.out.rights = &user_rights;
3568 
3569                 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
3570                 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3571                         "Failed to enum rights for account");
3572         }
3573 
3574         return ret;
3575 }
3576 
3577 static bool test_user_ops(struct dcerpc_pipe *p,
     /* [<][>][^][v][top][bottom][index][help] */
3578                           struct torture_context *tctx,
3579                           struct policy_handle *user_handle,
3580                           struct policy_handle *domain_handle,
3581                           const struct dom_sid *domain_sid,
3582                           uint32_t base_acct_flags,
3583                           const char *base_acct_name, enum torture_samr_choice which_ops,
3584                           struct cli_credentials *machine_credentials)
3585 {
3586         char *password = NULL;
3587         struct samr_QueryUserInfo q;
3588         union samr_UserInfo *info;
3589         NTSTATUS status;
3590 
3591         bool ret = true;
3592         int i;
3593         uint32_t rid;
3594         const uint32_t password_fields[] = {
3595                 SAMR_FIELD_NT_PASSWORD_PRESENT,
3596                 SAMR_FIELD_LM_PASSWORD_PRESENT,
3597                 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
3598                 0
3599         };
3600 
3601         status = test_LookupName(p, tctx, domain_handle, base_acct_name, &rid);
3602         if (!NT_STATUS_IS_OK(status)) {
3603                 ret = false;
3604         }
3605 
3606         switch (which_ops) {
3607         case TORTURE_SAMR_USER_ATTRIBUTES:
3608                 if (!test_QuerySecurity(p, tctx, user_handle)) {
3609                         ret = false;
3610                 }
3611 
3612                 if (!test_QueryUserInfo(p, tctx, user_handle)) {
3613                         ret = false;
3614                 }
3615 
3616                 if (!test_QueryUserInfo2(p, tctx, user_handle)) {
3617                         ret = false;
3618                 }
3619 
3620                 if (!test_SetUserInfo(p, tctx, user_handle, base_acct_flags,
3621                                       base_acct_name)) {
3622                         ret = false;
3623                 }
3624 
3625                 if (!test_GetUserPwInfo(p, tctx, user_handle)) {
3626                         ret = false;
3627                 }
3628 
3629                 if (!test_TestPrivateFunctionsUser(p, tctx, user_handle)) {
3630                         ret = false;
3631                 }
3632 
3633                 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
3634                         ret = false;
3635                 }
3636                 break;
3637         case TORTURE_SAMR_PASSWORDS:
3638                 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
3639                         char simple_pass[9];
3640                         char *v = generate_random_str(tctx, 1);
3641 
3642                         ZERO_STRUCT(simple_pass);
3643                         memset(simple_pass, *v, sizeof(simple_pass) - 1);
3644 
3645                         printf("Testing machine account password policy rules\n");
3646 
3647                         /* Workstation trust accounts don't seem to need to honour password quality policy */
3648                         if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
3649                                 ret = false;
3650                         }
3651 
3652                         if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
3653                                 ret = false;
3654                         }
3655 
3656                         /* reset again, to allow another 'user' password change */
3657                         if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
3658                                 ret = false;
3659                         }
3660 
3661                         /* Try a 'short' password */
3662                         if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
3663                                 ret = false;
3664                         }
3665 
3666                         /* Try a compleatly random password */
3667                         if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
3668                                 ret = false;
3669                         }
3670                 }
3671 
3672                 for (i = 0; password_fields[i]; i++) {
3673                         if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
3674                                 ret = false;
3675                         }
3676 
3677                         /* check it was set right */
3678                         if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3679                                 ret = false;
3680                         }
3681                 }
3682 
3683                 for (i = 0; password_fields[i]; i++) {
3684                         if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
3685                                 ret = false;
3686                         }
3687 
3688                         /* check it was set right */
3689                         if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3690                                 ret = false;
3691                         }
3692                 }
3693 
3694                 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
3695                         ret = false;
3696                 }
3697 
3698                 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
3699                         ret = false;
3700                 }
3701 
3702                 if (torture_setting_bool(tctx, "samba4", false)) {
3703                         printf("skipping Set Password level 18 and 21 against Samba4\n");
3704                 } else {
3705 
3706                         if (!test_SetUserPass_18(p, tctx, user_handle, &password)) {
3707                                 ret = false;
3708                         }
3709 
3710                         if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3711                                 ret = false;
3712                         }
3713 
3714                         for (i = 0; password_fields[i]; i++) {
3715 
3716                                 if (password_fields[i] == SAMR_FIELD_LM_PASSWORD_PRESENT) {
3717                                         /* we need to skip as that would break
3718                                          * the ChangePasswordUser3 verify */
3719                                         continue;
3720                                 }
3721 
3722                                 if (!test_SetUserPass_21(p, tctx, user_handle, password_fields[i], &password)) {
3723                                         ret = false;
3724                                 }
3725 
3726                                 /* check it was set right */
3727                                 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3728                                         ret = false;
3729                                 }
3730                         }
3731                 }
3732 
3733                 q.in.user_handle = user_handle;
3734                 q.in.level = 5;
3735                 q.out.info = &info;
3736 
3737                 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
3738                 if (!NT_STATUS_IS_OK(status)) {
3739                         printf("QueryUserInfo level %u failed - %s\n",
3740                                q.in.level, nt_errstr(status));
3741                         ret = false;
3742                 } else {
3743                         uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
3744                         if ((info->info5.acct_flags) != expected_flags) {
3745                                 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
3746                                        info->info5.acct_flags,
3747                                        expected_flags);
3748                                 /* FIXME: GD */
3749                                 if (!torture_setting_bool(tctx, "samba3", false)) {
3750                                         ret = false;
3751                                 }
3752                         }
3753                         if (info->info5.rid != rid) {
3754                                 printf("QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
3755                                        info->info5.rid, rid);
3756 
3757                         }
3758                 }
3759 
3760                 break;
3761 
3762         case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
3763 
3764                 /* test last password change timestamp behaviour */
3765                 if (!test_SetPassword_pwdlastset(p, tctx, base_acct_flags,
3766                                                  base_acct_name,
3767                                                  user_handle, &password,
3768                                                  machine_credentials)) {
3769                         ret = false;
3770                 }
3771 
3772                 if (ret == true) {
3773                         torture_comment(tctx, "pwdLastSet test succeeded\n");
3774                 } else {
3775                         torture_warning(tctx, "pwdLastSet test failed\n");
3776                 }
3777 
3778                 break;
3779 
3780         case TORTURE_SAMR_USER_PRIVILEGES: {
3781 
3782                 struct dcerpc_pipe *lp;
3783                 struct policy_handle *lsa_handle;
3784 
3785                 status = torture_rpc_connection(tctx, &lp, &ndr_table_lsarpc);
3786                 torture_assert_ntstatus_ok(tctx, status, "Failed to open LSA pipe");
3787 
3788                 if (!test_lsa_OpenPolicy2(lp, tctx, &lsa_handle)) {
3789                         ret = false;
3790                 }
3791 
3792                 if (!test_DeleteUser_with_privs(p, lp, tctx,
3793                                                 domain_handle, lsa_handle, user_handle,
3794                                                 domain_sid, rid,
3795                                                 machine_credentials)) {
3796                         ret = false;
3797                 }
3798 
3799                 if (!test_lsa_Close(lp, tctx, lsa_handle)) {
3800                         ret = false;
3801                 }
3802 
3803                 if (!ret) {
3804                         torture_warning(tctx, "privileged user delete test failed\n");
3805                 }
3806 
3807                 break;
3808         }
3809         case TORTURE_SAMR_OTHER:
3810                 /* We just need the account to exist */
3811                 break;
3812         }
3813         return ret;
3814 }
3815 
3816 static bool test_alias_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
3817                            struct policy_handle *alias_handle,
3818                            const struct dom_sid *domain_sid)
3819 {
3820         bool ret = true;
3821 
3822         if (!torture_setting_bool(tctx, "samba3", false)) {
3823                 if (!test_QuerySecurity(p, tctx, alias_handle)) {
3824                         ret = false;
3825                 }
3826         }
3827 
3828         if (!test_QueryAliasInfo(p, tctx, alias_handle)) {
3829                 ret = false;
3830         }
3831 
3832         if (!test_SetAliasInfo(p, tctx, alias_handle)) {
3833                 ret = false;
3834         }
3835 
3836         if (!test_AddMemberToAlias(p, tctx, alias_handle, domain_sid)) {
3837                 ret = false;
3838         }
3839 
3840         if (torture_setting_bool(tctx, "samba4", false)) {
3841                 printf("skipping MultipleMembers Alias tests against Samba4\n");
3842                 return ret;
3843         }
3844 
3845         if (!test_AddMultipleMembersToAlias(p, tctx, alias_handle)) {
3846                 ret = false;
3847         }
3848 
3849         return ret;
3850 }
3851 
3852 
3853 static bool test_DeleteUser(struct dcerpc_pipe *p, struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
3854                                      struct policy_handle *user_handle)
3855 {
3856         struct samr_DeleteUser d;
3857         NTSTATUS status;
3858         torture_comment(tctx, "Testing DeleteUser\n");
3859 
3860         d.in.user_handle = user_handle;
3861         d.out.user_handle = user_handle;
3862 
3863         status = dcerpc_samr_DeleteUser(p, tctx, &d);
3864         torture_assert_ntstatus_ok(tctx, status, "DeleteUser");
3865 
3866         return true;
3867 }
3868 
3869 bool test_DeleteUser_byname(struct dcerpc_pipe *p,
     /* [<][>][^][v][top][bottom][index][help] */
3870                             struct torture_context *tctx,
3871                             struct policy_handle *handle, const char *name)
3872 {
3873         NTSTATUS status;
3874         struct samr_DeleteUser d;
3875         struct policy_handle user_handle;
3876         uint32_t rid;
3877 
3878         status = test_LookupName(p, tctx, handle, name, &rid);
3879         if (!NT_STATUS_IS_OK(status)) {
3880                 goto failed;
3881         }
3882 
3883         status = test_OpenUser_byname(p, tctx, handle, name, &user_handle);
3884         if (!NT_STATUS_IS_OK(status)) {
3885                 goto failed;
3886         }
3887 
3888         d.in.user_handle = &user_handle;
3889         d.out.user_handle = &user_handle;
3890         status = dcerpc_samr_DeleteUser(p, tctx, &d);
3891         if (!NT_STATUS_IS_OK(status)) {
3892                 goto failed;
3893         }
3894 
3895         return true;
3896 
3897 failed:
3898         printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
3899         return false;
3900 }
3901 
3902 
3903 static bool test_DeleteGroup_byname(struct dcerpc_pipe *p,
     /* [<][>][^][v][top][bottom][index][help] */
3904                                     struct torture_context *tctx,
3905                                     struct policy_handle *handle, const char *name)
3906 {
3907         NTSTATUS status;
3908         struct samr_OpenGroup r;
3909         struct samr_DeleteDomainGroup d;
3910         struct policy_handle group_handle;
3911         uint32_t rid;
3912 
3913         status = test_LookupName(p, tctx, handle, name, &rid);
3914         if (!NT_STATUS_IS_OK(status)) {
3915                 goto failed;
3916         }
3917 
3918         r.in.domain_handle = handle;
3919         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3920         r.in.rid = rid;
3921         r.out.group_handle = &group_handle;
3922         status = dcerpc_samr_OpenGroup(p, tctx, &r);
3923         if (!NT_STATUS_IS_OK(status)) {
3924                 goto failed;
3925         }
3926 
3927         d.in.group_handle = &group_handle;
3928         d.out.group_handle = &group_handle;
3929         status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
3930         if (!NT_STATUS_IS_OK(status)) {
3931                 goto failed;
3932         }
3933 
3934         return true;
3935 
3936 failed:
3937         printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
3938         return false;
3939 }
3940 
3941 
3942 static bool test_DeleteAlias_byname(struct dcerpc_pipe *p,
     /* [<][>][^][v][top][bottom][index][help] */
3943                                     struct torture_context *tctx,
3944                                     struct policy_handle *domain_handle,
3945                                     const char *name)
3946 {
3947         NTSTATUS status;
3948         struct samr_OpenAlias r;
3949         struct samr_DeleteDomAlias d;
3950         struct policy_handle alias_handle;
3951         uint32_t rid;
3952 
3953         printf("testing DeleteAlias_byname\n");
3954 
3955         status = test_LookupName(p, tctx, domain_handle, name, &rid);
3956         if (!NT_STATUS_IS_OK(status)) {
3957                 goto failed;
3958         }
3959 
3960         r.in.domain_handle = domain_handle;
3961         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3962         r.in.rid = rid;
3963         r.out.alias_handle = &alias_handle;
3964         status = dcerpc_samr_OpenAlias(p, tctx, &r);
3965         if (!NT_STATUS_IS_OK(status)) {
3966                 goto failed;
3967         }
3968 
3969         d.in.alias_handle = &alias_handle;
3970         d.out.alias_handle = &alias_handle;
3971         status = dcerpc_samr_DeleteDomAlias(p, tctx, &d);
3972         if (!NT_STATUS_IS_OK(status)) {
3973                 goto failed;
3974         }
3975 
3976         return true;
3977 
3978 failed:
3979         printf("DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
3980         return false;
3981 }
3982 
3983 static bool test_DeleteAlias(struct dcerpc_pipe *p,
     /* [<][>][^][v][top][bottom][index][help] */
3984                              struct torture_context *tctx,
3985                              struct policy_handle *alias_handle)
3986 {
3987         struct samr_DeleteDomAlias d;
3988         NTSTATUS status;
3989         bool ret = true;
3990         printf("Testing DeleteAlias\n");
3991 
3992         d.in.alias_handle = alias_handle;
3993         d.out.alias_handle = alias_handle;
3994 
3995         status = dcerpc_samr_DeleteDomAlias(p, tctx, &d);
3996         if (!NT_STATUS_IS_OK(status)) {
3997                 printf("DeleteAlias failed - %s\n", nt_errstr(status));
3998                 ret = false;
3999         }
4000 
4001         return ret;
4002 }
4003 
4004 static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
4005                              struct policy_handle *domain_handle,
4006                              const char *alias_name,
4007                              struct policy_handle *alias_handle,
4008                              const struct dom_sid *domain_sid,
4009                              bool test_alias)
4010 {
4011         NTSTATUS status;
4012         struct samr_CreateDomAlias r;
4013         struct lsa_String name;
4014         uint32_t rid;
4015         bool ret = true;
4016 
4017         init_lsa_String(&name, alias_name);
4018         r.in.domain_handle = domain_handle;
4019         r.in.alias_name = &name;
4020         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4021         r.out.alias_handle = alias_handle;
4022         r.out.rid = &rid;
4023 
4024         printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
4025 
4026         status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
4027 
4028         if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4029                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
4030                         printf("Server correctly refused create of '%s'\n", r.in.alias_name->string);
4031                         return true;
4032                 } else {
4033                         printf("Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
4034                                nt_errstr(status));
4035                         return false;
4036                 }
4037         }
4038 
4039         if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
4040                 if (!test_DeleteAlias_byname(p, tctx, domain_handle, r.in.alias_name->string)) {
4041                         return false;
4042                 }
4043                 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
4044         }
4045 
4046         if (!NT_STATUS_IS_OK(status)) {
4047                 printf("CreateAlias failed - %s\n", nt_errstr(status));
4048                 return false;
4049         }
4050 
4051         if (!test_alias) {
4052                 return ret;
4053         }
4054 
4055         if (!test_alias_ops(p, tctx, alias_handle, domain_sid)) {
4056                 ret = false;
4057         }
4058 
4059         return ret;
4060 }
4061 
4062 static bool test_ChangePassword(struct dcerpc_pipe *p,
     /* [<][>][^][v][top][bottom][index][help] */
4063                                 struct torture_context *tctx,
4064                                 const char *acct_name,
4065                                 struct policy_handle *domain_handle, char **password)
4066 {
4067         bool ret = true;
4068 
4069         if (!*password) {
4070                 return false;
4071         }
4072 
4073         if (!test_ChangePasswordUser(p, tctx, acct_name, domain_handle, password)) {
4074                 ret = false;
4075         }
4076 
4077         if (!test_ChangePasswordUser2(p, tctx, acct_name, password, 0, true)) {
4078                 ret = false;
4079         }
4080 
4081         if (!test_OemChangePasswordUser2(p, tctx, acct_name, domain_handle, password)) {
4082                 ret = false;
4083         }
4084 
4085         /* test what happens when setting the old password again */
4086         if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, *password, 0, true)) {
4087                 ret = false;
4088         }
4089 
4090         {
4091                 char simple_pass[9];
4092                 char *v = generate_random_str(tctx, 1);
4093 
4094                 ZERO_STRUCT(simple_pass);
4095                 memset(simple_pass, *v, sizeof(simple_pass) - 1);
4096 
4097                 /* test what happens when picking a simple password */
4098                 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, simple_pass, 0, true)) {
4099                         ret = false;
4100                 }
4101         }
4102 
4103         /* set samr_SetDomainInfo level 1 with min_length 5 */
4104         {
4105                 struct samr_QueryDomainInfo r;
4106                 union samr_DomainInfo *info = NULL;
4107                 struct samr_SetDomainInfo s;
4108                 uint16_t len_old, len;
4109                 uint32_t pwd_prop_old;
4110                 int64_t min_pwd_age_old;
4111                 NTSTATUS status;
4112 
4113                 len = 5;
4114 
4115                 r.in.domain_handle = domain_handle;
4116                 r.in.level = 1;
4117                 r.out.info = &info;
4118 
4119                 printf("testing samr_QueryDomainInfo level 1\n");
4120                 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
4121                 if (!NT_STATUS_IS_OK(status)) {
4122                         return false;
4123                 }
4124 
4125                 s.in.domain_handle = domain_handle;
4126                 s.in.level = 1;
4127                 s.in.info = info;
4128 
4129                 /* remember the old min length, so we can reset it */
4130                 len_old = s.in.info->info1.min_password_length;
4131                 s.in.info->info1.min_password_length = len;
4132                 pwd_prop_old = s.in.info->info1.password_properties;
4133                 /* turn off password complexity checks for this test */
4134                 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
4135 
4136                 min_pwd_age_old = s.in.info->info1.min_password_age;
4137                 s.in.info->info1.min_password_age = 0;
4138 
4139                 printf("testing samr_SetDomainInfo level 1\n");
4140                 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
4141                 if (!NT_STATUS_IS_OK(status)) {
4142                         return false;
4143                 }
4144 
4145                 printf("calling test_ChangePasswordUser3 with too short password\n");
4146 
4147                 if (!test_ChangePasswordUser3(p, tctx, acct_name, len - 1, password, NULL, 0, true)) {
4148                         ret = false;
4149                 }
4150 
4151                 s.in.info->info1.min_password_length = len_old;
4152                 s.in.info->info1.password_properties = pwd_prop_old;
4153                 s.in.info->info1.min_password_age = min_pwd_age_old;
4154 
4155                 printf("testing samr_SetDomainInfo level 1\n");
4156                 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
4157                 if (!NT_STATUS_IS_OK(status)) {
4158                         return false;
4159                 }
4160 
4161         }
4162 
4163         {
4164                 NTSTATUS status;
4165                 struct samr_OpenUser r;
4166                 struct samr_QueryUserInfo q;
4167                 union samr_UserInfo *info;
4168                 struct samr_LookupNames n;
4169                 struct policy_handle user_handle;
4170                 struct samr_Ids rids, types;
4171 
4172                 n.in.domain_handle = domain_handle;
4173                 n.in.num_names = 1;
4174                 n.in.names = talloc_array(tctx, struct lsa_String, 1);
4175                 n.in.names[0].string = acct_name;
4176                 n.out.rids = &rids;
4177                 n.out.types = &types;
4178 
4179                 status = dcerpc_samr_LookupNames(p, tctx, &n);
4180                 if (!NT_STATUS_IS_OK(status)) {
4181                         printf("LookupNames failed - %s\n", nt_errstr(status));
4182                         return false;
4183                 }
4184 
4185                 r.in.domain_handle = domain_handle;
4186                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4187                 r.in.rid = n.out.rids->ids[0];
4188                 r.out.user_handle = &user_handle;
4189 
4190                 status = dcerpc_samr_OpenUser(p, tctx, &r);
4191                 if (!NT_STATUS_IS_OK(status)) {
4192                         printf("OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(status));
4193                         return false;
4194                 }
4195 
4196                 q.in.user_handle = &user_handle;
4197                 q.in.level = 5;
4198                 q.out.info = &info;
4199 
4200                 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
4201                 if (!NT_STATUS_IS_OK(status)) {
4202                         printf("QueryUserInfo failed - %s\n", nt_errstr(status));
4203                         return false;
4204                 }
4205 
4206                 printf("calling test_ChangePasswordUser3 with too early password change\n");
4207 
4208                 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL,
4209                                               info->info5.last_password_change, true)) {
4210                         ret = false;
4211                 }
4212         }
4213 
4214         /* we change passwords twice - this has the effect of verifying
4215            they were changed correctly for the final call */
4216         if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
4217                 ret = false;
4218         }
4219 
4220         if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
4221                 ret = false;
4222         }
4223 
4224         return ret;
4225 }
4226 
4227 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
4228                             struct policy_handle *domain_handle,
4229                             const char *user_name,
4230                             struct policy_handle *user_handle_out,
4231                             struct dom_sid *domain_sid,
4232                             enum torture_samr_choice which_ops,
4233                             struct cli_credentials *machine_credentials,
4234                             bool test_user)
4235 {
4236 
4237         TALLOC_CTX *user_ctx;
4238 
4239         NTSTATUS status;
4240         struct samr_CreateUser r;
4241         struct samr_QueryUserInfo q;
4242         union samr_UserInfo *info;
4243         struct samr_DeleteUser d;
4244         uint32_t rid;
4245 
4246         /* This call creates a 'normal' account - check that it really does */
4247         const uint32_t acct_flags = ACB_NORMAL;
4248         struct lsa_String name;
4249         bool ret = true;
4250 
4251         struct policy_handle user_handle;
4252         user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
4253         init_lsa_String(&name, user_name);
4254 
4255         r.in.domain_handle = domain_handle;
4256         r.in.account_name = &name;
4257         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4258         r.out.user_handle = &user_handle;
4259         r.out.rid = &rid;
4260 
4261         printf("Testing CreateUser(%s)\n", r.in.account_name->string);
4262 
4263         status = dcerpc_samr_CreateUser(p, user_ctx, &r);
4264 
4265         if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4266                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
4267                         printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
4268                         return true;
4269                 } else {
4270                         printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
4271                                nt_errstr(status));
4272                         return false;
4273                 }
4274         }
4275 
4276         if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4277                 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
4278                         talloc_free(user_ctx);
4279                         return false;
4280                 }
4281                 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
4282         }
4283 
4284         if (!NT_STATUS_IS_OK(status)) {
4285                 talloc_free(user_ctx);
4286                 printf("CreateUser failed - %s\n", nt_errstr(status));
4287                 return false;
4288         }
4289 
4290         if (!test_user) {
4291                 if (user_handle_out) {
4292                         *user_handle_out = user_handle;
4293                 }
4294                 return ret;
4295         }
4296 
4297         {
4298                 q.in.user_handle = &user_handle;
4299                 q.in.level = 16;
4300                 q.out.info = &info;
4301 
4302                 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
4303                 if (!NT_STATUS_IS_OK(status)) {
4304                         printf("QueryUserInfo level %u failed - %s\n",
4305                                q.in.level, nt_errstr(status));
4306                         ret = false;
4307                 } else {
4308                         if ((info->info16.acct_flags & acct_flags) != acct_flags) {
4309                                 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
4310                                        info->info16.acct_flags,
4311                                        acct_flags);
4312                                 ret = false;
4313                         }
4314                 }
4315 
4316                 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
4317                                    domain_sid, acct_flags, name.string, which_ops,
4318                                    machine_credentials)) {
4319                         ret = false;
4320                 }
4321 
4322                 if (user_handle_out) {
4323                         *user_handle_out = user_handle;
4324                 } else {
4325                         printf("Testing DeleteUser (createuser test)\n");
4326 
4327                         d.in.user_handle = &user_handle;
4328                         d.out.user_handle = &user_handle;
4329 
4330                         status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
4331                         if (!NT_STATUS_IS_OK(status)) {
4332                                 printf("DeleteUser failed - %s\n", nt_errstr(status));
4333                                 ret = false;
4334                         }
4335                 }
4336 
4337         }
4338 
4339         talloc_free(user_ctx);
4340 
4341         return ret;
4342 }
4343 
4344 
4345 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
4346                              struct policy_handle *domain_handle,
4347                              struct dom_sid *domain_sid,
4348                              enum torture_samr_choice which_ops,
4349                              struct cli_credentials *machine_credentials)
4350 {
4351         NTSTATUS status;
4352         struct samr_CreateUser2 r;
4353         struct samr_QueryUserInfo q;
4354         union samr_UserInfo *info;
4355         struct samr_DeleteUser d;
4356         struct policy_handle user_handle;
4357         uint32_t rid;
4358         struct lsa_String name;
4359         bool ret = true;
4360         int i;
4361 
4362         struct {
4363                 uint32_t acct_flags;
4364                 const char *account_name;
4365                 NTSTATUS nt_status;
4366         } account_types[] = {
4367                 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
4368                 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4369                 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4370                 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
4371                 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4372                 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4373                 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
4374                 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4375                 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4376                 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
4377                 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
4378                 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
4379                 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4380                 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4381                 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
4382         };
4383 
4384         for (i = 0; account_types[i].account_name; i++) {
4385                 TALLOC_CTX *user_ctx;
4386                 uint32_t acct_flags = account_types[i].acct_flags;
4387                 uint32_t access_granted;
4388                 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
4389                 init_lsa_String(&name, account_types[i].account_name);
4390 
4391                 r.in.domain_handle = domain_handle;
4392                 r.in.account_name = &name;
4393                 r.in.acct_flags = acct_flags;
4394                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4395                 r.out.user_handle = &user_handle;
4396                 r.out.access_granted = &access_granted;
4397                 r.out.rid = &rid;
4398 
4399                 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
4400 
4401                 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
4402 
4403                 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4404                         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
4405                                 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
4406                                 continue;
4407                         } else {
4408                                 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
4409                                        nt_errstr(status));
4410                                 ret = false;
4411                                 continue;
4412                         }
4413                 }
4414 
4415                 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4416                         if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
4417                                 talloc_free(user_ctx);
4418                                 ret = false;
4419                                 continue;
4420                         }
4421                         status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
4422 
4423                 }
4424                 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
4425                         printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
4426                                nt_errstr(status), nt_errstr(account_types[i].nt_status));
4427                         ret = false;
4428                 }
4429 
4430                 if (NT_STATUS_IS_OK(status)) {
4431                         q.in.user_handle = &user_handle;
4432                         q.in.level = 5;
4433                         q.out.info = &info;
4434 
4435                         status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
4436                         if (!NT_STATUS_IS_OK(status)) {
4437                                 printf("QueryUserInfo level %u failed - %s\n",
4438                                        q.in.level, nt_errstr(status));
4439                                 ret = false;
4440                         } else {
4441                                 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
4442                                 if (acct_flags == ACB_NORMAL) {
4443                                         expected_flags |= ACB_PW_EXPIRED;
4444                                 }
4445                                 if ((info->info5.acct_flags) != expected_flags) {
4446                                         printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
4447                                                info->info5.acct_flags,
4448                                                expected_flags);
4449                                         ret = false;
4450                                 }
4451                                 switch (acct_flags) {
4452                                 case ACB_SVRTRUST:
4453                                         if (info->info5.primary_gid != DOMAIN_RID_DCS) {
4454                                                 printf("QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
4455                                                        DOMAIN_RID_DCS, info->info5.primary_gid);
4456                                                 ret = false;
4457                                         }
4458                                         break;
4459                                 case ACB_WSTRUST:
4460                                         if (info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
4461                                                 printf("QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
4462                                                        DOMAIN_RID_DOMAIN_MEMBERS, info->info5.primary_gid);
4463                                                 ret = false;
4464                                         }
4465                                         break;
4466                                 case ACB_NORMAL:
4467                                         if (info->info5.primary_gid != DOMAIN_RID_USERS) {
4468                                                 printf("QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
4469                                                        DOMAIN_RID_USERS, info->info5.primary_gid);
4470                                                 ret = false;
4471                                         }
4472                                         break;
4473                                 }
4474                         }
4475 
4476                         if (!test_user_ops(p, tctx, &user_handle, domain_handle,
4477                                            domain_sid, acct_flags, name.string, which_ops,
4478                                            machine_credentials)) {
4479                                 ret = false;
4480                         }
4481 
4482                         if (!policy_handle_empty(&user_handle)) {
4483                                 printf("Testing DeleteUser (createuser2 test)\n");
4484 
4485                                 d.in.user_handle = &user_handle;
4486                                 d.out.user_handle = &user_handle;
4487 
4488                                 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
4489                                 if (!NT_STATUS_IS_OK(status)) {
4490                                         printf("DeleteUser failed - %s\n", nt_errstr(status));
4491                                         ret = false;
4492                                 }
4493                         }
4494                 }
4495                 talloc_free(user_ctx);
4496         }
4497 
4498         return ret;
4499 }
4500 
4501 static bool test_QueryAliasInfo(struct dcerpc_pipe *p,
     /* [<][>][^][v][top][bottom][index][help] */
4502                                 struct torture_context *tctx,
4503                                 struct policy_handle *handle)
4504 {
4505         NTSTATUS status;
4506         struct samr_QueryAliasInfo r;
4507         union samr_AliasInfo *info;
4508         uint16_t levels[] = {1, 2, 3};
4509         int i;
4510         bool ret = true;
4511 
4512         for (i=0;i<ARRAY_SIZE(levels);i++) {
4513                 printf("Testing QueryAliasInfo level %u\n", levels[i]);
4514 
4515                 r.in.alias_handle = handle;
4516                 r.in.level = levels[i];
4517                 r.out.info = &info;
4518 
4519                 status = dcerpc_samr_QueryAliasInfo(p, tctx, &r);
4520                 if (!NT_STATUS_IS_OK(status)) {
4521                         printf("QueryAliasInfo level %u failed - %s\n",
4522                                levels[i], nt_errstr(status));
4523                         ret = false;
4524                 }
4525         }
4526 
4527         return ret;
4528 }
4529 
4530 static bool test_QueryGroupInfo(struct dcerpc_pipe *p,
     /* [<][>][^][v][top][bottom][index][help] */
4531                                 struct torture_context *tctx,
4532                                 struct policy_handle *handle)
4533 {
4534         NTSTATUS status;
4535         struct samr_QueryGroupInfo r;
4536         union samr_GroupInfo *info;
4537         uint16_t levels[] = {1, 2, 3, 4, 5};
4538         int i;
4539         bool ret = true;
4540 
4541         for (i=0;i<ARRAY_SIZE(levels);i++) {
4542                 printf("Testing QueryGroupInfo level %u\n", levels[i]);
4543 
4544                 r.in.group_handle = handle;
4545                 r.in.level = levels[i];
4546                 r.out.info = &info;
4547 
4548                 status = dcerpc_samr_QueryGroupInfo(p, tctx, &r);
4549                 if (!NT_STATUS_IS_OK(status)) {
4550                         printf("QueryGroupInfo level %u failed - %s\n",
4551                                levels[i], nt_errstr(status));
4552                         ret = false;
4553                 }
4554         }
4555 
4556         return ret;
4557 }
4558 
4559 static bool test_QueryGroupMember(struct dcerpc_pipe *p,
     /* [<][>][^][v][top][bottom][index][help] */
4560                                   struct torture_context *tctx,
4561                                   struct policy_handle *handle)
4562 {
4563         NTSTATUS status;
4564         struct samr_QueryGroupMember r;
4565         struct samr_RidTypeArray *rids = NULL;
4566         bool ret = true;
4567 
4568         printf("Testing QueryGroupMember\n");
4569 
4570         r.in.group_handle = handle;
4571         r.out.rids = &rids;
4572 
4573         status = dcerpc_samr_QueryGroupMember(p, tctx, &r);
4574         if (!NT_STATUS_IS_OK(status)) {
4575                 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
4576                 ret = false;
4577         }
4578 
4579         return ret;
4580 }
4581 
4582 
4583 static bool test_SetGroupInfo(struct dcerpc_pipe *p,
     /* [<][>][^][v][top][bottom][index][help] */
4584                               struct torture_context *tctx,
4585                               struct policy_handle *handle)
4586 {
4587         NTSTATUS status;
4588         struct samr_QueryGroupInfo r;
4589         union samr_GroupInfo *info;
4590         struct samr_SetGroupInfo s;
4591         uint16_t levels[] = {1, 2, 3, 4};
4592         uint16_t set_ok[] = {0, 1, 1, 1};
4593         int i;
4594         bool ret = true;
4595 
4596         for (i=0;i<ARRAY_SIZE(levels);i++) {
4597                 printf("Testing QueryGroupInfo level %u\n", levels[i]);
4598 
4599                 r.in.group_handle = handle;
4600                 r.in.level = levels[i];
4601                 r.out.info = &info;
4602 
4603                 status = dcerpc_samr_QueryGroupInfo(p, tctx, &r);
4604                 if (!NT_STATUS_IS_OK(status)) {
4605                         printf("QueryGroupInfo level %u failed - %s\n",
4606                                levels[i], nt_errstr(status));
4607                         ret = false;
4608                 }
4609 
4610                 printf("Testing SetGroupInfo level %u\n", levels[i]);
4611 
4612                 s.in.group_handle = handle;
4613                 s.in.level = levels[i];
4614                 s.in.info = *r.out.info;
4615 
4616 #if 0
4617                 /* disabled this, as it changes the name only from the point of view of samr,
4618                    but leaves the name from the point of view of w2k3 internals (and ldap). This means
4619                    the name is still reserved, so creating the old name fails, but deleting by the old name
4620                    also fails */
4621                 if (s.in.level == 2) {
4622                         init_lsa_String(&s.in.info->string, "NewName");
4623                 }
4624 #endif
4625 
4626                 if (s.in.level == 4) {
4627                         init_lsa_String(&s.in.info->description, "test description");
4628                 }
4629 
4630                 status = dcerpc_samr_SetGroupInfo(p, tctx, &s);
4631                 if (set_ok[i]) {
4632                         if (!NT_STATUS_IS_OK(status)) {
4633                                 printf("SetGroupInfo level %u failed - %s\n",
4634                                        r.in.level, nt_errstr(status));
4635                                 ret = false;
4636                                 continue;
4637                         }
4638                 } else {
4639                         if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
4640                                 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
4641                                        r.in.level, nt_errstr(status));
4642                                 ret = false;
4643                                 continue;
4644                         }
4645                 }
4646         }
4647 
4648         return ret;
4649 }
4650 
4651 static bool test_QueryUserInfo(struct dcerpc_pipe *p,
     /* [<][>][^][v][top][bottom][index][help] */
4652                                struct torture_context *tctx,
4653                                struct policy_handle *handle)
4654 {
4655         NTSTATUS status;
4656         struct samr_QueryUserInfo r;
4657         union samr_UserInfo *info;
4658         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
4659                            11, 12, 13, 14, 16, 17, 20, 21};
4660         int i;
4661         bool ret = true;
4662 
4663         for (i=0;i<ARRAY_SIZE(levels);i++) {
4664                 printf("Testing QueryUserInfo level %u\n", levels[i]);
4665 
4666                 r.in.user_handle = handle;
4667                 r.in.level = levels[i];
4668                 r.out.info = &info;
4669 
4670                 status = dcerpc_samr_QueryUserInfo(p, tctx, &r);
4671                 if (!NT_STATUS_IS_OK(status)) {
4672                         printf("QueryUserInfo level %u failed - %s\n",
4673                                levels[i], nt_errstr(status));
4674                         ret = false;
4675                 }
4676         }
4677 
4678         return ret;
4679 }
4680 
4681 static bool test_QueryUserInfo2(struct dcerpc_pipe *p,
     /* [<][>][^][v][top][bottom][index][help] */
4682                                 struct torture_context *tctx,
4683                                 struct policy_handle *handle)
4684 {
4685         NTSTATUS status;
4686         struct samr_QueryUserInfo2 r;
4687         union samr_UserInfo *info;
4688         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
4689                            11, 12, 13, 14, 16, 17, 20, 21};
4690         int i;
4691         bool ret = true;
4692 
4693         for (i=0;i<ARRAY_SIZE(levels);i++) {
4694                 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
4695 
4696                 r.in.user_handle = handle;
4697                 r.in.level = levels[i];
4698                 r.out.info = &info;
4699 
4700                 status = dcerpc_samr_QueryUserInfo2(p, tctx, &r);
4701                 if (!NT_STATUS_IS_OK(status)) {
4702                         printf("QueryUserInfo2 level %u failed - %s\n",
4703                                levels[i], nt_errstr(status));
4704                         ret = false;
4705                 }
4706         }
4707 
4708         return ret;
4709 }
4710 
4711 static bool test_OpenUser(struct dcerpc_pipe *p,
     /* [<][>][^][v][top][bottom][index][help] */
4712                           struct torture_context *tctx,
4713                           struct policy_handle *handle, uint32_t rid)
4714 {
4715         NTSTATUS status;
4716         struct samr_OpenUser r;
4717         struct policy_handle user_handle;
4718         bool ret = true;
4719 
4720         printf("Testing OpenUser(%u)\n", rid);
4721 
4722         r.in.domain_handle = handle;
4723         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4724         r.in.rid = rid;
4725         r.out.user_handle = &user_handle;
4726 
4727         status = dcerpc_samr_OpenUser(p, tctx, &r);
4728         if (!NT_STATUS_IS_OK(status)) {
4729                 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
4730                 return false;
4731         }
4732 
4733         if (!test_QuerySecurity(p, tctx, &user_handle)) {
4734                 ret = false;
4735         }
4736 
4737         if (!test_QueryUserInfo(p, tctx, &user_handle)) {
4738                 ret = false;
4739         }
4740 
4741         if (!test_QueryUserInfo2(p, tctx, &user_handle)) {
4742                 ret = false;
4743         }
4744 
4745         if (!test_GetUserPwInfo(p, tctx, &user_handle)) {
4746                 ret = false;
4747         }
4748 
4749         if (!test_GetGroupsForUser(p,tctx, &user_handle)) {
4750                 ret = false;
4751         }
4752 
4753         if (!test_samr_handle_Close(p, tctx, &user_handle)) {
4754                 ret = false;
4755         }
4756 
4757         return ret;
4758 }
4759 
4760 static bool test_OpenGroup(struct dcerpc_pipe *p,
     /* [<][>][^][v][top][bottom][index][help] */
4761                            struct torture_context *tctx,
4762                            struct policy_handle *handle, uint32_t rid)
4763 {
4764         NTSTATUS status;
4765         struct samr_OpenGroup r;
4766         struct policy_handle group_handle;
4767         bool ret = true;
4768 
4769         printf("Testing OpenGroup(%u)\n", rid);
4770 
4771         r.in.domain_handle = handle;
4772         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4773         r.in.rid = rid;
4774         r.out.group_handle = &group_handle;
4775 
4776         status = dcerpc_samr_OpenGroup(p, tctx, &r);
4777         if (!NT_STATUS_IS_OK(status)) {
4778                 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
4779                 return false;
4780         }
4781 
4782         if (!torture_setting_bool(tctx, "samba3", false)) {
4783                 if (!test_QuerySecurity(p, tctx, &group_handle)) {
4784                         ret = false;
4785                 }
4786         }
4787 
4788         if (!test_QueryGroupInfo(p, tctx, &group_handle)) {
4789                 ret = false;
4790         }
4791 
4792         if (!test_QueryGroupMember(p, tctx, &group_handle)) {
4793                 ret = false;
4794         }
4795 
4796         if (!test_samr_handle_Close(p, tctx, &group_handle)) {
4797                 ret = false;
4798         }
4799 
4800         return ret;
4801 }
4802 
4803 static bool test_OpenAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
4804                            struct policy_handle *handle, uint32_t rid)
4805 {
4806         NTSTATUS status;
4807         struct samr_OpenAlias r;
4808         struct policy_handle alias_handle;
4809         bool ret = true;
4810 
4811         torture_comment(tctx, "Testing OpenAlias(%u)\n", rid);
4812 
4813         r.in.domain_handle = handle;
4814         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4815         r.in.rid = rid;
4816         r.out.alias_handle = &alias_handle;
4817 
4818         status = dcerpc_samr_OpenAlias(p, tctx, &r);
4819         if (!NT_STATUS_IS_OK(status)) {
4820                 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
4821                 return false;
4822         }
4823 
4824         if (!torture_setting_bool(tctx, "samba3", false)) {
4825                 if (!test_QuerySecurity(p, tctx, &alias_handle)) {
4826                         ret = false;
4827                 }
4828         }
4829 
4830         if (!test_QueryAliasInfo(p, tctx, &alias_handle)) {
4831                 ret = false;
4832         }
4833 
4834         if (!test_GetMembersInAlias(p, tctx, &alias_handle)) {
4835                 ret = false;
4836         }
4837 
4838         if (!test_samr_handle_Close(p, tctx, &alias_handle)) {
4839                 ret = false;
4840         }
4841 
4842         return ret;
4843 }
4844 
4845 static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
4846                        struct policy_handle *handle, uint32_t rid,
4847                        uint32_t acct_flag_mask)
4848 {
4849         NTSTATUS status;
4850         struct samr_OpenUser r;
4851         struct samr_QueryUserInfo q;
4852         union samr_UserInfo *info;
4853         struct policy_handle user_handle;
4854         bool ret = true;
4855 
4856         torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
4857 
4858         r.in.domain_handle = handle;
4859         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4860         r.in.rid = rid;
4861         r.out.user_handle = &user_handle;
4862 
4863         status = dcerpc_samr_OpenUser(p, tctx, &r);
4864         if (!NT_STATUS_IS_OK(status)) {
4865                 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
4866                 return false;
4867         }
4868 
4869         q.in.user_handle = &user_handle;
4870         q.in.level = 16;
4871         q.out.info = &info;
4872 
4873         status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
4874         if (!NT_STATUS_IS_OK(status)) {
4875                 printf("QueryUserInfo level 16 failed - %s\n",
4876                        nt_errstr(status));
4877                 ret = false;
4878         } else {
4879                 if ((acct_flag_mask & info->info16.acct_flags) == 0) {
4880                         printf("Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
4881                                acct_flag_mask, info->info16.acct_flags, rid);
4882                         ret = false;
4883                 }
4884         }
4885 
4886         if (!test_samr_handle_Close(p, tctx, &user_handle)) {
4887                 ret = false;
4888         }
4889 
4890         return ret;
4891 }
4892 
4893 static bool test_EnumDomainUsers_all(struct dcerpc_pipe *p,
     /* [<][>][^][v][top][bottom][index][help] */
4894                                      struct torture_context *tctx,
4895                                      struct policy_handle *handle)
4896 {
4897         NTSTATUS status = STATUS_MORE_ENTRIES;
4898         struct samr_EnumDomainUsers r;
4899         uint32_t mask, resume_handle=0;
4900         int i, mask_idx;
4901         bool ret = true;
4902         struct samr_LookupNames n;
4903         struct samr_LookupRids  lr ;
4904         struct lsa_Strings names;
4905         struct samr_Ids rids, types;
4906         struct samr_SamArray *sam = NULL;
4907         uint32_t num_entries = 0;
4908 
4909         uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
4910                             ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
4911                             ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
4912                             ACB_PWNOEXP, 0};
4913 
4914         printf("Testing EnumDomainUsers\n");
4915 
4916         for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
4917                 r.in.domain_handle = handle;
4918                 r.in.resume_handle = &resume_handle;
4919                 r.in.acct_flags = mask = masks[mask_idx];
4920                 r.in.max_size = (uint32_t)-1;
4921                 r.out.resume_handle = &resume_handle;
4922                 r.out.num_entries = &num_entries;
4923                 r.out.sam = &sam;
4924 
4925                 status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
4926                 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
4927                     !NT_STATUS_IS_OK(status)) {
4928                         printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
4929                         return false;
4930                 }
4931 
4932                 torture_assert(tctx, sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
4933 
4934                 if (sam->count == 0) {
4935                         continue;
4936                 }
4937 
4938                 for (i=0;i<sam->count;i++) {
4939                         if (mask) {
4940                                 if (!check_mask(p, tctx, handle, sam->entries[i].idx, mask)) {
4941                                         ret = false;
4942                                 }
4943                         } else if (!test_OpenUser(p, tctx, handle, sam->entries[i].idx)) {
4944                                 ret = false;
4945                         }
4946                 }
4947         }
4948 
4949         printf("Testing LookupNames\n");
4950         n.in.domain_handle = handle;
4951         n.in.num_names = sam->count;
4952         n.in.names = talloc_array(tctx, struct lsa_String, sam->count);
4953         n.out.rids = &rids;
4954         n.out.types = &types;
4955         for (i=0;i<sam->count;i++) {
4956                 n.in.names[i].string = sam->entries[i].name.string;
4957         }
4958         status = dcerpc_samr_LookupNames(p, tctx, &n);
4959         if (!NT_STATUS_IS_OK(status)) {
4960                 printf("LookupNames failed - %s\n", nt_errstr(status));
4961                 ret = false;
4962         }
4963 
4964 
4965         printf("Testing LookupRids\n");
4966         lr.in.domain_handle = handle;
4967         lr.in.num_rids = sam->count;
4968         lr.in.rids = talloc_array(tctx, uint32_t, sam->count);
4969         lr.out.names = &names;
4970         lr.out.types = &types;
4971         for (i=0;i<sam->count;i++) {
4972                 lr.in.rids[i] = sam->entries[i].idx;
4973         }
4974         status = dcerpc_samr_LookupRids(p, tctx, &lr);
4975         torture_assert_ntstatus_ok(tctx, status, "LookupRids");
4976 
4977         return ret;
4978 }
4979 
4980 /*
4981   try blasting the server with a bunch of sync requests
4982 */
4983 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
4984                                        struct policy_handle *handle)
4985 {
4986         NTSTATUS status;
4987         struct samr_EnumDomainUsers r;
4988         uint32_t resume_handle=0;
4989         int i;
4990 #define ASYNC_COUNT 100
4991         struct rpc_request *req[ASYNC_COUNT];
4992 
4993         if (!torture_setting_bool(tctx, "dangerous", false)) {
4994                 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
4995         }
4996 
4997         torture_comment(tctx, "Testing EnumDomainUsers_async\n");
4998 
4999         r.in.domain_handle = handle;
5000         r.in.resume_handle = &resume_handle;
5001         r.in.acct_flags = 0;
5002         r.in.max_size = (uint32_t)-1;
5003         r.out.resume_handle = &resume_handle;
5004 
5005         for (i=0;i<ASYNC_COUNT;i++) {
5006                 req[i] = dcerpc_samr_EnumDomainUsers_send(p, tctx, &r);
5007         }
5008 
5009         for (i=0;i<ASYNC_COUNT;i++) {
5010                 status = dcerpc_ndr_request_recv(req[i]);
5011                 if (!NT_STATUS_IS_OK(status)) {
5012                         printf("EnumDomainUsers[%d] failed - %s\n",
5013                                i, nt_errstr(status));
5014                         return false;
5015                 }
5016         }
5017 
5018         torture_comment(tctx, "%d async requests OK\n", i);
5019 
5020         return true;
5021 }
5022 
5023 static bool test_EnumDomainGroups_all(struct dcerpc_pipe *p,
     /* [<][>][^][v][top][bottom][index][help] */
5024                                       struct torture_context *tctx,
5025                                       struct policy_handle *handle)
5026 {
5027         NTSTATUS status;
5028         struct samr_EnumDomainGroups r;
5029         uint32_t resume_handle=0;
5030         struct samr_SamArray *sam = NULL;
5031         uint32_t num_entries = 0;
5032         int i;
5033         bool ret = true;
5034 
5035         printf("Testing EnumDomainGroups\n");
5036 
5037         r.in.domain_handle = handle;
5038         r.in.resume_handle = &resume_handle;
5039         r.in.max_size = (uint32_t)-1;
5040         r.out.resume_handle = &resume_handle;
5041         r.out.num_entries = &num_entries;
5042         r.out.sam = &sam;
5043 
5044         status = dcerpc_samr_EnumDomainGroups(p, tctx, &r);
5045         if (!NT_STATUS_IS_OK(status)) {
5046                 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
5047                 return false;
5048         }
5049 
5050         if (!sam) {
5051                 return false;
5052         }
5053 
5054         for (i=0;i<sam->count;i++) {
5055                 if (!test_OpenGroup(p, tctx, handle, sam->entries[i].idx)) {
5056                         ret = false;
5057                 }
5058         }
5059 
5060         return ret;
5061 }
5062 
5063 static bool test_EnumDomainAliases_all(struct dcerpc_pipe *p,
     /* [<][>][^][v][top][bottom][index][help] */
5064                                        struct torture_context *tctx,
5065                                        struct policy_handle *handle)
5066 {
5067         NTSTATUS status;
5068         struct samr_EnumDomainAliases r;
5069         uint32_t resume_handle=0;
5070         struct samr_SamArray *sam = NULL;
5071         uint32_t num_entries = 0;
5072         int i;
5073         bool ret = true;
5074 
5075         printf("Testing EnumDomainAliases\n");
5076 
5077         r.in.domain_handle = handle;
5078         r.in.resume_handle = &resume_handle;
5079         r.in.max_size = (uint32_t)-1;
5080         r.out.sam = &sam;
5081         r.out.num_entries = &num_entries;
5082         r.out.resume_handle = &resume_handle;
5083 
5084         status = dcerpc_samr_EnumDomainAliases(p, tctx, &r);
5085         if (!NT_STATUS_IS_OK(status)) {
5086                 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
5087                 return false;
5088         }
5089 
5090         if (!sam) {
5091                 return false;
5092         }
5093 
5094         for (i=0;i<sam->count;i++) {
5095                 if (!test_OpenAlias(p, tctx, handle, sam->entries[i].idx)) {
5096                         ret = false;
5097                 }
5098         }
5099 
5100         return ret;
5101 }
5102 
5103 static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p,
     /* [<][>][^][v][top][bottom][index][help] */
5104                                             struct torture_context *tctx,
5105                                             struct policy_handle *handle)
5106 {
5107         NTSTATUS status;
5108         struct samr_GetDisplayEnumerationIndex r;
5109         bool ret = true;
5110         uint16_t levels[] = {1, 2, 3, 4, 5};
5111         uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
5112         struct lsa_String name;
5113         uint32_t idx = 0;
5114         int i;
5115 
5116         for (i=0;i<ARRAY_SIZE(levels);i++) {
5117                 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
5118 
5119                 init_lsa_String(&name, TEST_ACCOUNT_NAME);
5120 
5121                 r.in.domain_handle = handle;
5122                 r.in.level = levels[i];
5123                 r.in.name = &name;
5124                 r.out.idx = &idx;
5125 
5126                 status = dcerpc_samr_GetDisplayEnumerationIndex(p, tctx, &r);
5127 
5128                 if (ok_lvl[i] &&
5129                     !NT_STATUS_IS_OK(status) &&
5130                     !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
5131                         printf("GetDisplayEnumerationIndex level %u failed - %s\n",
5132                                levels[i], nt_errstr(status));
5133                         ret = false;
5134                 }
5135 
5136                 init_lsa_String(&name, "zzzzzzzz");
5137 
5138                 status = dcerpc_samr_GetDisplayEnumerationIndex(p, tctx, &r);
5139 
5140                 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
5141                         printf("GetDisplayEnumerationIndex level %u failed - %s\n",
5142                                levels[i], nt_errstr(status));
5143                         ret = false;
5144                 }
5145         }
5146 
5147         return ret;
5148 }
5149 
5150 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p,
     /* [<][>][^][v][top][bottom][index][help] */
5151                                              struct torture_context *tctx,
5152                                              struct policy_handle *handle)
5153 {
5154         NTSTATUS status;
5155         struct samr_GetDisplayEnumerationIndex2 r;
5156         bool ret = true;
5157         uint16_t levels[] = {1, 2, 3, 4, 5};
5158         uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
5159         struct lsa_String name;
5160         uint32_t idx = 0;
5161         int i;
5162 
5163         for (i=0;i<ARRAY_SIZE(levels);i++) {
5164                 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
5165 
5166                 init_lsa_String(&name, TEST_ACCOUNT_NAME);
5167 
5168                 r.in.domain_handle = handle;
5169                 r.in.level = levels[i];
5170                 r.in.name = &name;
5171                 r.out.idx = &idx;
5172 
5173                 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, tctx, &r);
5174                 if (ok_lvl[i] &&
5175                     !NT_STATUS_IS_OK(status) &&
5176                     !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
5177                         printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
5178                                levels[i], nt_errstr(status));
5179                         ret = false;
5180                 }
5181 
5182                 init_lsa_String(&name, "zzzzzzzz");
5183 
5184                 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, tctx, &r);
5185                 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
5186                         printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
5187                                levels[i], nt_errstr(status));
5188                         ret = false;
5189                 }
5190         }
5191 
5192         return ret;
5193 }
5194 
5195 #define STRING_EQUAL_QUERY(s1, s2, user)                                        \
5196         if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
5197                 /* odd, but valid */                                            \
5198         } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
5199                         printf("%s mismatch for %s: %s != %s (%s)\n", \
5200                                #s1, user.string,  s1.string, s2.string, __location__);   \
5201                         ret = false; \
5202         }
5203 #define INT_EQUAL_QUERY(s1, s2, user)           \
5204                 if (s1 != s2) { \
5205                         printf("%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
5206                                #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
5207                         ret = false; \
5208                 }
5209 
5210 static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p,
     /* [<][>][^][v][top][bottom][index][help] */
5211                                        struct torture_context *tctx,
5212                                        struct samr_QueryDisplayInfo *querydisplayinfo,
5213                                        bool *seen_testuser)
5214 {
5215         struct samr_OpenUser r;
5216         struct samr_QueryUserInfo q;
5217         union samr_UserInfo *info;
5218         struct policy_handle user_handle;
5219         int i, ret = true;
5220         NTSTATUS status;
5221         r.in.domain_handle = querydisplayinfo->in.domain_handle;
5222         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5223         for (i = 0; ; i++) {
5224                 switch (querydisplayinfo->in.level) {
5225                 case 1:
5226                         if (i >= querydisplayinfo->out.info->info1.count) {
5227                                 return ret;
5228                         }
5229                         r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid;
5230                         break;
5231                 case 2:
5232                         if (i >= querydisplayinfo->out.info->info2.count) {
5233                                 return ret;
5234                         }
5235                         r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid;
5236                         break;
5237                 case 3:
5238                         /* Groups */
5239                 case 4:
5240                 case 5:
5241                         /* Not interested in validating just the account name */
5242                         return true;
5243                 }
5244 
5245                 r.out.user_handle = &user_handle;
5246 
5247                 switch (querydisplayinfo->in.level) {
5248                 case 1:
5249                 case 2:
5250                         status = dcerpc_samr_OpenUser(p, tctx, &r);
5251                         if (!NT_STATUS_IS_OK(status)) {
5252                                 printf("OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(status));
5253                                 return false;
5254                         }
5255                 }
5256 
5257                 q.in.user_handle = &user_handle;
5258                 q.in.level = 21;
5259                 q.out.info = &info;
5260                 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
5261                 if (!NT_STATUS_IS_OK(status)) {
5262                         printf("QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
5263                         return false;
5264                 }
5265 
5266                 switch (querydisplayinfo->in.level) {
5267                 case 1:
5268                         if (seen_testuser && strcmp(info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
5269                                 *seen_testuser = true;
5270                         }
5271                         STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name,
5272                                            info->info21.full_name, info->info21.account_name);
5273                         STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name,
5274                                            info->info21.account_name, info->info21.account_name);
5275                         STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description,
5276                                            info->info21.description, info->info21.account_name);
5277                         INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid,
5278                                         info->info21.rid, info->info21.account_name);
5279                         INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags,
5280                                         info->info21.acct_flags, info->info21.account_name);
5281 
5282                         break;
5283                 case 2:
5284                         STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name,
5285                                            info->info21.account_name, info->info21.account_name);
5286                         STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description,
5287                                            info->info21.description, info->info21.account_name);
5288                         INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid,
5289                                         info->info21.rid, info->info21.account_name);
5290                         INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL),
5291                                         info->info21.acct_flags, info->info21.account_name);
5292 
5293                         if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) {
5294                                 printf("Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
5295                                        info->info21.account_name.string);
5296                         }
5297 
5298                         if (!(info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
5299                                 printf("Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
5300                                        info->info21.account_name.string,
5301                                        querydisplayinfo->out.info->info2.entries[i].acct_flags,
5302                                        info->info21.acct_flags);
5303                                 return false;
5304                         }
5305 
5306                         break;
5307                 }
5308 
5309                 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
5310                         return false;
5311                 }
5312         }
5313         return ret;
5314 }
5315 
5316 static bool test_QueryDisplayInfo(struct dcerpc_pipe *p,
     /* [<][>][^][v][top][bottom][index][help] */
5317                                   struct torture_context *tctx,
5318                                   struct policy_handle *handle)
5319 {
5320         NTSTATUS status;
5321         struct samr_QueryDisplayInfo r;
5322         struct samr_QueryDomainInfo dom_info;
5323         union samr_DomainInfo *info = NULL;
5324         bool ret = true;
5325         uint16_t levels[] = {1, 2, 3, 4, 5};
5326         int i;
5327         bool seen_testuser = false;
5328         uint32_t total_size;
5329         uint32_t returned_size;
5330         union samr_DispInfo disp_info;
5331 
5332 
5333         for (i=0;i<ARRAY_SIZE(levels);i++) {
5334                 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
5335 
5336                 r.in.start_idx = 0;
5337                 status = STATUS_MORE_ENTRIES;
5338                 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5339                         r.in.domain_handle = handle;
5340                         r.in.level = levels[i];
5341                         r.in.max_entries = 2;
5342                         r.in.buf_size = (uint32_t)-1;
5343                         r.out.total_size = &total_size;
5344                         r.out.returned_size = &returned_size;
5345                         r.out.info = &disp_info;
5346 
5347                         status = dcerpc_samr_QueryDisplayInfo(p, tctx, &r);
5348                         if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
5349                                 printf("QueryDisplayInfo level %u failed - %s\n",
5350                                        levels[i], nt_errstr(status));
5351                                 ret = false;
5352                         }
5353                         switch (r.in.level) {
5354                         case 1:
5355                                 if (!test_each_DisplayInfo_user(p, tctx, &r, &seen_testuser)) {
5356                                         ret = false;
5357                                 }
5358                                 r.in.start_idx += r.out.info->info1.count;
5359                                 break;
5360                         case 2:
5361                                 if (!test_each_DisplayInfo_user(p, tctx, &r, NULL)) {
5362                                         ret = false;
5363                                 }
5364                                 r.in.start_idx += r.out.info->info2.count;
5365                                 break;
5366                         case 3:
5367                                 r.in.start_idx += r.out.info->info3.count;
5368                                 break;
5369                         case 4:
5370                                 r.in.start_idx += r.out.info->info4.count;
5371                                 break;
5372                         case 5:
5373                                 r.in.start_idx += r.out.info->info5.count;
5374                                 break;
5375                         }
5376                 }
5377                 dom_info.in.domain_handle = handle;
5378                 dom_info.in.level = 2;
5379                 dom_info.out.info = &info;
5380 
5381                 /* Check number of users returned is correct */
5382                 status = dcerpc_samr_QueryDomainInfo(p, tctx, &dom_info);
5383                 if (!NT_STATUS_IS_OK(status)) {
5384                         printf("QueryDomainInfo level %u failed - %s\n",
5385                                r.in.level, nt_errstr(status));
5386                                 ret = false;
5387                                 break;
5388                 }
5389                 switch (r.in.level) {
5390                 case 1:
5391                 case 4:
5392                         if (info->general.num_users < r.in.start_idx) {
5393                                 printf("QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
5394                                        r.in.start_idx, info->general.num_groups,
5395                                        info->general.domain_name.string);
5396                                 ret = false;
5397                         }
5398                         if (!seen_testuser) {
5399                                 struct policy_handle user_handle;
5400                                 if (NT_STATUS_IS_OK(test_OpenUser_byname(p, tctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
5401                                         printf("Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
5402                                                info->general.domain_name.string);
5403                                         ret = false;
5404                                         test_samr_handle_Close(p, tctx, &user_handle);
5405                                 }
5406                         }
5407                         break;
5408                 case 3:
5409                 case 5:
5410                         if (info->general.num_groups != r.in.start_idx) {
5411                                 printf("QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
5412                                        r.in.start_idx, info->general.num_groups,
5413                                        info->general.domain_name.string);
5414                                 ret = false;
5415                         }
5416 
5417                         break;
5418                 }
5419 
5420         }
5421 
5422         return ret;
5423 }
5424 
5425 static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p,
     /* [<][>][^][v][top][bottom][index][help] */
5426                                    struct torture_context *tctx,
5427                                    struct policy_handle *handle)
5428 {
5429         NTSTATUS status;
5430         struct samr_QueryDisplayInfo2 r;
5431         bool ret = true;
5432         uint16_t levels[] = {1, 2, 3, 4, 5};
5433         int i;
5434         uint32_t total_size;
5435         uint32_t returned_size;
5436         union samr_DispInfo info;
5437 
5438         for (i=0;i<ARRAY_SIZE(levels);i++) {
5439                 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
5440 
5441                 r.in.domain_handle = handle;
5442                 r.in.level = levels[i];
5443                 r.in.start_idx = 0;
5444                 r.in.max_entries = 1000;
5445                 r.in.buf_size = (uint32_t)-1;
5446                 r.out.total_size = &total_size;
5447                 r.out.returned_size = &returned_size;
5448                 r.out.info = &info;
5449 
5450                 status = dcerpc_samr_QueryDisplayInfo2(p, tctx, &r);
5451                 if (!NT_STATUS_IS_OK(status)) {
5452                         printf("QueryDisplayInfo2 level %u failed - %s\n",
5453                                levels[i], nt_errstr(status));
5454                         ret = false;
5455                 }
5456         }
5457 
5458         return ret;
5459 }
5460 
5461 static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
5462                                   struct policy_handle *handle)
5463 {
5464         NTSTATUS status;
5465         struct samr_QueryDisplayInfo3 r;
5466         bool ret = true;
5467         uint16_t levels[] = {1, 2, 3, 4, 5};
5468         int i;
5469         uint32_t total_size;
5470         uint32_t returned_size;
5471         union samr_DispInfo info;
5472 
5473         for (i=0;i<ARRAY_SIZE(levels);i++) {
5474                 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
5475 
5476                 r.in.domain_handle = handle;
5477                 r.in.level = levels[i];
5478                 r.in.start_idx = 0;
5479                 r.in.max_entries = 1000;
5480                 r.in.buf_size = (uint32_t)-1;
5481                 r.out.total_size = &total_size;
5482                 r.out.returned_size = &returned_size;
5483                 r.out.info = &info;
5484 
5485                 status = dcerpc_samr_QueryDisplayInfo3(p, tctx, &r);
5486                 if (!NT_STATUS_IS_OK(status)) {
5487                         printf("QueryDisplayInfo3 level %u failed - %s\n",
5488                                levels[i], nt_errstr(status));
5489                         ret = false;
5490                 }
5491         }
5492 
5493         return ret;
5494 }
5495 
5496 
5497 static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p,
     /* [<][>][^][v][top][bottom][index][help] */
5498                                            struct torture_context *tctx,
5499                                            struct policy_handle *handle)
5500 {
5501         NTSTATUS status;
5502         struct samr_QueryDisplayInfo r;
5503         bool ret = true;
5504         uint32_t total_size;
5505         uint32_t returned_size;
5506         union samr_DispInfo info;
5507 
5508         printf("Testing QueryDisplayInfo continuation\n");
5509 
5510         r.in.domain_handle = handle;
5511         r.in.level = 1;
5512         r.in.start_idx = 0;
5513         r.in.max_entries = 1;
5514         r.in.buf_size = (uint32_t)-1;
5515         r.out.total_size = &total_size;
5516         r.out.returned_size = &returned_size;
5517         r.out.info = &info;
5518 
5519         do {
5520                 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &r);
5521                 if (NT_STATUS_IS_OK(status) && *r.out.returned_size != 0) {
5522                         if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) {
5523                                 printf("expected idx %d but got %d\n",
5524                                        r.in.start_idx + 1,
5525                                        r.out.info->info1.entries[0].idx);
5526                                 break;
5527                         }
5528                 }
5529                 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
5530                     !NT_STATUS_IS_OK(status)) {
5531                         printf("QueryDisplayInfo level %u failed - %s\n",
5532                                r.in.level, nt_errstr(status));
5533                         ret = false;
5534                         break;
5535                 }
5536                 r.in.start_idx++;
5537         } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
5538                   NT_STATUS_IS_OK(status)) &&
5539                  *r.out.returned_size != 0);
5540 
5541         return ret;
5542 }
5543 
5544 static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
5545                                  struct policy_handle *handle)
5546 {
5547         NTSTATUS status;
5548         struct samr_QueryDomainInfo r;
5549         union samr_DomainInfo *info = NULL;
5550         struct samr_SetDomainInfo s;
5551         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
5552         uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1,  0,  1,  0};
5553         int i;
5554         bool ret = true;
5555         const char *domain_comment = talloc_asprintf(tctx,
5556                                   "Tortured by Samba4 RPC-SAMR: %s",
5557                                   timestring(tctx, time(NULL)));
5558 
5559         s.in.domain_handle = handle;
5560         s.in.level = 4;
5561         s.in.info = talloc(tctx, union samr_DomainInfo);
5562 
5563         s.in.info->oem.oem_information.string = domain_comment;
5564         status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
5565         if (!NT_STATUS_IS_OK(status)) {
5566                 printf("SetDomainInfo level %u (set comment) failed - %s\n",
5567                        s.in.level, nt_errstr(status));
5568                 return false;
5569         }
5570 
5571         for (i=0;i<ARRAY_SIZE(levels);i++) {
5572                 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
5573 
5574                 r.in.domain_handle = handle;
5575                 r.in.level = levels[i];
5576                 r.out.info = &info;
5577 
5578                 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
5579                 if (!NT_STATUS_IS_OK(status)) {
5580                         printf("QueryDomainInfo level %u failed - %s\n",
5581                                r.in.level, nt_errstr(status));
5582                         ret = false;
5583                         continue;
5584                 }
5585 
5586                 switch (levels[i]) {
5587                 case 2:
5588                         if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
5589                                 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
5590                                        levels[i], info->general.oem_information.string, domain_comment);
5591                                 ret = false;
5592                         }
5593                         if (!info->general.primary.string) {
5594                                 printf("QueryDomainInfo level %u returned no PDC name\n",
5595                                        levels[i]);
5596                                 ret = false;
5597                         } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
5598                                 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
5599                                         printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
5600                                                levels[i], info->general.primary.string, dcerpc_server_name(p));
5601                                 }
5602                         }
5603                         break;
5604                 case 4:
5605                         if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
5606                                 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
5607                                        levels[i], info->oem.oem_information.string, domain_comment);
5608                                 ret = false;
5609                         }
5610                         break;
5611                 case 6:
5612                         if (!info->info6.primary.string) {
5613                                 printf("QueryDomainInfo level %u returned no PDC name\n",
5614                                        levels[i]);
5615                                 ret = false;
5616                         }
5617                         break;
5618                 case 11:
5619                         if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
5620                                 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
5621                                        levels[i], info->general2.general.oem_information.string, domain_comment);
5622                                 ret = false;
5623                         }
5624                         break;
5625                 }
5626 
5627                 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
5628 
5629                 s.in.domain_handle = handle;
5630                 s.in.level = levels[i];
5631                 s.in.info = info;
5632 
5633                 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
5634                 if (set_ok[i]) {
5635                         if (!NT_STATUS_IS_OK(status)) {
5636                                 printf("SetDomainInfo level %u failed - %s\n",
5637                                        r.in.level, nt_errstr(status));
5638                                 ret = false;
5639                                 continue;
5640                         }
5641                 } else {
5642                         if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
5643                                 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
5644                                        r.in.level, nt_errstr(status));
5645                                 ret = false;
5646                                 continue;
5647                         }
5648                 }
5649 
5650                 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
5651                 if (!NT_STATUS_IS_OK(status)) {
5652                         printf("QueryDomainInfo level %u failed - %s\n",
5653                                r.in.level, nt_errstr(status));
5654                         ret = false;
5655                         continue;
5656                 }
5657         }
5658 
5659         return ret;
5660 }
5661 
5662 
5663 static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
5664                                   struct policy_handle *handle)
5665 {
5666         NTSTATUS status;
5667         struct samr_QueryDomainInfo2 r;
5668         union samr_DomainInfo *info = NULL;
5669         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
5670         int i;
5671         bool ret = true;
5672 
5673         for (i=0;i<ARRAY_SIZE(levels);i++) {
5674                 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
5675 
5676                 r.in.domain_handle = handle;
5677                 r.in.level = levels[i];
5678                 r.out.info = &info;
5679 
5680                 status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
5681                 if (!NT_STATUS_IS_OK(status)) {
5682                         printf("QueryDomainInfo2 level %u failed - %s\n",
5683                                r.in.level, nt_errstr(status));
5684                         ret = false;
5685                         continue;
5686                 }
5687         }
5688 
5689         return true;
5690 }
5691 
5692 /* Test whether querydispinfo level 5 and enumdomgroups return the same
5693    set of group names. */
5694 static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
5695                            struct policy_handle *handle)
5696 {
5697         struct samr_EnumDomainGroups q1;
5698         struct samr_QueryDisplayInfo q2;
5699         NTSTATUS status;
5700         uint32_t resume_handle=0;
5701         struct samr_SamArray *sam = NULL;
5702         uint32_t num_entries = 0;
5703         int i;
5704         bool ret = true;
5705         uint32_t total_size;
5706         uint32_t returned_size;
5707         union samr_DispInfo info;
5708 
5709         int num_names = 0;
5710         const char **names = NULL;
5711 
5712         torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
5713 
5714         q1.in.domain_handle = handle;
5715         q1.in.resume_handle = &resume_handle;
5716         q1.in.max_size = 5;
5717         q1.out.resume_handle = &resume_handle;
5718         q1.out.num_entries = &num_entries;
5719         q1.out.sam = &sam;
5720 
5721         status = STATUS_MORE_ENTRIES;
5722         while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5723                 status = dcerpc_samr_EnumDomainGroups(p, tctx, &q1);
5724 
5725                 if (!NT_STATUS_IS_OK(status) &&
5726                     !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
5727                         break;
5728 
5729                 for (i=0; i<*q1.out.num_entries; i++) {
5730                         add_string_to_array(tctx,
5731                                             sam->entries[i].name.string,
5732                                             &names, &num_names);
5733                 }
5734         }
5735 
5736         torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
5737 
5738         torture_assert(tctx, sam, "EnumDomainGroups failed to return sam");
5739 
5740         q2.in.domain_handle = handle;
5741         q2.in.level = 5;
5742         q2.in.start_idx = 0;
5743         q2.in.max_entries = 5;
5744         q2.in.buf_size = (uint32_t)-1;
5745         q2.out.total_size = &total_size;
5746         q2.out.returned_size = &returned_size;
5747         q2.out.info = &info;
5748 
5749         status = STATUS_MORE_ENTRIES;
5750         while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5751                 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &q2);
5752 
5753                 if (!NT_STATUS_IS_OK(status) &&
5754                     !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
5755                         break;
5756 
5757                 for (i=0; i<q2.out.info->info5.count; i++) {
5758                         int j;
5759                         const char *name = q2.out.info->info5.entries[i].account_name.string;
5760                         bool found = false;
5761                         for (j=0; j<num_names; j++) {
5762                                 if (names[j] == NULL)
5763                                         continue;
5764                                 if (strequal(names[j], name)) {
5765                                         names[j] = NULL;
5766                                         found = true;
5767                                         break;
5768                                 }
5769                         }
5770 
5771                         if (!found) {
5772                                 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
5773                                        name);
5774                                 ret = false;
5775                         }
5776                 }
5777                 q2.in.start_idx += q2.out.info->info5.count;
5778         }
5779 
5780         if (!NT_STATUS_IS_OK(status)) {
5781                 printf("QueryDisplayInfo level 5 failed - %s\n",
5782                        nt_errstr(status));
5783                 ret = false;
5784         }
5785 
5786         for (i=0; i<num_names; i++) {
5787                 if (names[i] != NULL) {
5788                         printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
5789                                names[i]);
5790                         ret = false;
5791                 }
5792         }
5793 
5794         return ret;
5795 }
5796 
5797 static bool test_DeleteDomainGroup(struct dcerpc_pipe *p, struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
5798                                    struct policy_handle *group_handle)
5799 {
5800         struct samr_DeleteDomainGroup d;
5801         NTSTATUS status;
5802 
5803         torture_comment(tctx, "Testing DeleteDomainGroup\n");
5804 
5805         d.in.group_handle = group_handle;
5806         d.out.group_handle = group_handle;
5807 
5808         status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
5809         torture_assert_ntstatus_ok(tctx, status, "DeleteDomainGroup");
5810 
5811         return true;
5812 }
5813 
5814 static bool test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
5815                                             struct policy_handle *domain_handle)
5816 {
5817         struct samr_TestPrivateFunctionsDomain r;
5818         NTSTATUS status;
5819         bool ret = true;
5820 
5821         torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
5822 
5823         r.in.domain_handle = domain_handle;
5824 
5825         status = dcerpc_samr_TestPrivateFunctionsDomain(p, tctx, &r);
5826         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsDomain");
5827 
5828         return ret;
5829 }
5830 
5831 static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
5832                           struct dom_sid *domain_sid,
5833                           struct policy_handle *domain_handle)
5834 {
5835         struct samr_RidToSid r;
5836         NTSTATUS status;
5837         bool ret = true;
5838         struct dom_sid *calc_sid, *out_sid;
5839         int rids[] = { 0, 42, 512, 10200 };
5840         int i;
5841 
5842         for (i=0;i<ARRAY_SIZE(rids);i++) {
5843                 torture_comment(tctx, "Testing RidToSid\n");
5844 
5845                 calc_sid = dom_sid_dup(tctx, domain_sid);
5846                 r.in.domain_handle = domain_handle;
5847                 r.in.rid = rids[i];
5848                 r.out.sid = &out_sid;
5849 
5850                 status = dcerpc_samr_RidToSid(p, tctx, &r);
5851                 if (!NT_STATUS_IS_OK(status)) {
5852                         printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
5853                         ret = false;
5854                 } else {
5855                         calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
5856 
5857                         if (!dom_sid_equal(calc_sid, out_sid)) {
5858                                 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i],
5859                                        dom_sid_string(tctx, out_sid),
5860                                        dom_sid_string(tctx, calc_sid));
5861                                 ret = false;
5862                         }
5863                 }
5864         }
5865 
5866         return ret;
5867 }
5868 
5869 static bool test_GetBootKeyInformation(struct dcerpc_pipe *p, struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
5870                                        struct policy_handle *domain_handle)
5871 {
5872         struct samr_GetBootKeyInformation r;
5873         NTSTATUS status;
5874         bool ret = true;
5875         uint32_t unknown = 0;
5876 
5877         torture_comment(tctx, "Testing GetBootKeyInformation\n");
5878 
5879         r.in.domain_handle = domain_handle;
5880         r.out.unknown = &unknown;
5881 
5882         status = dcerpc_samr_GetBootKeyInformation(p, tctx, &r);
5883         if (!NT_STATUS_IS_OK(status)) {
5884                 /* w2k3 seems to fail this sometimes and pass it sometimes */
5885                 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
5886         }
5887 
5888         return ret;
5889 }
5890 
5891 static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
5892                                 struct policy_handle *domain_handle,
5893                                 struct policy_handle *group_handle)
5894 {
5895         NTSTATUS status;
5896         struct samr_AddGroupMember r;
5897         struct samr_DeleteGroupMember d;
5898         struct samr_QueryGroupMember q;
5899         struct samr_RidTypeArray *rids = NULL;
5900         struct samr_SetMemberAttributesOfGroup s;
5901         uint32_t rid;
5902 
5903         status = test_LookupName(p, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
5904         torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
5905 
5906         r.in.group_handle = group_handle;
5907         r.in.rid = rid;
5908         r.in.flags = 0; /* ??? */
5909 
5910         torture_comment(tctx, "Testing AddGroupMember and DeleteGroupMember\n");
5911 
5912         d.in.group_handle = group_handle;
5913         d.in.rid = rid;
5914 
5915         status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
5916         torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, status, "DeleteGroupMember");
5917 
5918         status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5919         torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
5920 
5921         status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5922         torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, status, "AddGroupMember");
5923 
5924         if (torture_setting_bool(tctx, "samba4", false) ||
5925             torture_setting_bool(tctx, "samba3", false)) {
5926                 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba4\n");
5927         } else {
5928                 /* this one is quite strange. I am using random inputs in the
5929                    hope of triggering an error that might give us a clue */
5930 
5931                 s.in.group_handle = group_handle;
5932                 s.in.unknown1 = random();
5933                 s.in.unknown2 = random();
5934 
5935                 status = dcerpc_samr_SetMemberAttributesOfGroup(p, tctx, &s);
5936                 torture_assert_ntstatus_ok(tctx, status, "SetMemberAttributesOfGroup");
5937         }
5938 
5939         q.in.group_handle = group_handle;
5940         q.out.rids = &rids;
5941 
5942         status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
5943         torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember");
5944 
5945         status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
5946         torture_assert_ntstatus_ok(tctx, status, "DeleteGroupMember");
5947 
5948         status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5949         torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
5950 
5951         return true;
5952 }
5953 
5954 
5955 static bool test_CreateDomainGroup(struct dcerpc_pipe *p,
     /* [<][>][^][v][top][bottom][index][help] */
5956                                    struct torture_context *tctx,
5957                                    struct policy_handle *domain_handle,
5958                                    const char *group_name,
5959                                    struct policy_handle *group_handle,
5960                                    struct dom_sid *domain_sid,
5961                                    bool test_group)
5962 {
5963         NTSTATUS status;
5964         struct samr_CreateDomainGroup r;
5965         uint32_t rid;
5966         struct lsa_String name;
5967         bool ret = true;
5968 
5969         init_lsa_String(&name, group_name);
5970 
5971         r.in.domain_handle = domain_handle;
5972         r.in.name = &name;
5973         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5974         r.out.group_handle = group_handle;
5975         r.out.rid = &rid;
5976 
5977         printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
5978 
5979         status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
5980 
5981         if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5982                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5983                         torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
5984                         return true;
5985                 } else {
5986                         printf("Server should have refused create of '%s', got %s instead\n", r.in.name->string,
5987                                nt_errstr(status));
5988                         return false;
5989                 }
5990         }
5991 
5992         if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
5993                 if (!test_DeleteGroup_byname(p, tctx, domain_handle, r.in.name->string)) {
5994                         printf("CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
5995                                nt_errstr(status));
5996                         return false;
5997                 }
5998                 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
5999         }
6000         if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
6001                 if (!test_DeleteUser_byname(p, tctx, domain_handle, r.in.name->string)) {
6002 
6003                         printf("CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
6004                                nt_errstr(status));
6005                         return false;
6006                 }
6007                 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
6008         }
6009         torture_assert_ntstatus_ok(tctx, status, "CreateDomainGroup");
6010 
6011         if (!test_group) {
6012                 return ret;
6013         }
6014 
6015         if (!test_AddGroupMember(p, tctx, domain_handle, group_handle)) {
6016                 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
6017                 ret = false;
6018         }
6019 
6020         if (!test_SetGroupInfo(p, tctx, group_handle)) {
6021                 ret = false;
6022         }
6023 
6024         return ret;
6025 }
6026 
6027 
6028 /*
6029   its not totally clear what this does. It seems to accept any sid you like.
6030 */
6031 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
     /* [<][>][^][v][top][bottom][index][help] */
6032                                                struct torture_context *tctx,
6033                                                struct policy_handle *domain_handle)
6034 {
6035         NTSTATUS status;
6036         struct samr_RemoveMemberFromForeignDomain r;
6037 
6038         r.in.domain_handle = domain_handle;
6039         r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
6040 
6041         status = dcerpc_samr_RemoveMemberFromForeignDomain(p, tctx, &r);
6042         torture_assert_ntstatus_ok(tctx, status, "RemoveMemberFromForeignDomain");
6043 
6044         return true;
6045 }
6046 
6047 static bool test_EnumDomainUsers(struct dcerpc_pipe *p,
     /* [<][>][^][v][top][bottom][index][help] */
6048                                  struct torture_context *tctx,
6049                                  struct policy_handle *domain_handle,
6050                                  uint32_t *total_num_entries_p)
6051 {
6052         NTSTATUS status;
6053         struct samr_EnumDomainUsers r;
6054         uint32_t resume_handle = 0;
6055         uint32_t num_entries = 0;
6056         uint32_t total_num_entries = 0;
6057         struct samr_SamArray *sam;
6058 
6059         r.in.domain_handle = domain_handle;
6060         r.in.acct_flags = ACB_NORMAL;
6061         r.in.max_size = (uint32_t)-1;
6062         r.in.resume_handle = &resume_handle;
6063 
6064         r.out.sam = &sam;
6065         r.out.num_entries = &num_entries;
6066         r.out.resume_handle = &resume_handle;
6067 
6068         printf("Testing EnumDomainUsers\n");
6069 
6070         do {
6071                 status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
6072                 if (NT_STATUS_IS_ERR(status)) {
6073                         torture_assert_ntstatus_ok(tctx, status,
6074                                 "failed to enumerate users");
6075                 }
6076 
6077                 total_num_entries += num_entries;
6078         } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
6079 
6080         if (total_num_entries_p) {
6081                 *total_num_entries_p = total_num_entries;
6082         }
6083 
6084         return true;
6085 }
6086 
6087 static bool test_EnumDomainGroups(struct dcerpc_pipe *p,
     /* [<][>][^][v][top][bottom][index][help] */
6088                                   struct torture_context *tctx,
6089                                   struct policy_handle *domain_handle,
6090                                   uint32_t *total_num_entries_p)
6091 {
6092         NTSTATUS status;
6093         struct samr_EnumDomainGroups r;
6094         uint32_t resume_handle = 0;
6095         uint32_t num_entries = 0;
6096         uint32_t total_num_entries = 0;
6097         struct samr_SamArray *sam;
6098 
6099         r.in.domain_handle = domain_handle;
6100         r.in.max_size = (uint32_t)-1;
6101         r.in.resume_handle = &resume_handle;
6102 
6103         r.out.sam = &sam;
6104         r.out.num_entries = &num_entries;
6105         r.out.resume_handle = &resume_handle;
6106 
6107         printf("Testing EnumDomainGroups\n");
6108 
6109         do {
6110                 status = dcerpc_samr_EnumDomainGroups(p, tctx, &r);
6111                 if (NT_STATUS_IS_ERR(status)) {
6112                         torture_assert_ntstatus_ok(tctx, status,
6113                                 "failed to enumerate groups");
6114                 }
6115 
6116                 total_num_entries += num_entries;
6117         } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
6118 
6119         if (total_num_entries_p) {
6120                 *total_num_entries_p = total_num_entries;
6121         }
6122 
6123         return true;
6124 }
6125 
6126 static bool test_EnumDomainAliases(struct dcerpc_pipe *p,
     /* [<][>][^][v][top][bottom][index][help] */
6127                                    struct torture_context *tctx,
6128                                    struct policy_handle *domain_handle,
6129                                    uint32_t *total_num_entries_p)
6130 {
6131         NTSTATUS status;
6132         struct samr_EnumDomainAliases r;
6133         uint32_t resume_handle = 0;
6134         uint32_t num_entries = 0;
6135         uint32_t total_num_entries = 0;
6136         struct samr_SamArray *sam;
6137 
6138         r.in.domain_handle = domain_handle;
6139         r.in.max_size = (uint32_t)-1;
6140         r.in.resume_handle = &resume_handle;
6141 
6142         r.out.sam = &sam;
6143         r.out.num_entries = &num_entries;
6144         r.out.resume_handle = &resume_handle;
6145 
6146         printf("Testing EnumDomainAliases\n");
6147 
6148         do {
6149                 status = dcerpc_samr_EnumDomainAliases(p, tctx, &r);
6150                 if (NT_STATUS_IS_ERR(status)) {
6151                         torture_assert_ntstatus_ok(tctx, status,
6152                                 "failed to enumerate aliases");
6153                 }
6154 
6155                 total_num_entries += num_entries;
6156         } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
6157 
6158         if (total_num_entries_p) {
6159                 *total_num_entries_p = total_num_entries;
6160         }
6161 
6162         return true;
6163 }
6164 
6165 static bool test_ManyObjects(struct dcerpc_pipe *p,
     /* [<][>][^][v][top][bottom][index][help] */
6166                              struct torture_context *tctx,
6167                              struct policy_handle *domain_handle,
6168                              struct dom_sid *domain_sid,
6169                              enum torture_samr_choice which_ops)
6170 {
6171         uint32_t num_total = 1500;
6172         uint32_t num_enum = 0;
6173         uint32_t num_disp = 0;
6174         uint32_t num_created = 0;
6175         uint32_t num_anounced = 0;
6176         bool ret = true;
6177         NTSTATUS status;
6178         uint32_t i;
6179 
6180         /* query */
6181 
6182         {
6183                 struct samr_QueryDomainInfo2 r;
6184                 union samr_DomainInfo *info;
6185                 r.in.domain_handle = domain_handle;
6186                 r.in.level = 2;
6187                 r.out.info = &info;
6188 
6189                 status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
6190                 torture_assert_ntstatus_ok(tctx, status,
6191                         "failed to query domain info");
6192 
6193                 switch (which_ops) {
6194                 case TORTURE_SAMR_MANY_ACCOUNTS:
6195                         num_anounced = info->general.num_users;
6196                         break;
6197                 case TORTURE_SAMR_MANY_GROUPS:
6198                         num_anounced = info->general.num_groups;
6199                         break;
6200                 case TORTURE_SAMR_MANY_ALIASES:
6201                         num_anounced = info->general.num_aliases;
6202                         break;
6203                 default:
6204                         return false;
6205                 }
6206         }
6207 
6208         /* create */
6209 
6210         for (i=0; i < num_total; i++) {
6211 
6212                 struct policy_handle handle;
6213                 const char *name = NULL;
6214 
6215                 ZERO_STRUCT(handle);
6216 
6217                 switch (which_ops) {
6218                 case TORTURE_SAMR_MANY_ACCOUNTS:
6219                         name = talloc_asprintf(tctx, "%s%04d", TEST_ACCOUNT_NAME, i);
6220                         ret &= test_CreateUser(p, tctx, domain_handle, name, &handle, domain_sid, 0, NULL, false);
6221                         break;
6222                 case TORTURE_SAMR_MANY_GROUPS:
6223                         name = talloc_asprintf(tctx, "%s%04d", TEST_GROUPNAME, i);
6224                         ret &= test_CreateDomainGroup(p, tctx, domain_handle, name, &handle, domain_sid, false);
6225                         break;
6226                 case TORTURE_SAMR_MANY_ALIASES:
6227                         name = talloc_asprintf(tctx, "%s%04d", TEST_ALIASNAME, i);
6228                         ret &= test_CreateAlias(p, tctx, domain_handle, name, &handle, domain_sid, false);
6229                         break;
6230                 default:
6231                         return false;
6232                 }
6233                 if (!policy_handle_empty(&handle)) {
6234                         ret &= test_samr_handle_Close(p, tctx, &handle);
6235                         num_created++;
6236                 }
6237         }
6238 
6239         /* enum */
6240 
6241         switch (which_ops) {
6242         case TORTURE_SAMR_MANY_ACCOUNTS:
6243                 ret &= test_EnumDomainUsers(p, tctx, domain_handle, &num_enum);
6244                 break;
6245         case TORTURE_SAMR_MANY_GROUPS:
6246                 ret &= test_EnumDomainGroups(p, tctx, domain_handle, &num_enum);
6247                 break;
6248         case TORTURE_SAMR_MANY_ALIASES:
6249                 ret &= test_EnumDomainAliases(p, tctx, domain_handle, &num_enum);
6250                 break;
6251         default:
6252                 return false;
6253         }
6254 
6255         torture_assert_int_equal(tctx, num_enum, num_anounced + num_created,
6256                 "unexpected number of results returned in enum call");
6257 #if 0
6258         /* TODO: dispinfo */
6259 
6260         switch (which_ops) {
6261         case TORTURE_SAMR_MANY_ACCOUNTS:
6262                 break;
6263         case TORTURE_SAMR_MANY_GROUPS:
6264                 break;
6265         case TORTURE_SAMR_MANY_ALIASES:
6266                 break;
6267         default:
6268                 return false;
6269         }
6270 
6271         torture_assert_int_equal(tctx, num_disp, num_anounced + num_created,
6272                 "unexpected number of results returned in dispinfo call");
6273 #endif
6274         return ret;
6275 }
6276 
6277 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
6278                          struct policy_handle *handle);
6279 
6280 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
6281                             struct policy_handle *handle, struct dom_sid *sid,
6282                             enum torture_samr_choice which_ops,
6283                             struct cli_credentials *machine_credentials)
6284 {
6285         NTSTATUS status;
6286         struct samr_OpenDomain r;
6287         struct policy_handle domain_handle;
6288         struct policy_handle alias_handle;
6289         struct policy_handle user_handle;
6290         struct policy_handle group_handle;
6291         bool ret = true;
6292 
6293         ZERO_STRUCT(alias_handle);
6294         ZERO_STRUCT(user_handle);
6295         ZERO_STRUCT(group_handle);
6296         ZERO_STRUCT(domain_handle);
6297 
6298         torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
6299 
6300         r.in.connect_handle = handle;
6301         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6302         r.in.sid = sid;
6303         r.out.domain_handle = &domain_handle;
6304 
6305         status = dcerpc_samr_OpenDomain(p, tctx, &r);
6306         torture_assert_ntstatus_ok(tctx, status, "OpenDomain");
6307 
6308         /* run the domain tests with the main handle closed - this tests
6309            the servers reference counting */
6310         ret &= test_samr_handle_Close(p, tctx, handle);
6311 
6312         switch (which_ops) {
6313         case TORTURE_SAMR_USER_ATTRIBUTES:
6314         case TORTURE_SAMR_USER_PRIVILEGES:
6315         case TORTURE_SAMR_PASSWORDS:
6316                 if (!torture_setting_bool(tctx, "samba3", false)) {
6317                         ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, NULL);
6318                 }
6319                 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, which_ops, NULL, true);
6320                 /* This test needs 'complex' users to validate */
6321                 ret &= test_QueryDisplayInfo(p, tctx, &domain_handle);
6322                 if (!ret) {
6323                         printf("Testing PASSWORDS or ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
6324                 }
6325                 break;
6326         case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
6327                 if (!torture_setting_bool(tctx, "samba3", false)) {
6328                         ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, machine_credentials);
6329                 }
6330                 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, which_ops, machine_credentials, true);
6331                 if (!ret) {
6332                         printf("Testing PASSWORDS PWDLASTSET on domain %s failed!\n", dom_sid_string(tctx, sid));
6333                 }
6334                 break;
6335         case TORTURE_SAMR_MANY_ACCOUNTS:
6336         case TORTURE_SAMR_MANY_GROUPS:
6337         case TORTURE_SAMR_MANY_ALIASES:
6338                 ret &= test_ManyObjects(p, tctx, &domain_handle, sid, which_ops);
6339                 break;
6340         case TORTURE_SAMR_OTHER:
6341                 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, which_ops, NULL, true);
6342                 if (!ret) {
6343                         printf("Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
6344                 }
6345                 if (!torture_setting_bool(tctx, "samba3", false)) {
6346                         ret &= test_QuerySecurity(p, tctx, &domain_handle);
6347                 }
6348                 ret &= test_RemoveMemberFromForeignDomain(p, tctx, &domain_handle);
6349                 ret &= test_CreateAlias(p, tctx, &domain_handle, TEST_ALIASNAME, &alias_handle, sid, true);
6350                 ret &= test_CreateDomainGroup(p, tctx, &domain_handle, TEST_GROUPNAME, &group_handle, sid, true);
6351                 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
6352                 ret &= test_QueryDomainInfo2(p, tctx, &domain_handle);
6353                 ret &= test_EnumDomainUsers_all(p, tctx, &domain_handle);
6354                 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
6355                 ret &= test_EnumDomainGroups_all(p, tctx, &domain_handle);
6356                 ret &= test_EnumDomainAliases_all(p, tctx, &domain_handle);
6357                 ret &= test_QueryDisplayInfo2(p, tctx, &domain_handle);
6358                 ret &= test_QueryDisplayInfo3(p, tctx, &domain_handle);
6359                 ret &= test_QueryDisplayInfo_continue(p, tctx, &domain_handle);
6360 
6361                 if (torture_setting_bool(tctx, "samba4", false)) {
6362                         torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
6363                 } else {
6364                         ret &= test_GetDisplayEnumerationIndex(p, tctx, &domain_handle);
6365                         ret &= test_GetDisplayEnumerationIndex2(p, tctx, &domain_handle);
6366                 }
6367                 ret &= test_GroupList(p, tctx, &domain_handle);
6368                 ret &= test_TestPrivateFunctionsDomain(p, tctx, &domain_handle);
6369                 ret &= test_RidToSid(p, tctx, sid, &domain_handle);
6370                 ret &= test_GetBootKeyInformation(p, tctx, &domain_handle);
6371                 if (!ret) {
6372                         torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
6373                 }
6374                 break;
6375         }
6376 
6377         if (!policy_handle_empty(&user_handle) &&
6378             !test_DeleteUser(p, tctx, &user_handle)) {
6379                 ret = false;
6380         }
6381 
6382         if (!policy_handle_empty(&alias_handle) &&
6383             !test_DeleteAlias(p, tctx, &alias_handle)) {
6384                 ret = false;
6385         }
6386 
6387         if (!policy_handle_empty(&group_handle) &&
6388             !test_DeleteDomainGroup(p, tctx, &group_handle)) {
6389                 ret = false;
6390         }
6391 
6392         ret &= test_samr_handle_Close(p, tctx, &domain_handle);
6393 
6394         /* reconnect the main handle */
6395         ret &= test_Connect(p, tctx, handle);
6396 
6397         if (!ret) {
6398                 printf("Testing domain %s failed!\n", dom_sid_string(tctx, sid));
6399         }
6400 
6401         return ret;
6402 }
6403 
6404 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
6405                               struct policy_handle *handle, const char *domain,
6406                               enum torture_samr_choice which_ops,
6407                               struct cli_credentials *machine_credentials)
6408 {
6409         NTSTATUS status;
6410         struct samr_LookupDomain r;
6411         struct dom_sid2 *sid = NULL;
6412         struct lsa_String n1;
6413         struct lsa_String n2;
6414         bool ret = true;
6415 
6416         torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
6417 
6418         /* check for correct error codes */
6419         r.in.connect_handle = handle;
6420         r.in.domain_name = &n2;
6421         r.out.sid = &sid;
6422         n2.string = NULL;
6423 
6424         status = dcerpc_samr_LookupDomain(p, tctx, &r);
6425         torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, status, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
6426 
6427         init_lsa_String(&n2, "xxNODOMAINxx");
6428 
6429         status = dcerpc_samr_LookupDomain(p, tctx, &r);
6430         torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, status, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
6431 
6432         r.in.connect_handle = handle;
6433 
6434         init_lsa_String(&n1, domain);
6435         r.in.domain_name = &n1;
6436 
6437         status = dcerpc_samr_LookupDomain(p, tctx, &r);
6438         torture_assert_ntstatus_ok(tctx, status, "LookupDomain");
6439 
6440         if (!test_GetDomPwInfo(p, tctx, &n1)) {
6441                 ret = false;
6442         }
6443 
6444         if (!test_OpenDomain(p, tctx, handle, *r.out.sid, which_ops,
6445                              machine_credentials)) {
6446                 ret = false;
6447         }
6448 
6449         return ret;
6450 }
6451 
6452 
6453 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
6454                              struct policy_handle *handle, enum torture_samr_choice which_ops,
6455                              struct cli_credentials *machine_credentials)
6456 {
6457         NTSTATUS status;
6458         struct samr_EnumDomains r;
6459         uint32_t resume_handle = 0;
6460         uint32_t num_entries = 0;
6461         struct samr_SamArray *sam = NULL;
6462         int i;
6463         bool ret = true;
6464 
6465         r.in.connect_handle = handle;
6466         r.in.resume_handle = &resume_handle;
6467         r.in.buf_size = (uint32_t)-1;
6468         r.out.resume_handle = &resume_handle;
6469         r.out.num_entries = &num_entries;
6470         r.out.sam = &sam;
6471 
6472         status = dcerpc_samr_EnumDomains(p, tctx, &r);
6473         torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
6474 
6475         if (!*r.out.sam) {
6476                 return false;
6477         }
6478 
6479         for (i=0;i<sam->count;i++) {
6480                 if (!test_LookupDomain(p, tctx, handle,
6481                                        sam->entries[i].name.string, which_ops,
6482                                        machine_credentials)) {
6483                         ret = false;
6484                 }
6485         }
6486 
6487         status = dcerpc_samr_EnumDomains(p, tctx, &r);
6488         torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
6489 
6490         return ret;
6491 }
6492 
6493 
6494 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
6495                          struct policy_handle *handle)
6496 {
6497         NTSTATUS status;
6498         struct samr_Connect r;
6499         struct samr_Connect2 r2;
6500         struct samr_Connect3 r3;
6501         struct samr_Connect4 r4;
6502         struct samr_Connect5 r5;
6503         union samr_ConnectInfo info;
6504         struct policy_handle h;
6505         uint32_t level_out = 0;
6506         bool ret = true, got_handle = false;
6507 
6508         torture_comment(tctx, "testing samr_Connect\n");
6509 
6510         r.in.system_name = 0;
6511         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6512         r.out.connect_handle = &h;
6513 
6514         status = dcerpc_samr_Connect(p, tctx, &r);
6515         if (!NT_STATUS_IS_OK(status)) {
6516                 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(status));
6517                 ret = false;
6518         } else {
6519                 got_handle = true;
6520                 *handle = h;
6521         }
6522 
6523         torture_comment(tctx, "testing samr_Connect2\n");
6524 
6525         r2.in.system_name = NULL;
6526         r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6527         r2.out.connect_handle = &h;
6528 
6529         status = dcerpc_samr_Connect2(p, tctx, &r2);
6530         if (!NT_STATUS_IS_OK(status)) {
6531                 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(status));
6532                 ret = false;
6533         } else {
6534                 if (got_handle) {
6535                         test_samr_handle_Close(p, tctx, handle);
6536                 }
6537                 got_handle = true;
6538                 *handle = h;
6539         }
6540 
6541         torture_comment(tctx, "testing samr_Connect3\n");
6542 
6543         r3.in.system_name = NULL;
6544         r3.in.unknown = 0;
6545         r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6546         r3.out.connect_handle = &h;
6547 
6548         status = dcerpc_samr_Connect3(p, tctx, &r3);
6549         if (!NT_STATUS_IS_OK(status)) {
6550                 printf("Connect3 failed - %s\n", nt_errstr(status));
6551                 ret = false;
6552         } else {
6553                 if (got_handle) {
6554                         test_samr_handle_Close(p, tctx, handle);
6555                 }
6556                 got_handle = true;
6557                 *handle = h;
6558         }
6559 
6560         torture_comment(tctx, "testing samr_Connect4\n");
6561 
6562         r4.in.system_name = "";
6563         r4.in.client_version = 0;
6564         r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6565         r4.out.connect_handle = &h;
6566 
6567         status = dcerpc_samr_Connect4(p, tctx, &r4);
6568         if (!NT_STATUS_IS_OK(status)) {
6569                 printf("Connect4 failed - %s\n", nt_errstr(status));
6570                 ret = false;
6571         } else {
6572                 if (got_handle) {
6573                         test_samr_handle_Close(p, tctx, handle);
6574                 }
6575                 got_handle = true;
6576                 *handle = h;
6577         }
6578 
6579         torture_comment(tctx, "testing samr_Connect5\n");
6580 
6581         info.info1.client_version = 0;
6582         info.info1.unknown2 = 0;
6583 
6584         r5.in.system_name = "";
6585         r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6586         r5.in.level_in = 1;
6587         r5.out.level_out = &level_out;
6588         r5.in.info_in = &info;
6589         r5.out.info_out = &info;
6590         r5.out.connect_handle = &h;
6591 
6592         status = dcerpc_samr_Connect5(p, tctx, &r5);
6593         if (!NT_STATUS_IS_OK(status)) {
6594                 printf("Connect5 failed - %s\n", nt_errstr(status));
6595                 ret = false;
6596         } else {
6597                 if (got_handle) {
6598                         test_samr_handle_Close(p, tctx, handle);
6599                 }
6600                 got_handle = true;
6601                 *handle = h;
6602         }
6603 
6604         return ret;
6605 }
6606 
6607 
6608 bool torture_rpc_samr(struct torture_context *torture)
     /* [<][>][^][v][top][bottom][index][help] */
6609 {
6610         NTSTATUS status;
6611         struct dcerpc_pipe *p;
6612         bool ret = true;
6613         struct policy_handle handle;
6614 
6615         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6616         if (!NT_STATUS_IS_OK(status)) {
6617                 return false;
6618         }
6619 
6620         ret &= test_Connect(p, torture, &handle);
6621 
6622         if (!torture_setting_bool(torture, "samba3", false)) {
6623                 ret &= test_QuerySecurity(p, torture, &handle);
6624         }
6625 
6626         ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_OTHER, NULL);
6627 
6628         ret &= test_SetDsrmPassword(p, torture, &handle);
6629 
6630         ret &= test_Shutdown(p, torture, &handle);
6631 
6632         ret &= test_samr_handle_Close(p, torture, &handle);
6633 
6634         return ret;
6635 }
6636 
6637 
6638 bool torture_rpc_samr_users(struct torture_context *torture)
     /* [<][>][^][v][top][bottom][index][help] */
6639 {
6640         NTSTATUS status;
6641         struct dcerpc_pipe *p;
6642         bool ret = true;
6643         struct policy_handle handle;
6644 
6645         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6646         if (!NT_STATUS_IS_OK(status)) {
6647                 return false;
6648         }
6649 
6650         ret &= test_Connect(p, torture, &handle);
6651 
6652         if (!torture_setting_bool(torture, "samba3", false)) {
6653                 ret &= test_QuerySecurity(p, torture, &handle);
6654         }
6655 
6656         ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_USER_ATTRIBUTES, NULL);
6657 
6658         ret &= test_SetDsrmPassword(p, torture, &handle);
6659 
6660         ret &= test_Shutdown(p, torture, &handle);
6661 
6662         ret &= test_samr_handle_Close(p, torture, &handle);
6663 
6664         return ret;
6665 }
6666 
6667 
6668 bool torture_rpc_samr_passwords(struct torture_context *torture)
     /* [<][>][^][v][top][bottom][index][help] */
6669 {
6670         NTSTATUS status;
6671         struct dcerpc_pipe *p;
6672         bool ret = true;
6673         struct policy_handle handle;
6674 
6675         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6676         if (!NT_STATUS_IS_OK(status)) {
6677                 return false;
6678         }
6679 
6680         ret &= test_Connect(p, torture, &handle);
6681 
6682         ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_PASSWORDS, NULL);
6683 
6684         ret &= test_samr_handle_Close(p, torture, &handle);
6685 
6686         return ret;
6687 }
6688 
6689 static bool torture_rpc_samr_pwdlastset(struct torture_context *torture,
     /* [<][>][^][v][top][bottom][index][help] */
6690                                         struct dcerpc_pipe *p2,
6691                                         struct cli_credentials *machine_credentials)
6692 {
6693         NTSTATUS status;
6694         struct dcerpc_pipe *p;
6695         bool ret = true;
6696         struct policy_handle handle;
6697 
6698         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6699         if (!NT_STATUS_IS_OK(status)) {
6700                 return false;
6701         }
6702 
6703         ret &= test_Connect(p, torture, &handle);
6704 
6705         ret &= test_EnumDomains(p, torture, &handle,
6706                                 TORTURE_SAMR_PASSWORDS_PWDLASTSET,
6707                                 machine_credentials);
6708 
6709         ret &= test_samr_handle_Close(p, torture, &handle);
6710 
6711         return ret;
6712 }
6713 
6714 struct torture_suite *torture_rpc_samr_passwords_pwdlastset(TALLOC_CTX *mem_ctx)
     /* [<][>][^][v][top][bottom][index][help] */
6715 {
6716         struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-PASSWORDS-PWDLASTSET");
6717         struct torture_rpc_tcase *tcase;
6718 
6719         tcase = torture_suite_add_machine_rpc_iface_tcase(suite, "samr",
6720                                                           &ndr_table_samr,
6721                                                           TEST_ACCOUNT_NAME_PWD);
6722 
6723         torture_rpc_tcase_add_test_creds(tcase, "pwdLastSet",
6724                                          torture_rpc_samr_pwdlastset);
6725 
6726         return suite;
6727 }
6728 
6729 static bool torture_rpc_samr_users_privileges_delete_user(struct torture_context *torture,
     /* [<][>][^][v][top][bottom][index][help] */
6730                                                           struct dcerpc_pipe *p2,
6731                                                           struct cli_credentials *machine_credentials)
6732 {
6733         NTSTATUS status;
6734         struct dcerpc_pipe *p;
6735         bool ret = true;
6736         struct policy_handle handle;
6737 
6738         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6739         if (!NT_STATUS_IS_OK(status)) {
6740                 return false;
6741         }
6742 
6743         ret &= test_Connect(p, torture, &handle);
6744 
6745         ret &= test_EnumDomains(p, torture, &handle,
6746                                 TORTURE_SAMR_USER_PRIVILEGES,
6747                                 machine_credentials);
6748 
6749         ret &= test_samr_handle_Close(p, torture, &handle);
6750 
6751         return ret;
6752 }
6753 
6754 struct torture_suite *torture_rpc_samr_user_privileges(TALLOC_CTX *mem_ctx)
     /* [<][>][^][v][top][bottom][index][help] */
6755 {
6756         struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-USERS-PRIVILEGES");
6757         struct torture_rpc_tcase *tcase;
6758 
6759         tcase = torture_suite_add_machine_rpc_iface_tcase(suite, "samr",
6760                                                           &ndr_table_samr,
6761                                                           TEST_ACCOUNT_NAME_PWD);
6762 
6763         torture_rpc_tcase_add_test_creds(tcase, "delete_privileged_user",
6764                                          torture_rpc_samr_users_privileges_delete_user);
6765 
6766         return suite;
6767 }
6768 
6769 static bool torture_rpc_samr_many_accounts(struct torture_context *torture,
     /* [<][>][^][v][top][bottom][index][help] */
6770                                            struct dcerpc_pipe *p2,
6771                                            struct cli_credentials *machine_credentials)
6772 {
6773         NTSTATUS status;
6774         struct dcerpc_pipe *p;
6775         bool ret = true;
6776         struct policy_handle handle;
6777 
6778         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6779         if (!NT_STATUS_IS_OK(status)) {
6780                 return false;
6781         }
6782 
6783         ret &= test_Connect(p, torture, &handle);
6784 
6785         ret &= test_EnumDomains(p, torture, &handle,
6786                                 TORTURE_SAMR_MANY_ACCOUNTS,
6787                                 machine_credentials);
6788 
6789         ret &= test_samr_handle_Close(p, torture, &handle);
6790 
6791         return ret;
6792 }
6793 
6794 static bool torture_rpc_samr_many_groups(struct torture_context *torture,
     /* [<][>][^][v][top][bottom][index][help] */
6795                                          struct dcerpc_pipe *p2,
6796                                          struct cli_credentials *machine_credentials)
6797 {
6798         NTSTATUS status;
6799         struct dcerpc_pipe *p;
6800         bool ret = true;
6801         struct policy_handle handle;
6802 
6803         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6804         if (!NT_STATUS_IS_OK(status)) {
6805                 return false;
6806         }
6807 
6808         ret &= test_Connect(p, torture, &handle);
6809 
6810         ret &= test_EnumDomains(p, torture, &handle,
6811                                 TORTURE_SAMR_MANY_GROUPS,
6812                                 machine_credentials);
6813 
6814         ret &= test_samr_handle_Close(p, torture, &handle);
6815 
6816         return ret;
6817 }
6818 
6819 static bool torture_rpc_samr_many_aliases(struct torture_context *torture,
     /* [<][>][^][v][top][bottom][index][help] */
6820                                           struct dcerpc_pipe *p2,
6821                                           struct cli_credentials *machine_credentials)
6822 {
6823         NTSTATUS status;
6824         struct dcerpc_pipe *p;
6825         bool ret = true;
6826         struct policy_handle handle;
6827 
6828         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6829         if (!NT_STATUS_IS_OK(status)) {
6830                 return false;
6831         }
6832 
6833         ret &= test_Connect(p, torture, &handle);
6834 
6835         ret &= test_EnumDomains(p, torture, &handle,
6836                                 TORTURE_SAMR_MANY_ALIASES,
6837                                 machine_credentials);
6838 
6839         ret &= test_samr_handle_Close(p, torture, &handle);
6840 
6841         return ret;
6842 }
6843 
6844 struct torture_suite *torture_rpc_samr_large_dc(TALLOC_CTX *mem_ctx)
     /* [<][>][^][v][top][bottom][index][help] */
6845 {
6846         struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-LARGE-DC");
6847         struct torture_rpc_tcase *tcase;
6848 
6849         tcase = torture_suite_add_machine_rpc_iface_tcase(suite, "samr",
6850                                                           &ndr_table_samr,
6851                                                           TEST_ACCOUNT_NAME);
6852 
6853         torture_rpc_tcase_add_test_creds(tcase, "many_aliases",
6854                                          torture_rpc_samr_many_aliases);
6855         torture_rpc_tcase_add_test_creds(tcase, "many_groups",
6856                                          torture_rpc_samr_many_groups);
6857         torture_rpc_tcase_add_test_creds(tcase, "many_accounts",
6858                                          torture_rpc_samr_many_accounts);
6859 
6860         return suite;
6861 }

/* [<][>][^][v][top][bottom][index][help] */