LCOV - code coverage report
Current view: top level - source4/torture/rpc - samr.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 3244 4130 78.5 %
Date: 2021-09-23 10:06:22 Functions: 118 127 92.9 %

          Line data    Source code
       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) Jelmer Vernooij 2005-2007
       8             :    Copyright (C) Guenther Deschner 2008-2010
       9             : 
      10             :    This program is free software; you can redistribute it and/or modify
      11             :    it under the terms of the GNU General Public License as published by
      12             :    the Free Software Foundation; either version 3 of the License, or
      13             :    (at your option) any later version.
      14             : 
      15             :    This program is distributed in the hope that it will be useful,
      16             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      17             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      18             :    GNU General Public License for more details.
      19             : 
      20             :    You should have received a copy of the GNU General Public License
      21             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      22             : */
      23             : 
      24             : #include "includes.h"
      25             : #include "torture/torture.h"
      26             : #include <tevent.h>
      27             : #include "system/time.h"
      28             : #include "system/network.h"
      29             : #include "librpc/gen_ndr/lsa.h"
      30             : #include "librpc/gen_ndr/ndr_netlogon.h"
      31             : #include "librpc/gen_ndr/ndr_netlogon_c.h"
      32             : #include "librpc/gen_ndr/ndr_samr_c.h"
      33             : #include "librpc/gen_ndr/ndr_lsa_c.h"
      34             : #include "lib/crypto/crypto.h"
      35             : #include "libcli/auth/libcli_auth.h"
      36             : #include "libcli/security/security.h"
      37             : #include "torture/rpc/torture_rpc.h"
      38             : #include "param/param.h"
      39             : #include "auth/gensec/gensec.h"
      40             : #include "auth/gensec/gensec_proto.h"
      41             : #include "../libcli/auth/schannel.h"
      42             : #include "torture/util.h"
      43             : #include "source4/librpc/rpc/dcerpc.h"
      44             : #include "source3/rpc_client/init_samr.h"
      45             : #include "lib/crypto/gnutls_helpers.h"
      46             : 
      47             : #undef strcasecmp
      48             : 
      49             : #define TEST_ACCOUNT_NAME "samrtorturetest"
      50             : #define TEST_ACCOUNT_NAME_PWD "samrpwdlastset"
      51             : #define TEST_ALIASNAME "samrtorturetestalias"
      52             : #define TEST_GROUPNAME "samrtorturetestgroup"
      53             : #define TEST_MACHINENAME "samrtestmach$"
      54             : #define TEST_DOMAINNAME "samrtestdom$"
      55             : 
      56             : #include <gnutls/gnutls.h>
      57             : #include <gnutls/crypto.h>
      58             : 
      59             : enum torture_samr_choice {
      60             :         TORTURE_SAMR_PASSWORDS,
      61             :         TORTURE_SAMR_PASSWORDS_PWDLASTSET,
      62             :         TORTURE_SAMR_PASSWORDS_BADPWDCOUNT,
      63             :         TORTURE_SAMR_PASSWORDS_LOCKOUT,
      64             :         TORTURE_SAMR_USER_ATTRIBUTES,
      65             :         TORTURE_SAMR_USER_PRIVILEGES,
      66             :         TORTURE_SAMR_OTHER,
      67             :         TORTURE_SAMR_MANY_ACCOUNTS,
      68             :         TORTURE_SAMR_MANY_GROUPS,
      69             :         TORTURE_SAMR_MANY_ALIASES
      70             : };
      71             : 
      72             : struct torture_samr_context {
      73             :         struct policy_handle handle;
      74             :         struct cli_credentials *machine_credentials;
      75             :         enum torture_samr_choice choice;
      76             :         uint32_t num_objects_large_dc;
      77             : };
      78             : 
      79             : static bool test_QueryUserInfo(struct dcerpc_binding_handle *b,
      80             :                                struct torture_context *tctx,
      81             :                                struct policy_handle *handle);
      82             : 
      83             : static bool test_QueryUserInfo2(struct dcerpc_binding_handle *b,
      84             :                                 struct torture_context *tctx,
      85             :                                 struct policy_handle *handle);
      86             : 
      87             : static bool test_QueryAliasInfo(struct dcerpc_binding_handle *b,
      88             :                                 struct torture_context *tctx,
      89             :                                 struct policy_handle *handle);
      90             : 
      91             : static bool test_ChangePassword(struct dcerpc_pipe *p,
      92             :                                 struct torture_context *tctx,
      93             :                                 const char *acct_name,
      94             :                                 struct policy_handle *domain_handle, char **password);
      95             : 
      96       10831 : static void init_lsa_String(struct lsa_String *string, const char *s)
      97             : {
      98       10831 :         string->string = s;
      99       10831 : }
     100             : 
     101          32 : static void init_lsa_StringLarge(struct lsa_StringLarge *string, const char *s)
     102             : {
     103          32 :         string->string = s;
     104          32 : }
     105             : 
     106         192 : static void init_lsa_BinaryString(struct lsa_BinaryString *string, const char *s, uint32_t length)
     107             : {
     108         192 :         string->length = length;
     109         192 :         string->size = length;
     110         192 :         string->array = (uint16_t *)discard_const(s);
     111         192 : }
     112             : 
     113        4139 : bool test_samr_handle_Close(struct dcerpc_binding_handle *b,
     114             :                             struct torture_context *tctx,
     115             :                             struct policy_handle *handle)
     116             : {
     117             :         struct samr_Close r;
     118             : 
     119        4139 :         r.in.handle = handle;
     120        4139 :         r.out.handle = handle;
     121             : 
     122        4139 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_Close_r(b, tctx, &r),
     123             :                 "Close failed");
     124        4139 :         torture_assert_ntstatus_ok(tctx, r.out.result, "Close failed");
     125             : 
     126        4139 :         return true;
     127             : }
     128             : 
     129          14 : static bool test_Shutdown(struct dcerpc_binding_handle *b,
     130             :                           struct torture_context *tctx,
     131             :                           struct policy_handle *handle)
     132             : {
     133             :         struct samr_Shutdown r;
     134             : 
     135          14 :         if (!torture_setting_bool(tctx, "dangerous", false)) {
     136          14 :                 torture_skip(tctx, "samr_Shutdown disabled - enable dangerous tests to use\n");
     137             :                 return true;
     138             :         }
     139             : 
     140           0 :         r.in.connect_handle = handle;
     141             : 
     142           0 :         torture_comment(tctx, "Testing samr_Shutdown\n");
     143             : 
     144           0 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_Shutdown_r(b, tctx, &r),
     145             :                 "Shutdown failed");
     146           0 :         torture_assert_ntstatus_ok(tctx, r.out.result, "Shutdown failed");
     147             : 
     148           0 :         return true;
     149             : }
     150             : 
     151          14 : static bool test_SetDsrmPassword(struct dcerpc_binding_handle *b,
     152             :                                  struct torture_context *tctx,
     153             :                                  struct policy_handle *handle)
     154             : {
     155             :         struct samr_SetDsrmPassword r;
     156             :         struct lsa_String string;
     157             :         struct samr_Password hash;
     158             : 
     159          14 :         if (!torture_setting_bool(tctx, "dangerous", false)) {
     160          14 :                 torture_skip(tctx, "samr_SetDsrmPassword disabled - enable dangerous tests to use");
     161             :         }
     162             : 
     163           0 :         E_md4hash("TeSTDSRM123", hash.hash);
     164             : 
     165           0 :         init_lsa_String(&string, "Administrator");
     166             : 
     167           0 :         r.in.name = &string;
     168           0 :         r.in.unknown = 0;
     169           0 :         r.in.hash = &hash;
     170             : 
     171           0 :         torture_comment(tctx, "Testing samr_SetDsrmPassword\n");
     172             : 
     173           0 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDsrmPassword_r(b, tctx, &r),
     174             :                 "SetDsrmPassword failed");
     175           0 :         torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_SUPPORTED, "SetDsrmPassword failed");
     176             : 
     177           0 :         return true;
     178             : }
     179             : 
     180             : 
     181         149 : static bool test_QuerySecurity(struct dcerpc_binding_handle *b,
     182             :                                struct torture_context *tctx,
     183             :                                struct policy_handle *handle)
     184             : {
     185             :         struct samr_QuerySecurity r;
     186             :         struct samr_SetSecurity s;
     187         149 :         struct sec_desc_buf *sdbuf = NULL;
     188             : 
     189         149 :         r.in.handle = handle;
     190         149 :         r.in.sec_info = 7;
     191         149 :         r.out.sdbuf = &sdbuf;
     192             : 
     193         149 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_QuerySecurity_r(b, tctx, &r),
     194             :                 "QuerySecurity failed");
     195         149 :         torture_assert_ntstatus_ok(tctx, r.out.result, "QuerySecurity failed");
     196             : 
     197         149 :         torture_assert(tctx, sdbuf != NULL, "sdbuf is NULL");
     198             : 
     199         149 :         s.in.handle = handle;
     200         149 :         s.in.sec_info = 7;
     201         149 :         s.in.sdbuf = sdbuf;
     202             : 
     203         149 :         if (torture_setting_bool(tctx, "samba4", false)) {
     204         143 :                 torture_skip(tctx, "skipping SetSecurity test against Samba4\n");
     205             :         }
     206             : 
     207           6 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetSecurity_r(b, tctx, &s),
     208             :                 "SetSecurity failed");
     209           4 :         torture_assert_ntstatus_ok(tctx, r.out.result, "SetSecurity failed");
     210             : 
     211           4 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_QuerySecurity_r(b, tctx, &r),
     212             :                 "QuerySecurity failed");
     213           4 :         torture_assert_ntstatus_ok(tctx, r.out.result, "QuerySecurity failed");
     214             : 
     215           4 :         return true;
     216             : }
     217             : 
     218             : 
     219          16 : static bool test_SetUserInfo(struct dcerpc_binding_handle *b, struct torture_context *tctx,
     220             :                              struct policy_handle *handle, uint32_t base_acct_flags,
     221             :                              const char *base_account_name)
     222             : {
     223             :         struct samr_SetUserInfo s;
     224             :         struct samr_SetUserInfo2 s2;
     225             :         struct samr_QueryUserInfo q;
     226             :         struct samr_QueryUserInfo q0;
     227             :         union samr_UserInfo u;
     228             :         union samr_UserInfo *info;
     229          16 :         bool ret = true;
     230             :         const char *test_account_name;
     231             : 
     232          16 :         uint32_t user_extra_flags = 0;
     233             : 
     234          16 :         if (!torture_setting_bool(tctx, "samba3", false)) {
     235          12 :                 if (base_acct_flags == ACB_NORMAL) {
     236             :                         /* When created, accounts are expired by default */
     237           6 :                         user_extra_flags = ACB_PW_EXPIRED;
     238             :                 }
     239             :         }
     240             : 
     241          16 :         s.in.user_handle = handle;
     242          16 :         s.in.info = &u;
     243             : 
     244          16 :         s2.in.user_handle = handle;
     245          16 :         s2.in.info = &u;
     246             : 
     247          16 :         q.in.user_handle = handle;
     248          16 :         q.out.info = &info;
     249          16 :         q0 = q;
     250             : 
     251             : #define TESTCALL(call, r) \
     252             :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ ##call## _r(b, tctx, &r),\
     253             :                         #call " failed"); \
     254             :                 if (!NT_STATUS_IS_OK(r.out.result)) { \
     255             :                         torture_result(tctx, TORTURE_FAIL, #call " level %u failed - %s (%s)\n", \
     256             :                                r.in.level, nt_errstr(r.out.result), __location__); \
     257             :                         ret = false; \
     258             :                         break; \
     259             :                 }
     260             : 
     261             : #define STRING_EQUAL(s1, s2, field) \
     262             :         torture_assert_str_equal(tctx, s1, s2, "Failed to set " #field)
     263             : 
     264             : #define MEM_EQUAL(s1, s2, length, field) \
     265             :         torture_assert_mem_equal(tctx, s1, s2, length, "Failed to set " #field)
     266             : 
     267             : #define INT_EQUAL(i1, i2, field) \
     268             :         torture_assert_int_equal(tctx, i1, i2, "Failed to set " #field)
     269             : 
     270             : #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
     271             :                 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
     272             :                 q.in.level = lvl1; \
     273             :                 TESTCALL(QueryUserInfo, q) \
     274             :                 s.in.level = lvl1; \
     275             :                 s2.in.level = lvl1; \
     276             :                 u = *info; \
     277             :                 if (lvl1 == 21) { \
     278             :                         ZERO_STRUCT(u.info21); \
     279             :                         u.info21.fields_present = fpval; \
     280             :                 } \
     281             :                 init_lsa_String(&u.info ## lvl1.field1, value); \
     282             :                 TESTCALL(SetUserInfo, s) \
     283             :                 TESTCALL(SetUserInfo2, s2) \
     284             :                 init_lsa_String(&u.info ## lvl1.field1, ""); \
     285             :                 TESTCALL(QueryUserInfo, q); \
     286             :                 u = *info; \
     287             :                 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
     288             :                 q.in.level = lvl2; \
     289             :                 TESTCALL(QueryUserInfo, q) \
     290             :                 u = *info; \
     291             :                 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
     292             :         } while (0)
     293             : 
     294             : #define TEST_USERINFO_BINARYSTRING(lvl1, field1, lvl2, field2, value, fpval) do { \
     295             :                 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
     296             :                 q.in.level = lvl1; \
     297             :                 TESTCALL(QueryUserInfo, q) \
     298             :                 s.in.level = lvl1; \
     299             :                 s2.in.level = lvl1; \
     300             :                 u = *info; \
     301             :                 if (lvl1 == 21) { \
     302             :                         ZERO_STRUCT(u.info21); \
     303             :                         u.info21.fields_present = fpval; \
     304             :                 } \
     305             :                 init_lsa_BinaryString(&u.info ## lvl1.field1, value, strlen(value)); \
     306             :                 TESTCALL(SetUserInfo, s) \
     307             :                 TESTCALL(SetUserInfo2, s2) \
     308             :                 init_lsa_BinaryString(&u.info ## lvl1.field1, "", 1); \
     309             :                 TESTCALL(QueryUserInfo, q); \
     310             :                 u = *info; \
     311             :                 MEM_EQUAL(u.info ## lvl1.field1.array, value, strlen(value), field1); \
     312             :                 q.in.level = lvl2; \
     313             :                 TESTCALL(QueryUserInfo, q) \
     314             :                 u = *info; \
     315             :                 MEM_EQUAL(u.info ## lvl2.field2.array, value, strlen(value), field2); \
     316             :         } while (0)
     317             : 
     318             : #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
     319             :                 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
     320             :                 q.in.level = lvl1; \
     321             :                 TESTCALL(QueryUserInfo, q) \
     322             :                 s.in.level = lvl1; \
     323             :                 s2.in.level = lvl1; \
     324             :                 u = *info; \
     325             :                 if (lvl1 == 21) { \
     326             :                         uint8_t *bits = u.info21.logon_hours.bits; \
     327             :                         ZERO_STRUCT(u.info21); \
     328             :                         if (fpval == SAMR_FIELD_LOGON_HOURS) { \
     329             :                                 u.info21.logon_hours.units_per_week = 168; \
     330             :                                 u.info21.logon_hours.bits = bits; \
     331             :                         } \
     332             :                         u.info21.fields_present = fpval; \
     333             :                 } \
     334             :                 u.info ## lvl1.field1 = value; \
     335             :                 TESTCALL(SetUserInfo, s) \
     336             :                 TESTCALL(SetUserInfo2, s2) \
     337             :                 u.info ## lvl1.field1 = 0; \
     338             :                 TESTCALL(QueryUserInfo, q); \
     339             :                 u = *info; \
     340             :                 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
     341             :                 q.in.level = lvl2; \
     342             :                 TESTCALL(QueryUserInfo, q) \
     343             :                 u = *info; \
     344             :                 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
     345             :         } while (0)
     346             : 
     347             : #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
     348             :         TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
     349             :         } while (0)
     350             : 
     351          16 :         q0.in.level = 12;
     352          16 :         do { TESTCALL(QueryUserInfo, q0) } while (0);
     353             : 
     354          16 :         TEST_USERINFO_STRING(2, comment,  1, comment, "xx2-1 comment", 0);
     355          16 :         TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
     356          16 :         TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
     357             :                            SAMR_FIELD_COMMENT);
     358             : 
     359          16 :         test_account_name = talloc_asprintf(tctx, "%sxx7-1", base_account_name);
     360          16 :         TEST_USERINFO_STRING(7, account_name,  1, account_name, test_account_name, 0);
     361          16 :         test_account_name = talloc_asprintf(tctx, "%sxx7-3", base_account_name);
     362          16 :         TEST_USERINFO_STRING(7, account_name,  3, account_name, test_account_name, 0);
     363          16 :         test_account_name = talloc_asprintf(tctx, "%sxx7-5", base_account_name);
     364          16 :         TEST_USERINFO_STRING(7, account_name,  5, account_name, test_account_name, 0);
     365          16 :         test_account_name = talloc_asprintf(tctx, "%sxx7-6", base_account_name);
     366          16 :         TEST_USERINFO_STRING(7, account_name,  6, account_name, test_account_name, 0);
     367          16 :         test_account_name = talloc_asprintf(tctx, "%sxx7-7", base_account_name);
     368          16 :         TEST_USERINFO_STRING(7, account_name,  7, account_name, test_account_name, 0);
     369          16 :         test_account_name = talloc_asprintf(tctx, "%sxx7-21", base_account_name);
     370          16 :         TEST_USERINFO_STRING(7, account_name, 21, account_name, test_account_name, 0);
     371          16 :         test_account_name = base_account_name;
     372          16 :         TEST_USERINFO_STRING(21, account_name, 21, account_name, test_account_name,
     373             :                            SAMR_FIELD_ACCOUNT_NAME);
     374             : 
     375          16 :         TEST_USERINFO_STRING(6, full_name,  1, full_name, "xx6-1 full_name", 0);
     376          16 :         TEST_USERINFO_STRING(6, full_name,  3, full_name, "xx6-3 full_name", 0);
     377          16 :         TEST_USERINFO_STRING(6, full_name,  5, full_name, "xx6-5 full_name", 0);
     378          16 :         TEST_USERINFO_STRING(6, full_name,  6, full_name, "xx6-6 full_name", 0);
     379          16 :         TEST_USERINFO_STRING(6, full_name,  8, full_name, "xx6-8 full_name", 0);
     380          16 :         TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
     381          16 :         TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
     382          16 :         TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
     383             :                            SAMR_FIELD_FULL_NAME);
     384             : 
     385          16 :         TEST_USERINFO_STRING(6, full_name,  1, full_name, "", 0);
     386          16 :         TEST_USERINFO_STRING(6, full_name,  3, full_name, "", 0);
     387          16 :         TEST_USERINFO_STRING(6, full_name,  5, full_name, "", 0);
     388          16 :         TEST_USERINFO_STRING(6, full_name,  6, full_name, "", 0);
     389          16 :         TEST_USERINFO_STRING(6, full_name,  8, full_name, "", 0);
     390          16 :         TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
     391          16 :         TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
     392          16 :         TEST_USERINFO_STRING(21, full_name, 21, full_name, "",
     393             :                            SAMR_FIELD_FULL_NAME);
     394             : 
     395          16 :         TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
     396          16 :         TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
     397          16 :         TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
     398          16 :         TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
     399             :                            SAMR_FIELD_LOGON_SCRIPT);
     400             : 
     401          16 :         TEST_USERINFO_STRING(12, profile_path,  3, profile_path, "xx12-3 profile_path", 0);
     402          16 :         TEST_USERINFO_STRING(12, profile_path,  5, profile_path, "xx12-5 profile_path", 0);
     403          16 :         TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
     404          16 :         TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
     405             :                            SAMR_FIELD_PROFILE_PATH);
     406             : 
     407          16 :         TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
     408          16 :         TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
     409          16 :         TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
     410          16 :         TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
     411             :                              SAMR_FIELD_HOME_DIRECTORY);
     412          16 :         TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
     413             :                              SAMR_FIELD_HOME_DIRECTORY);
     414             : 
     415          16 :         TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
     416          16 :         TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
     417          16 :         TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
     418          16 :         TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
     419             :                              SAMR_FIELD_HOME_DRIVE);
     420          16 :         TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
     421             :                              SAMR_FIELD_HOME_DRIVE);
     422             : 
     423          16 :         TEST_USERINFO_STRING(13, description,  1, description, "xx13-1 description", 0);
     424          16 :         TEST_USERINFO_STRING(13, description,  5, description, "xx13-5 description", 0);
     425          16 :         TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
     426          16 :         TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
     427             :                            SAMR_FIELD_DESCRIPTION);
     428             : 
     429          16 :         TEST_USERINFO_STRING(14, workstations,  3, workstations, "14workstation3", 0);
     430          16 :         TEST_USERINFO_STRING(14, workstations,  5, workstations, "14workstation4", 0);
     431          16 :         TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
     432          16 :         TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
     433             :                            SAMR_FIELD_WORKSTATIONS);
     434          16 :         TEST_USERINFO_STRING(21, workstations, 3, workstations, "21workstation3",
     435             :                            SAMR_FIELD_WORKSTATIONS);
     436          16 :         TEST_USERINFO_STRING(21, workstations, 5, workstations, "21workstation5",
     437             :                            SAMR_FIELD_WORKSTATIONS);
     438          16 :         TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14",
     439             :                            SAMR_FIELD_WORKSTATIONS);
     440             : 
     441          16 :         TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
     442          16 :         TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "xx21-21 parameters",
     443             :                            SAMR_FIELD_PARAMETERS);
     444          16 :         TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "xx21-20 parameters",
     445             :                            SAMR_FIELD_PARAMETERS);
     446             :         /* also empty user parameters are allowed */
     447          16 :         TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "", 0);
     448          16 :         TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "",
     449             :                            SAMR_FIELD_PARAMETERS);
     450          16 :         TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "",
     451             :                            SAMR_FIELD_PARAMETERS);
     452             : 
     453             :         /* Samba 3 cannot store country_code and code_page atm. - gd */
     454          16 :         if (!torture_setting_bool(tctx, "samba3", false)) {
     455          12 :                 TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
     456          12 :                 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
     457          12 :                 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
     458             :                                   SAMR_FIELD_COUNTRY_CODE);
     459          12 :                 TEST_USERINFO_INT(21, country_code, 2, country_code, __LINE__,
     460             :                                   SAMR_FIELD_COUNTRY_CODE);
     461             : 
     462          12 :                 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
     463          12 :                 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
     464             :                                   SAMR_FIELD_CODE_PAGE);
     465          12 :                 TEST_USERINFO_INT(21, code_page, 2, code_page, __LINE__,
     466             :                                   SAMR_FIELD_CODE_PAGE);
     467             :         }
     468             : 
     469          16 :         if (!torture_setting_bool(tctx, "samba3", false)) {
     470          12 :                 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
     471          12 :                 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
     472          12 :                 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__,
     473             :                                   SAMR_FIELD_ACCT_EXPIRY);
     474          12 :                 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, __LINE__,
     475             :                                   SAMR_FIELD_ACCT_EXPIRY);
     476          12 :                 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, __LINE__,
     477             :                                   SAMR_FIELD_ACCT_EXPIRY);
     478             :         } else {
     479             :                 /* Samba 3 can only store seconds / time_t in passdb - gd */
     480             :                 NTTIME nt;
     481           4 :                 unix_to_nt_time(&nt, time(NULL) + __LINE__);
     482           4 :                 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, nt, 0);
     483           4 :                 unix_to_nt_time(&nt, time(NULL) + __LINE__);
     484           4 :                 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, nt, 0);
     485           4 :                 unix_to_nt_time(&nt, time(NULL) + __LINE__);
     486           4 :                 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
     487           4 :                 unix_to_nt_time(&nt, time(NULL) + __LINE__);
     488           4 :                 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
     489           4 :                 unix_to_nt_time(&nt, time(NULL) + __LINE__);
     490           4 :                 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
     491             :         }
     492             : 
     493          16 :         TEST_USERINFO_INT(4, logon_hours.bits[3],  3, logon_hours.bits[3], 1, 0);
     494          16 :         TEST_USERINFO_INT(4, logon_hours.bits[3],  5, logon_hours.bits[3], 2, 0);
     495          16 :         TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
     496          16 :         TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
     497             :                           SAMR_FIELD_LOGON_HOURS);
     498             : 
     499          16 :         TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
     500             :                               (base_acct_flags  | ACB_DISABLED | ACB_HOMDIRREQ),
     501             :                               (base_acct_flags  | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
     502             :                               0);
     503          14 :         TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
     504             :                               (base_acct_flags  | ACB_DISABLED),
     505             :                               (base_acct_flags  | ACB_DISABLED | user_extra_flags),
     506             :                               0);
     507             : 
     508             :         /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
     509          14 :         TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
     510             :                               (base_acct_flags  | ACB_DISABLED | ACB_PWNOEXP),
     511             :                               (base_acct_flags  | ACB_DISABLED | ACB_PWNOEXP),
     512             :                               0);
     513          14 :         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
     514             :                               (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
     515             :                               (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
     516             :                               0);
     517             : 
     518             : 
     519             :         /* The 'autolock' flag doesn't stick - check this */
     520          14 :         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
     521             :                               (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
     522             :                               (base_acct_flags | ACB_DISABLED | user_extra_flags),
     523             :                               0);
     524             : #if 0
     525             :         /* Removing the 'disabled' flag doesn't stick - check this */
     526             :         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
     527             :                               (base_acct_flags),
     528             :                               (base_acct_flags | ACB_DISABLED | user_extra_flags),
     529             :                               0);
     530             : #endif
     531             : 
     532             :         /* Samba3 cannot store these atm */
     533          14 :         if (!torture_setting_bool(tctx, "samba3", false)) {
     534             :                 /* The 'store plaintext' flag does stick */
     535          12 :                 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
     536             :                                       (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
     537             :                                       (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
     538             :                                       0);
     539             :                 /* The 'use DES' flag does stick */
     540          12 :                 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
     541             :                                       (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
     542             :                                       (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
     543             :                                       0);
     544             :                 /* The 'don't require kerberos pre-authentication flag does stick */
     545          12 :                 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
     546             :                                       (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
     547             :                                       (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
     548             :                                       0);
     549             :                 /* The 'no kerberos PAC required' flag sticks */
     550          12 :                 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
     551             :                                       (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
     552             :                                       (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
     553             :                                       0);
     554             :         }
     555          14 :         TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
     556             :                               (base_acct_flags | ACB_DISABLED),
     557             :                               (base_acct_flags | ACB_DISABLED | user_extra_flags),
     558             :                               SAMR_FIELD_ACCT_FLAGS);
     559             : 
     560             : #if 0
     561             :         /* these fail with win2003 - it appears you can't set the primary gid?
     562             :            the set succeeds, but the gid isn't changed. Very weird! */
     563             :         TEST_USERINFO_INT(9, primary_gid,  1, primary_gid, 513);
     564             :         TEST_USERINFO_INT(9, primary_gid,  3, primary_gid, 513);
     565             :         TEST_USERINFO_INT(9, primary_gid,  5, primary_gid, 513);
     566             :         TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
     567             : #endif
     568             : 
     569          14 :         return ret;
     570             : }
     571             : 
     572             : /*
     573             :   generate a random password for password change tests
     574             : */
     575        1294 : static char *samr_rand_pass_silent(TALLOC_CTX *mem_ctx, int min_len)
     576             : {
     577        1294 :         size_t len = MAX(8, min_len);
     578        1294 :         char *s = generate_random_password(mem_ctx, len, len+6);
     579        1294 :         return s;
     580             : }
     581             : 
     582         686 : static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
     583             : {
     584         686 :         char *s = samr_rand_pass_silent(mem_ctx, min_len);
     585         686 :         printf("Generated password '%s'\n", s);
     586         686 :         return s;
     587             : 
     588             : }
     589             : 
     590             : /*
     591             :   generate a random password for password change tests
     592             : */
     593           4 : static DATA_BLOB samr_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
     594             : {
     595             :         int i;
     596           4 :         DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
     597           4 :         generate_random_buffer(password.data, password.length);
     598             : 
     599         516 :         for (i=0; i < len; i++) {
     600         512 :                 if (((uint16_t *)password.data)[i] == 0) {
     601           0 :                         ((uint16_t *)password.data)[i] = 1;
     602             :                 }
     603             :         }
     604             : 
     605           4 :         return password;
     606             : }
     607             : 
     608             : /*
     609             :   generate a random password for password change tests (fixed length)
     610             : */
     611          22 : static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
     612             : {
     613          22 :         char *s = generate_random_password(mem_ctx, len, len);
     614          22 :         printf("Generated password '%s'\n", s);
     615          22 :         return s;
     616             : }
     617             : 
     618         358 : static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx,
     619             :                              struct policy_handle *handle, char **password)
     620             : {
     621             :         NTSTATUS status;
     622             :         struct samr_SetUserInfo s;
     623             :         union samr_UserInfo u;
     624         358 :         bool ret = true;
     625             :         DATA_BLOB session_key;
     626             :         char *newpass;
     627         358 :         struct dcerpc_binding_handle *b = p->binding_handle;
     628             :         struct samr_GetUserPwInfo pwp;
     629             :         struct samr_PwInfo info;
     630         358 :         int policy_min_pw_len = 0;
     631         358 :         pwp.in.user_handle = handle;
     632         358 :         pwp.out.info = &info;
     633             : 
     634         358 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
     635             :                 "GetUserPwInfo failed");
     636         358 :         if (NT_STATUS_IS_OK(pwp.out.result)) {
     637         358 :                 policy_min_pw_len = pwp.out.info->min_password_length;
     638             :         }
     639         358 :         newpass = samr_rand_pass(tctx, policy_min_pw_len);
     640             : 
     641         358 :         s.in.user_handle = handle;
     642         358 :         s.in.info = &u;
     643         358 :         s.in.level = 24;
     644             : 
     645         358 :         u.info24.password_expired = 0;
     646             : 
     647         358 :         status = dcerpc_fetch_session_key(p, &session_key);
     648         358 :         if (!NT_STATUS_IS_OK(status)) {
     649           0 :                 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u - no session key - %s\n",
     650           0 :                        s.in.level, nt_errstr(status));
     651           0 :                 return false;
     652             :         }
     653             : 
     654         358 :         status = init_samr_CryptPassword(newpass,
     655             :                                           &session_key,
     656             :                                           &u.info24.password);
     657         358 :         torture_assert_ntstatus_ok(tctx,
     658             :                                    status,
     659             :                                    "init_samr_CryptPassword failed");
     660             : 
     661         358 :         torture_comment(tctx, "Testing SetUserInfo level 24 (set password)\n");
     662             : 
     663         358 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
     664             :                 "SetUserInfo failed");
     665         358 :         torture_comment(tctx, "(%s:%s) new_password[%s] status[%s]\n",
     666             :                         __location__, __FUNCTION__,
     667             :                         newpass, nt_errstr(s.out.result));
     668         358 :         if (!NT_STATUS_IS_OK(s.out.result)) {
     669           0 :                 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u failed - %s\n",
     670           0 :                        s.in.level, nt_errstr(s.out.result));
     671           0 :                 ret = false;
     672             :         } else {
     673         358 :                 *password = newpass;
     674             :         }
     675             : 
     676         358 :         return ret;
     677             : }
     678             : 
     679             : 
     680          24 : static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *tctx,
     681             :                                 struct policy_handle *handle, uint32_t fields_present,
     682             :                                 char **password)
     683             : {
     684             :         NTSTATUS status;
     685             :         struct samr_SetUserInfo s;
     686             :         union samr_UserInfo u;
     687          24 :         bool ret = true;
     688             :         DATA_BLOB session_key;
     689          24 :         struct dcerpc_binding_handle *b = p->binding_handle;
     690             :         char *newpass;
     691             :         struct samr_GetUserPwInfo pwp;
     692             :         struct samr_PwInfo info;
     693          24 :         int policy_min_pw_len = 0;
     694          24 :         pwp.in.user_handle = handle;
     695          24 :         pwp.out.info = &info;
     696             : 
     697          24 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
     698             :                 "GetUserPwInfo failed");
     699          24 :         if (NT_STATUS_IS_OK(pwp.out.result)) {
     700          24 :                 policy_min_pw_len = pwp.out.info->min_password_length;
     701             :         }
     702          24 :         newpass = samr_rand_pass(tctx, policy_min_pw_len);
     703             : 
     704          24 :         s.in.user_handle = handle;
     705          24 :         s.in.info = &u;
     706          24 :         s.in.level = 23;
     707             : 
     708          24 :         ZERO_STRUCT(u);
     709             : 
     710          24 :         u.info23.info.fields_present = fields_present;
     711             : 
     712          24 :         status = dcerpc_fetch_session_key(p, &session_key);
     713          24 :         if (!NT_STATUS_IS_OK(status)) {
     714           0 :                 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u - no session key - %s\n",
     715           0 :                        s.in.level, nt_errstr(status));
     716           0 :                 return false;
     717             :         }
     718             : 
     719          24 :         status = init_samr_CryptPassword(newpass,
     720             :                                          &session_key,
     721             :                                          &u.info23.password);
     722          24 :         torture_assert_ntstatus_ok(tctx,
     723             :                                    status,
     724             :                                    "init_samr_CryptPassword failed");
     725             : 
     726          24 :         torture_comment(tctx, "Testing SetUserInfo level 23 (set password)\n");
     727             : 
     728          24 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
     729             :                 "SetUserInfo failed");
     730          24 :         torture_comment(tctx, "(%s:%s) new_password[%s] status[%s]\n",
     731             :                         __location__, __FUNCTION__,
     732             :                         newpass, nt_errstr(s.out.result));
     733          24 :         if (!NT_STATUS_IS_OK(s.out.result)) {
     734           0 :                 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u failed - %s\n",
     735           0 :                        s.in.level, nt_errstr(s.out.result));
     736           0 :                 ret = false;
     737             :         } else {
     738          24 :                 *password = newpass;
     739             :         }
     740             : 
     741          24 :         status = dcerpc_fetch_session_key(p, &session_key);
     742          24 :         if (!NT_STATUS_IS_OK(status)) {
     743           0 :                 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u - no session key - %s\n",
     744           0 :                        s.in.level, nt_errstr(status));
     745           0 :                 return false;
     746             :         }
     747             : 
     748             :         /* This should break the key nicely */
     749          24 :         session_key.data[0]++;
     750             : 
     751          24 :         status = init_samr_CryptPassword(newpass,
     752             :                                          &session_key,
     753             :                                          &u.info23.password);
     754          24 :         torture_assert_ntstatus_ok(tctx,
     755             :                                    status,
     756             :                                    "init_samr_CryptPassword failed");
     757             : 
     758             :         /* Reset the session key */
     759          24 :         session_key.data[0]--;
     760             : 
     761          24 :         torture_comment(tctx, "Testing SetUserInfo level 23 (set password) with wrong password\n");
     762             : 
     763          24 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
     764             :                 "SetUserInfo failed");
     765          24 :         torture_comment(tctx, "(%s:%s) new_password[%s] status[%s]\n",
     766             :                         __location__, __FUNCTION__,
     767             :                         newpass, nt_errstr(s.out.result));
     768          24 :         if (!NT_STATUS_EQUAL(s.out.result, NT_STATUS_WRONG_PASSWORD)) {
     769           0 :                 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
     770           0 :                        s.in.level, nt_errstr(s.out.result));
     771           0 :                 ret = false;
     772             :         }
     773             : 
     774          24 :         return ret;
     775             : }
     776             : 
     777             : 
     778          12 : static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tctx,
     779             :                                struct policy_handle *handle, bool makeshort,
     780             :                                char **password)
     781             : {
     782             :         NTSTATUS status;
     783             :         struct samr_SetUserInfo s;
     784             :         union samr_UserInfo u;
     785          12 :         bool ret = true;
     786             :         DATA_BLOB session_key;
     787             :         char *newpass;
     788          12 :         struct dcerpc_binding_handle *b = p->binding_handle;
     789             :         struct samr_GetUserPwInfo pwp;
     790             :         struct samr_PwInfo info;
     791          12 :         int policy_min_pw_len = 0;
     792             : 
     793          12 :         pwp.in.user_handle = handle;
     794          12 :         pwp.out.info = &info;
     795             : 
     796          12 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
     797             :                 "GetUserPwInfo failed");
     798          12 :         if (NT_STATUS_IS_OK(pwp.out.result)) {
     799          12 :                 policy_min_pw_len = pwp.out.info->min_password_length;
     800             :         }
     801          12 :         if (makeshort && policy_min_pw_len) {
     802           4 :                 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len - 1);
     803             :         } else {
     804           8 :                 newpass = samr_rand_pass(tctx, policy_min_pw_len);
     805             :         }
     806             : 
     807          12 :         s.in.user_handle = handle;
     808          12 :         s.in.info = &u;
     809          12 :         s.in.level = 26;
     810             : 
     811          12 :         u.info26.password_expired = 0;
     812             : 
     813          12 :         status = dcerpc_fetch_session_key(p, &session_key);
     814          12 :         if (!NT_STATUS_IS_OK(status)) {
     815           0 :                 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u - no session key - %s\n",
     816           0 :                        s.in.level, nt_errstr(status));
     817           0 :                 return false;
     818             :         }
     819             : 
     820          12 :         status = init_samr_CryptPasswordEx(newpass,
     821             :                                            &session_key,
     822             :                                            &u.info26.password);
     823          12 :         torture_assert_ntstatus_ok(tctx,
     824             :                                    status,
     825             :                                    "init_samr_CryptPasswordEx failed");
     826             : 
     827          12 :         torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex)\n");
     828             : 
     829          12 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
     830             :                 "SetUserInfo failed");
     831          12 :         torture_comment(tctx, "(%s:%s) new_password[%s] status[%s]\n",
     832             :                         __location__, __FUNCTION__,
     833             :                         newpass, nt_errstr(s.out.result));
     834          12 :         if (!NT_STATUS_IS_OK(s.out.result)) {
     835           0 :                 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u failed - %s\n",
     836           0 :                        s.in.level, nt_errstr(s.out.result));
     837           0 :                 ret = false;
     838             :         } else {
     839          12 :                 *password = newpass;
     840             :         }
     841             : 
     842             :         /* This should break the key nicely */
     843          12 :         session_key.data[0]++;
     844             : 
     845          12 :         status = init_samr_CryptPasswordEx(newpass,
     846             :                                            &session_key,
     847             :                                            &u.info26.password);
     848          12 :         torture_assert_ntstatus_ok(tctx,
     849             :                                    status,
     850             :                                    "init_samr_CryptPasswordEx failed");
     851             : 
     852             :         /* Reset the key */
     853          12 :         session_key.data[0]--;
     854             : 
     855          12 :         torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
     856             : 
     857          12 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
     858             :                 "SetUserInfo failed");
     859          12 :         torture_comment(tctx, "(%s:%s) new_password[%s] status[%s]\n",
     860             :                         __location__, __FUNCTION__,
     861             :                         newpass, nt_errstr(s.out.result));
     862          12 :         if (!NT_STATUS_EQUAL(s.out.result, NT_STATUS_WRONG_PASSWORD)) {
     863           0 :                 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
     864           0 :                        s.in.level, nt_errstr(s.out.result));
     865           0 :                 ret = false;
     866             :         } else {
     867          12 :                 *password = newpass;
     868             :         }
     869             : 
     870          12 :         return ret;
     871             : }
     872             : 
     873          24 : static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *tctx,
     874             :                                 struct policy_handle *handle, uint32_t fields_present,
     875             :                                 char **password)
     876             : {
     877             :         NTSTATUS status;
     878             :         struct samr_SetUserInfo s;
     879             :         union samr_UserInfo u;
     880          24 :         bool ret = true;
     881             :         DATA_BLOB session_key;
     882             :         char *newpass;
     883          24 :         struct dcerpc_binding_handle *b = p->binding_handle;
     884             :         struct samr_GetUserPwInfo pwp;
     885             :         struct samr_PwInfo info;
     886          24 :         int policy_min_pw_len = 0;
     887             : 
     888          24 :         pwp.in.user_handle = handle;
     889          24 :         pwp.out.info = &info;
     890             : 
     891          24 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
     892             :                 "GetUserPwInfo failed");
     893          24 :         if (NT_STATUS_IS_OK(pwp.out.result)) {
     894          24 :                 policy_min_pw_len = pwp.out.info->min_password_length;
     895             :         }
     896          24 :         newpass = samr_rand_pass(tctx, policy_min_pw_len);
     897             : 
     898          24 :         s.in.user_handle = handle;
     899          24 :         s.in.info = &u;
     900          24 :         s.in.level = 25;
     901             : 
     902          24 :         ZERO_STRUCT(u);
     903             : 
     904          24 :         u.info25.info.fields_present = fields_present;
     905             : 
     906          24 :         status = dcerpc_fetch_session_key(p, &session_key);
     907          24 :         if (!NT_STATUS_IS_OK(status)) {
     908           0 :                 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u - no session key - %s\n",
     909           0 :                        s.in.level, nt_errstr(status));
     910           0 :                 return false;
     911             :         }
     912             : 
     913          24 :         status = init_samr_CryptPasswordEx(newpass,
     914             :                                            &session_key,
     915             :                                            &u.info25.password);
     916          24 :         torture_assert_ntstatus_ok(tctx,
     917             :                                    status,
     918             :                                    "init_samr_CryptPasswordEx failed");
     919             : 
     920          24 :         torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex)\n");
     921             : 
     922          24 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
     923             :                 "SetUserInfo failed");
     924          24 :         torture_comment(tctx, "(%s:%s) new_password[%s] status[%s]\n",
     925             :                         __location__, __FUNCTION__,
     926             :                         newpass, nt_errstr(s.out.result));
     927          24 :         if (!NT_STATUS_IS_OK(s.out.result)) {
     928           0 :                 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u failed - %s\n",
     929           0 :                        s.in.level, nt_errstr(s.out.result));
     930           0 :                 ret = false;
     931             :         } else {
     932          24 :                 *password = newpass;
     933             :         }
     934             : 
     935             :         /* This should break the key nicely */
     936          24 :         session_key.data[0]++;
     937             : 
     938          24 :         status = init_samr_CryptPasswordEx(newpass,
     939             :                                            &session_key,
     940             :                                            &u.info25.password);
     941          24 :         torture_assert_ntstatus_ok(tctx,
     942             :                                    status,
     943             :                                    "init_samr_CryptPasswordEx failed");
     944             : 
     945             :         /* Reset the key */
     946          24 :         session_key.data[0]--;
     947             : 
     948          24 :         torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
     949             : 
     950          24 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
     951             :                 "SetUserInfo failed");
     952          24 :         torture_comment(tctx, "(%s:%s) new_password[%s] status[%s]\n",
     953             :                         __location__, __FUNCTION__,
     954             :                         newpass, nt_errstr(s.out.result));
     955          24 :         if (!NT_STATUS_EQUAL(s.out.result, NT_STATUS_WRONG_PASSWORD)) {
     956           0 :                 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
     957           0 :                        s.in.level, nt_errstr(s.out.result));
     958           0 :                 ret = false;
     959             :         }
     960             : 
     961          24 :         return ret;
     962             : }
     963             : 
     964           8 : static bool test_SetUserPass_18(struct dcerpc_pipe *p, struct torture_context *tctx,
     965             :                                 struct policy_handle *handle, char **password)
     966             : {
     967             :         NTSTATUS status;
     968             :         struct samr_SetUserInfo s;
     969             :         union samr_UserInfo u;
     970           8 :         bool ret = true;
     971             :         DATA_BLOB session_key;
     972             :         char *newpass;
     973           8 :         struct dcerpc_binding_handle *b = p->binding_handle;
     974             :         struct samr_GetUserPwInfo pwp;
     975             :         struct samr_PwInfo info;
     976           8 :         int policy_min_pw_len = 0;
     977             :         uint8_t lm_hash[16], nt_hash[16];
     978             : 
     979           8 :         pwp.in.user_handle = handle;
     980           8 :         pwp.out.info = &info;
     981             : 
     982           8 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
     983             :                 "GetUserPwInfo failed");
     984           8 :         if (NT_STATUS_IS_OK(pwp.out.result)) {
     985           8 :                 policy_min_pw_len = pwp.out.info->min_password_length;
     986             :         }
     987           8 :         newpass = samr_rand_pass(tctx, policy_min_pw_len);
     988             : 
     989           8 :         s.in.user_handle = handle;
     990           8 :         s.in.info = &u;
     991           8 :         s.in.level = 18;
     992             : 
     993           8 :         ZERO_STRUCT(u);
     994             : 
     995           8 :         u.info18.nt_pwd_active = true;
     996           8 :         u.info18.lm_pwd_active = true;
     997             : 
     998           8 :         E_md4hash(newpass, nt_hash);
     999           8 :         E_deshash(newpass, lm_hash);
    1000             : 
    1001           8 :         status = dcerpc_fetch_session_key(p, &session_key);
    1002           8 :         if (!NT_STATUS_IS_OK(status)) {
    1003           0 :                 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u - no session key - %s\n",
    1004           0 :                        s.in.level, nt_errstr(status));
    1005           0 :                 return false;
    1006             :         }
    1007             : 
    1008             :         {
    1009             :                 DATA_BLOB in,out;
    1010           8 :                 in = data_blob_const(nt_hash, 16);
    1011           8 :                 out = data_blob_talloc_zero(tctx, 16);
    1012           8 :                 sess_crypt_blob(&out, &in, &session_key, SAMBA_GNUTLS_ENCRYPT);
    1013           8 :                 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
    1014             :         }
    1015             :         {
    1016             :                 DATA_BLOB in,out;
    1017           8 :                 in = data_blob_const(lm_hash, 16);
    1018           8 :                 out = data_blob_talloc_zero(tctx, 16);
    1019           8 :                 sess_crypt_blob(&out, &in, &session_key, SAMBA_GNUTLS_ENCRYPT);
    1020           8 :                 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
    1021             :         }
    1022             : 
    1023           8 :         torture_comment(tctx, "Testing SetUserInfo level 18 (set password hash)\n");
    1024             : 
    1025           8 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
    1026             :                 "SetUserInfo failed");
    1027           8 :         if (!NT_STATUS_IS_OK(s.out.result)) {
    1028           0 :                 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u failed - %s\n",
    1029           0 :                        s.in.level, nt_errstr(s.out.result));
    1030           0 :                 ret = false;
    1031             :         } else {
    1032           8 :                 *password = newpass;
    1033             :         }
    1034             : 
    1035           8 :         return ret;
    1036             : }
    1037             : 
    1038          16 : static bool test_SetUserPass_21(struct dcerpc_pipe *p, struct torture_context *tctx,
    1039             :                                 struct policy_handle *handle, uint32_t fields_present,
    1040             :                                 char **password)
    1041             : {
    1042             :         NTSTATUS status;
    1043             :         struct samr_SetUserInfo s;
    1044             :         union samr_UserInfo u;
    1045          16 :         bool ret = true;
    1046             :         DATA_BLOB session_key;
    1047             :         char *newpass;
    1048          16 :         struct dcerpc_binding_handle *b = p->binding_handle;
    1049             :         struct samr_GetUserPwInfo pwp;
    1050             :         struct samr_PwInfo info;
    1051          16 :         int policy_min_pw_len = 0;
    1052             :         uint8_t lm_hash[16], nt_hash[16];
    1053             : 
    1054          16 :         pwp.in.user_handle = handle;
    1055          16 :         pwp.out.info = &info;
    1056             : 
    1057          16 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
    1058             :                 "GetUserPwInfo failed");
    1059          16 :         if (NT_STATUS_IS_OK(pwp.out.result)) {
    1060          16 :                 policy_min_pw_len = pwp.out.info->min_password_length;
    1061             :         }
    1062          16 :         newpass = samr_rand_pass(tctx, policy_min_pw_len);
    1063             : 
    1064          16 :         s.in.user_handle = handle;
    1065          16 :         s.in.info = &u;
    1066          16 :         s.in.level = 21;
    1067             : 
    1068          16 :         E_md4hash(newpass, nt_hash);
    1069          16 :         E_deshash(newpass, lm_hash);
    1070             : 
    1071          16 :         ZERO_STRUCT(u);
    1072             : 
    1073          16 :         u.info21.fields_present = fields_present;
    1074             : 
    1075          16 :         if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
    1076           8 :                 u.info21.lm_owf_password.length = 16;
    1077           8 :                 u.info21.lm_owf_password.size = 16;
    1078           8 :                 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
    1079           8 :                 u.info21.lm_password_set = true;
    1080             :         }
    1081             : 
    1082          16 :         if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
    1083          16 :                 u.info21.nt_owf_password.length = 16;
    1084          16 :                 u.info21.nt_owf_password.size = 16;
    1085          16 :                 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
    1086          16 :                 u.info21.nt_password_set = true;
    1087             :         }
    1088             : 
    1089          16 :         status = dcerpc_fetch_session_key(p, &session_key);
    1090          16 :         if (!NT_STATUS_IS_OK(status)) {
    1091           0 :                 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u - no session key - %s\n",
    1092           0 :                        s.in.level, nt_errstr(status));
    1093           0 :                 return false;
    1094             :         }
    1095             : 
    1096          16 :         if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
    1097             :                 DATA_BLOB in,out;
    1098           8 :                 in = data_blob_const(u.info21.lm_owf_password.array,
    1099           8 :                                      u.info21.lm_owf_password.length);
    1100           8 :                 out = data_blob_talloc_zero(tctx, 16);
    1101           8 :                 sess_crypt_blob(&out, &in, &session_key, SAMBA_GNUTLS_ENCRYPT);
    1102           8 :                 u.info21.lm_owf_password.array = (uint16_t *)out.data;
    1103             :         }
    1104             : 
    1105          16 :         if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
    1106             :                 DATA_BLOB in,out;
    1107          16 :                 in = data_blob_const(u.info21.nt_owf_password.array,
    1108          16 :                                      u.info21.nt_owf_password.length);
    1109          16 :                 out = data_blob_talloc_zero(tctx, 16);
    1110          16 :                 sess_crypt_blob(&out, &in, &session_key, SAMBA_GNUTLS_ENCRYPT);
    1111          16 :                 u.info21.nt_owf_password.array = (uint16_t *)out.data;
    1112             :         }
    1113             : 
    1114          16 :         torture_comment(tctx, "Testing SetUserInfo level 21 (set password hash)\n");
    1115             : 
    1116          16 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
    1117             :                 "SetUserInfo failed");
    1118          16 :         if (!NT_STATUS_IS_OK(s.out.result)) {
    1119           0 :                 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u failed - %s\n",
    1120           0 :                        s.in.level, nt_errstr(s.out.result));
    1121           0 :                 ret = false;
    1122             :         } else {
    1123          16 :                 *password = newpass;
    1124             :         }
    1125             : 
    1126             :         /* try invalid length */
    1127          16 :         if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
    1128             : 
    1129          16 :                 u.info21.nt_owf_password.length++;
    1130             : 
    1131          16 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
    1132             :                         "SetUserInfo failed");
    1133          16 :                 if (!NT_STATUS_EQUAL(s.out.result, NT_STATUS_INVALID_PARAMETER)) {
    1134           0 :                         torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
    1135           0 :                                s.in.level, nt_errstr(s.out.result));
    1136           0 :                         ret = false;
    1137             :                 }
    1138             :         }
    1139             : 
    1140          16 :         if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
    1141             : 
    1142           8 :                 u.info21.lm_owf_password.length++;
    1143             : 
    1144           8 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
    1145             :                         "SetUserInfo failed");
    1146           8 :                 if (!NT_STATUS_EQUAL(s.out.result, NT_STATUS_INVALID_PARAMETER)) {
    1147           0 :                         torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
    1148           0 :                                s.in.level, nt_errstr(s.out.result));
    1149           0 :                         ret = false;
    1150             :                 }
    1151             :         }
    1152             : 
    1153          16 :         return ret;
    1154             : }
    1155             : 
    1156         608 : static bool test_SetUserPass_level_ex(struct dcerpc_pipe *p,
    1157             :                                       struct torture_context *tctx,
    1158             :                                       struct policy_handle *handle,
    1159             :                                       uint16_t level,
    1160             :                                       uint32_t fields_present,
    1161             :                                       char **password, uint8_t password_expired,
    1162             :                                       bool use_setinfo2,
    1163             :                                       bool *matched_expected_error)
    1164             : {
    1165             :         NTSTATUS status;
    1166         608 :         NTSTATUS expected_error = NT_STATUS_OK;
    1167             :         struct samr_SetUserInfo s;
    1168             :         struct samr_SetUserInfo2 s2;
    1169             :         union samr_UserInfo u;
    1170         608 :         bool ret = true;
    1171             :         DATA_BLOB session_key;
    1172             :         char *newpass;
    1173         608 :         struct dcerpc_binding_handle *b = p->binding_handle;
    1174             :         struct samr_GetUserPwInfo pwp;
    1175             :         struct samr_PwInfo info;
    1176         608 :         int policy_min_pw_len = 0;
    1177         608 :         const char *comment = NULL;
    1178             :         uint8_t lm_hash[16], nt_hash[16];
    1179             : 
    1180         608 :         pwp.in.user_handle = handle;
    1181         608 :         pwp.out.info = &info;
    1182             : 
    1183         608 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
    1184             :                 "GetUserPwInfo failed");
    1185         608 :         if (NT_STATUS_IS_OK(pwp.out.result)) {
    1186         608 :                 policy_min_pw_len = pwp.out.info->min_password_length;
    1187             :         }
    1188         608 :         newpass = samr_rand_pass_silent(tctx, policy_min_pw_len);
    1189             : 
    1190         608 :         if (use_setinfo2) {
    1191           0 :                 s2.in.user_handle = handle;
    1192           0 :                 s2.in.info = &u;
    1193           0 :                 s2.in.level = level;
    1194             :         } else {
    1195         608 :                 s.in.user_handle = handle;
    1196         608 :                 s.in.info = &u;
    1197         608 :                 s.in.level = level;
    1198             :         }
    1199             : 
    1200         608 :         if (fields_present & SAMR_FIELD_COMMENT) {
    1201          64 :                 comment = talloc_asprintf(tctx, "comment: %ld\n", (long int) time(NULL));
    1202             :         }
    1203             : 
    1204         608 :         ZERO_STRUCT(u);
    1205             : 
    1206         608 :         switch (level) {
    1207          64 :         case 18:
    1208          64 :                 E_md4hash(newpass, nt_hash);
    1209          64 :                 E_deshash(newpass, lm_hash);
    1210             : 
    1211          64 :                 u.info18.nt_pwd_active = true;
    1212          64 :                 u.info18.lm_pwd_active = true;
    1213          64 :                 u.info18.password_expired = password_expired;
    1214             : 
    1215          64 :                 memcpy(u.info18.lm_pwd.hash, lm_hash, 16);
    1216          64 :                 memcpy(u.info18.nt_pwd.hash, nt_hash, 16);
    1217             : 
    1218          64 :                 break;
    1219         480 :         case 21:
    1220         480 :                 E_md4hash(newpass, nt_hash);
    1221         480 :                 E_deshash(newpass, lm_hash);
    1222             : 
    1223         480 :                 u.info21.fields_present = fields_present;
    1224         480 :                 u.info21.password_expired = password_expired;
    1225         480 :                 u.info21.comment.string = comment;
    1226             : 
    1227         480 :                 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
    1228         160 :                         u.info21.lm_owf_password.length = 16;
    1229         160 :                         u.info21.lm_owf_password.size = 16;
    1230         160 :                         u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
    1231         160 :                         u.info21.lm_password_set = true;
    1232             :                 }
    1233             : 
    1234         480 :                 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
    1235         304 :                         u.info21.nt_owf_password.length = 16;
    1236         304 :                         u.info21.nt_owf_password.size = 16;
    1237         304 :                         u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
    1238         304 :                         u.info21.nt_password_set = true;
    1239             :                 }
    1240             : 
    1241         480 :                 break;
    1242           0 :         case 23:
    1243           0 :                 u.info23.info.fields_present = fields_present;
    1244           0 :                 u.info23.info.password_expired = password_expired;
    1245           0 :                 u.info23.info.comment.string = comment;
    1246             : 
    1247           0 :                 break;
    1248           0 :         case 24:
    1249           0 :                 u.info24.password_expired = password_expired;
    1250             : 
    1251           0 :                 break;
    1252           0 :         case 25:
    1253           0 :                 u.info25.info.fields_present = fields_present;
    1254           0 :                 u.info25.info.password_expired = password_expired;
    1255           0 :                 u.info25.info.comment.string = comment;
    1256             : 
    1257           0 :                 break;
    1258          64 :         case 26:
    1259          64 :                 u.info26.password_expired = password_expired;
    1260             : 
    1261          64 :                 break;
    1262             :         }
    1263             : 
    1264         608 :         status = dcerpc_fetch_session_key(p, &session_key);
    1265         608 :         if (!NT_STATUS_IS_OK(status)) {
    1266           0 :                 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u - no session key - %s\n",
    1267           0 :                        s.in.level, nt_errstr(status));
    1268           0 :                 return false;
    1269             :         }
    1270             : 
    1271         608 :         switch (level) {
    1272          64 :         case 18:
    1273          56 :                 {
    1274             :                         DATA_BLOB in,out;
    1275          64 :                         in = data_blob_const(u.info18.nt_pwd.hash, 16);
    1276          64 :                         out = data_blob_talloc_zero(tctx, 16);
    1277          64 :                         sess_crypt_blob(&out, &in, &session_key, SAMBA_GNUTLS_ENCRYPT);
    1278          64 :                         memcpy(u.info18.nt_pwd.hash, out.data, out.length);
    1279             :                 }
    1280          56 :                 {
    1281             :                         DATA_BLOB in,out;
    1282          64 :                         in = data_blob_const(u.info18.lm_pwd.hash, 16);
    1283          64 :                         out = data_blob_talloc_zero(tctx, 16);
    1284          64 :                         sess_crypt_blob(&out, &in, &session_key, SAMBA_GNUTLS_ENCRYPT);
    1285          64 :                         memcpy(u.info18.lm_pwd.hash, out.data, out.length);
    1286             :                 }
    1287             : 
    1288          64 :                 break;
    1289         480 :         case 21:
    1290         480 :                 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
    1291             :                         DATA_BLOB in,out;
    1292         160 :                         in = data_blob_const(u.info21.lm_owf_password.array,
    1293         160 :                                              u.info21.lm_owf_password.length);
    1294         160 :                         out = data_blob_talloc_zero(tctx, 16);
    1295         160 :                         sess_crypt_blob(&out, &in, &session_key, SAMBA_GNUTLS_ENCRYPT);
    1296         160 :                         u.info21.lm_owf_password.array = (uint16_t *)out.data;
    1297             :                 }
    1298         480 :                 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
    1299             :                         DATA_BLOB in,out;
    1300         304 :                         in = data_blob_const(u.info21.nt_owf_password.array,
    1301         304 :                                              u.info21.nt_owf_password.length);
    1302         304 :                         out = data_blob_talloc_zero(tctx, 16);
    1303         304 :                         sess_crypt_blob(&out, &in, &session_key, SAMBA_GNUTLS_ENCRYPT);
    1304         304 :                         u.info21.nt_owf_password.array = (uint16_t *)out.data;
    1305             :                 }
    1306         480 :                 break;
    1307           0 :         case 23:
    1308           0 :                 status = init_samr_CryptPassword(newpass,
    1309             :                                                  &session_key,
    1310             :                                                  &u.info23.password);
    1311           0 :                 torture_assert_ntstatus_ok(tctx,
    1312             :                                            status,
    1313             :                                            "init_samr_CryptPassword failed");
    1314           0 :                 break;
    1315           0 :         case 24:
    1316           0 :                 status = init_samr_CryptPassword(newpass,
    1317             :                                                  &session_key,
    1318             :                                                  &u.info24.password);
    1319           0 :                 torture_assert_ntstatus_ok(tctx,
    1320             :                                            status,
    1321             :                                            "init_samr_CryptPassword failed");
    1322           0 :                 break;
    1323           0 :         case 25:
    1324           0 :                 status = init_samr_CryptPasswordEx(newpass,
    1325             :                                                    &session_key,
    1326             :                                                    &u.info25.password);
    1327           0 :                 torture_assert_ntstatus_ok(tctx,
    1328             :                                            status,
    1329             :                                            "init_samr_CryptPasswordEx failed");
    1330           0 :                 break;
    1331          64 :         case 26:
    1332          64 :                 status = init_samr_CryptPasswordEx(newpass,
    1333             :                                                    &session_key,
    1334             :                                                    &u.info26.password);
    1335          64 :                 torture_assert_ntstatus_ok(tctx,
    1336             :                                            status,
    1337             :                                            "init_samr_CryptPasswordEx failed");
    1338          64 :                 break;
    1339             :         }
    1340             : 
    1341         608 :         if (use_setinfo2) {
    1342           0 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo2_r(b, tctx, &s2),
    1343             :                         "SetUserInfo2 failed");
    1344           0 :                 torture_comment(tctx, "(%s:%s) new_password[%s] status[%s]\n",
    1345             :                                 __location__, __FUNCTION__,
    1346             :                                 newpass, nt_errstr(s2.out.result));
    1347           0 :                         status = s2.out.result;
    1348             :         } else {
    1349         608 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
    1350             :                         "SetUserInfo failed");
    1351         608 :                 torture_comment(tctx, "(%s:%s) new_password[%s] status[%s]\n",
    1352             :                                 __location__, __FUNCTION__,
    1353             :                                 newpass, nt_errstr(s.out.result));
    1354         608 :                 status = s.out.result;
    1355             :         }
    1356             : 
    1357         608 :         if (!NT_STATUS_IS_OK(status)) {
    1358          96 :                 if (fields_present == 0) {
    1359          16 :                         expected_error = NT_STATUS_INVALID_PARAMETER;
    1360             :                 }
    1361          96 :                 if (fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
    1362          80 :                         expected_error = NT_STATUS_ACCESS_DENIED;
    1363             :                 }
    1364             :         }
    1365             : 
    1366         608 :         if (!NT_STATUS_IS_OK(expected_error)) {
    1367          96 :                 if (use_setinfo2) {
    1368           0 :                         torture_assert_ntstatus_equal(tctx,
    1369             :                                 s2.out.result,
    1370             :                                 expected_error, "SetUserInfo2 failed");
    1371             :                 } else {
    1372          96 :                         torture_assert_ntstatus_equal(tctx,
    1373             :                                 s.out.result,
    1374             :                                 expected_error, "SetUserInfo failed");
    1375             :                 }
    1376          96 :                 *matched_expected_error = true;
    1377          96 :                 return true;
    1378             :         }
    1379             : 
    1380         512 :         if (!NT_STATUS_IS_OK(status)) {
    1381           0 :                 torture_result(tctx, TORTURE_FAIL, "SetUserInfo%s level %u failed - %s\n",
    1382             :                        use_setinfo2 ? "2":"", level, nt_errstr(status));
    1383           0 :                 ret = false;
    1384             :         } else {
    1385         512 :                 *password = newpass;
    1386             :         }
    1387             : 
    1388         512 :         return ret;
    1389             : }
    1390             : 
    1391           7 : static bool test_SetAliasInfo(struct dcerpc_binding_handle *b,
    1392             :                               struct torture_context *tctx,
    1393             :                               struct policy_handle *handle)
    1394             : {
    1395             :         struct samr_SetAliasInfo r;
    1396             :         struct samr_QueryAliasInfo q;
    1397             :         union samr_AliasInfo *info;
    1398           7 :         uint16_t levels[] = {2, 3};
    1399             :         int i;
    1400           7 :         bool ret = true;
    1401             : 
    1402             :         /* Ignoring switch level 1, as that includes the number of members for the alias
    1403             :          * and setting this to a wrong value might have negative consequences
    1404             :          */
    1405             : 
    1406          21 :         for (i=0;i<ARRAY_SIZE(levels);i++) {
    1407          14 :                 torture_comment(tctx, "Testing SetAliasInfo level %u\n", levels[i]);
    1408             : 
    1409          14 :                 r.in.alias_handle = handle;
    1410          14 :                 r.in.level = levels[i];
    1411          14 :                 r.in.info  = talloc(tctx, union samr_AliasInfo);
    1412          14 :                 switch (r.in.level) {
    1413           7 :                     case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
    1414           7 :                     case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
    1415           7 :                                 "Test Description, should test I18N as well"); break;
    1416           0 :                     case ALIASINFOALL: torture_comment(tctx, "ALIASINFOALL ignored\n"); break;
    1417             :                 }
    1418             : 
    1419          14 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetAliasInfo_r(b, tctx, &r),
    1420             :                         "SetAliasInfo failed");
    1421          14 :                 if (!NT_STATUS_IS_OK(r.out.result)) {
    1422           0 :                         torture_result(tctx, TORTURE_FAIL, "SetAliasInfo level %u failed - %s\n",
    1423           0 :                                levels[i], nt_errstr(r.out.result));
    1424           0 :                         ret = false;
    1425             :                 }
    1426             : 
    1427          14 :                 q.in.alias_handle = handle;
    1428          14 :                 q.in.level = levels[i];
    1429          14 :                 q.out.info = &info;
    1430             : 
    1431          14 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryAliasInfo_r(b, tctx, &q),
    1432             :                         "QueryAliasInfo failed");
    1433          14 :                 if (!NT_STATUS_IS_OK(q.out.result)) {
    1434           0 :                         torture_result(tctx, TORTURE_FAIL, "QueryAliasInfo level %u failed - %s\n",
    1435           0 :                                levels[i], nt_errstr(q.out.result));
    1436           0 :                         ret = false;
    1437             :                 }
    1438             :         }
    1439             : 
    1440           7 :         return ret;
    1441             : }
    1442             : 
    1443           2 : static bool test_GetGroupsForUser(struct dcerpc_binding_handle *b,
    1444             :                                   struct torture_context *tctx,
    1445             :                                   struct policy_handle *user_handle)
    1446             : {
    1447             :         struct samr_GetGroupsForUser r;
    1448           2 :         struct samr_RidWithAttributeArray *rids = NULL;
    1449             : 
    1450           2 :         torture_comment(tctx, "Testing GetGroupsForUser\n");
    1451             : 
    1452           2 :         r.in.user_handle = user_handle;
    1453           2 :         r.out.rids = &rids;
    1454             : 
    1455           2 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetGroupsForUser_r(b, tctx, &r),
    1456             :                 "GetGroupsForUser failed");
    1457           2 :         torture_assert_ntstatus_ok(tctx, r.out.result, "GetGroupsForUser failed");
    1458             : 
    1459           2 :         return true;
    1460             : 
    1461             : }
    1462             : 
    1463         116 : static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
    1464             :                               struct lsa_String *domain_name)
    1465             : {
    1466             :         struct samr_GetDomPwInfo r;
    1467             :         struct samr_PwInfo info;
    1468         116 :         struct dcerpc_binding_handle *b = p->binding_handle;
    1469             : 
    1470         116 :         r.in.domain_name = domain_name;
    1471         116 :         r.out.info = &info;
    1472             : 
    1473         116 :         torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
    1474             : 
    1475         116 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &r),
    1476             :                 "GetDomPwInfo failed");
    1477         116 :         torture_assert_ntstatus_ok(tctx, r.out.result, "GetDomPwInfo failed");
    1478             : 
    1479         116 :         r.in.domain_name->string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
    1480         116 :         torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
    1481             : 
    1482         116 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &r),
    1483             :                 "GetDomPwInfo failed");
    1484         116 :         torture_assert_ntstatus_ok(tctx, r.out.result, "GetDomPwInfo failed");
    1485             : 
    1486         116 :         r.in.domain_name->string = "\\\\__NONAME__";
    1487         116 :         torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
    1488             : 
    1489         116 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &r),
    1490             :                 "GetDomPwInfo failed");
    1491         116 :         torture_assert_ntstatus_ok(tctx, r.out.result, "GetDomPwInfo failed");
    1492             : 
    1493         116 :         r.in.domain_name->string = "\\\\Builtin";
    1494         116 :         torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
    1495             : 
    1496         116 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &r),
    1497             :                 "GetDomPwInfo failed");
    1498         116 :         torture_assert_ntstatus_ok(tctx, r.out.result, "GetDomPwInfo failed");
    1499             : 
    1500         116 :         return true;
    1501             : }
    1502             : 
    1503          18 : static bool test_GetUserPwInfo(struct dcerpc_binding_handle *b,
    1504             :                                struct torture_context *tctx,
    1505             :                                struct policy_handle *handle)
    1506             : {
    1507             :         struct samr_GetUserPwInfo r;
    1508             :         struct samr_PwInfo info;
    1509             : 
    1510          18 :         torture_comment(tctx, "Testing GetUserPwInfo\n");
    1511             : 
    1512          18 :         r.in.user_handle = handle;
    1513          18 :         r.out.info = &info;
    1514             : 
    1515          18 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &r),
    1516             :                 "GetUserPwInfo failed");
    1517          18 :         torture_assert_ntstatus_ok(tctx, r.out.result, "GetUserPwInfo");
    1518             : 
    1519          18 :         return true;
    1520             : }
    1521             : 
    1522         356 : static NTSTATUS test_LookupName(struct dcerpc_binding_handle *b,
    1523             :                                 struct torture_context *tctx,
    1524             :                                 struct policy_handle *domain_handle, const char *name,
    1525             :                                 uint32_t *rid)
    1526             : {
    1527             :         NTSTATUS status;
    1528             :         struct samr_LookupNames n;
    1529             :         struct lsa_String sname[2];
    1530             :         struct samr_Ids rids, types;
    1531             : 
    1532         356 :         init_lsa_String(&sname[0], name);
    1533             : 
    1534         356 :         n.in.domain_handle = domain_handle;
    1535         356 :         n.in.num_names = 1;
    1536         356 :         n.in.names = sname;
    1537         356 :         n.out.rids = &rids;
    1538         356 :         n.out.types = &types;
    1539         356 :         status = dcerpc_samr_LookupNames_r(b, tctx, &n);
    1540         356 :         if (!NT_STATUS_IS_OK(status)) {
    1541           0 :                 return status;
    1542             :         }
    1543         356 :         if (NT_STATUS_IS_OK(n.out.result)) {
    1544         342 :                 *rid = n.out.rids->ids[0];
    1545             :         } else {
    1546          14 :                 return n.out.result;
    1547             :         }
    1548             : 
    1549         342 :         init_lsa_String(&sname[1], "xxNONAMExx");
    1550         342 :         n.in.num_names = 2;
    1551         342 :         status = dcerpc_samr_LookupNames_r(b, tctx, &n);
    1552         342 :         if (!NT_STATUS_IS_OK(status)) {
    1553           0 :                 return status;
    1554             :         }
    1555         342 :         if (!NT_STATUS_EQUAL(n.out.result, STATUS_SOME_UNMAPPED)) {
    1556           0 :                 torture_result(tctx, TORTURE_FAIL, "LookupNames[2] failed - %s\n", nt_errstr(n.out.result));
    1557           0 :                 if (NT_STATUS_IS_OK(n.out.result)) {
    1558           0 :                         return NT_STATUS_UNSUCCESSFUL;
    1559             :                 }
    1560           0 :                 return n.out.result;
    1561             :         }
    1562             : 
    1563         342 :         n.in.num_names = 0;
    1564         342 :         status = dcerpc_samr_LookupNames_r(b, tctx, &n);
    1565         342 :         if (!NT_STATUS_IS_OK(status)) {
    1566           0 :                 return status;
    1567             :         }
    1568         342 :         if (!NT_STATUS_IS_OK(n.out.result)) {
    1569           0 :                 torture_result(tctx, TORTURE_FAIL, "LookupNames[0] failed - %s\n", nt_errstr(status));
    1570           0 :                 return n.out.result;
    1571             :         }
    1572             : 
    1573         342 :         init_lsa_String(&sname[0], "xxNONAMExx");
    1574         342 :         n.in.num_names = 1;
    1575         342 :         status = dcerpc_samr_LookupNames_r(b, tctx, &n);
    1576         342 :         if (!NT_STATUS_IS_OK(status)) {
    1577           0 :                 return status;
    1578             :         }
    1579         342 :         if (!NT_STATUS_EQUAL(n.out.result, NT_STATUS_NONE_MAPPED)) {
    1580           0 :                 torture_result(tctx, TORTURE_FAIL, "LookupNames[1 bad name] failed - %s\n", nt_errstr(n.out.result));
    1581           0 :                 if (NT_STATUS_IS_OK(n.out.result)) {
    1582           0 :                         return NT_STATUS_UNSUCCESSFUL;
    1583             :                 }
    1584           0 :                 return n.out.result;
    1585             :         }
    1586             : 
    1587         342 :         init_lsa_String(&sname[0], "xxNONAMExx");
    1588         342 :         init_lsa_String(&sname[1], "xxNONAME2xx");
    1589         342 :         n.in.num_names = 2;
    1590         342 :         status = dcerpc_samr_LookupNames_r(b, tctx, &n);
    1591         342 :         if (!NT_STATUS_IS_OK(status)) {
    1592           0 :                 return status;
    1593             :         }
    1594         342 :         if (!NT_STATUS_EQUAL(n.out.result, NT_STATUS_NONE_MAPPED)) {
    1595           0 :                 torture_result(tctx, TORTURE_FAIL, "LookupNames[2 bad names] failed - %s\n", nt_errstr(n.out.result));
    1596           0 :                 if (NT_STATUS_IS_OK(n.out.result)) {
    1597           0 :                         return NT_STATUS_UNSUCCESSFUL;
    1598             :                 }
    1599           0 :                 return n.out.result;
    1600             :         }
    1601             : 
    1602         342 :         return NT_STATUS_OK;
    1603             : }
    1604             : 
    1605         288 : static NTSTATUS test_OpenUser_byname(struct dcerpc_binding_handle *b,
    1606             :                                      struct torture_context *tctx,
    1607             :                                      struct policy_handle *domain_handle,
    1608             :                                      const char *name, struct policy_handle *user_handle)
    1609             : {
    1610             :         NTSTATUS status;
    1611             :         struct samr_OpenUser r;
    1612             :         uint32_t rid;
    1613             : 
    1614         288 :         status = test_LookupName(b, tctx, domain_handle, name, &rid);
    1615         288 :         if (!NT_STATUS_IS_OK(status)) {
    1616          14 :                 return status;
    1617             :         }
    1618             : 
    1619         274 :         r.in.domain_handle = domain_handle;
    1620         274 :         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    1621         274 :         r.in.rid = rid;
    1622         274 :         r.out.user_handle = user_handle;
    1623         274 :         status = dcerpc_samr_OpenUser_r(b, tctx, &r);
    1624         274 :         if (!NT_STATUS_IS_OK(status)) {
    1625           0 :                 return status;
    1626             :         }
    1627         274 :         if (!NT_STATUS_IS_OK(r.out.result)) {
    1628           0 :                 torture_result(tctx, TORTURE_FAIL, "OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(r.out.result));
    1629             :         }
    1630             : 
    1631         274 :         return r.out.result;
    1632             : }
    1633             : 
    1634             : #if 0
    1635             : static bool test_ChangePasswordNT3(struct dcerpc_pipe *p,
    1636             :                                    struct torture_context *tctx,
    1637             :                                    struct policy_handle *handle)
    1638             : {
    1639             :         NTSTATUS status;
    1640             :         struct samr_ChangePasswordUser r;
    1641             :         bool ret = true;
    1642             :         struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
    1643             :         struct policy_handle user_handle;
    1644             :         char *oldpass = "test";
    1645             :         char *newpass = "test2";
    1646             :         uint8_t old_nt_hash[16], new_nt_hash[16];
    1647             :         uint8_t old_lm_hash[16], new_lm_hash[16];
    1648             : 
    1649             :         status = test_OpenUser_byname(p, tctx, handle, "testuser", &user_handle);
    1650             :         if (!NT_STATUS_IS_OK(status)) {
    1651             :                 return false;
    1652             :         }
    1653             : 
    1654             :         torture_comment(tctx, "Testing ChangePasswordUser for user 'testuser'\n");
    1655             : 
    1656             :         torture_comment(tctx, "old password: %s\n", oldpass);
    1657             :         torture_comment(tctx, "new password: %s\n", newpass);
    1658             : 
    1659             :         E_md4hash(oldpass, old_nt_hash);
    1660             :         E_md4hash(newpass, new_nt_hash);
    1661             :         E_deshash(oldpass, old_lm_hash);
    1662             :         E_deshash(newpass, new_lm_hash);
    1663             : 
    1664             :         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
    1665             :         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
    1666             :         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
    1667             :         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
    1668             :         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
    1669             :         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
    1670             : 
    1671             :         r.in.handle = &user_handle;
    1672             :         r.in.lm_present = 1;
    1673             :         r.in.old_lm_crypted = &hash1;
    1674             :         r.in.new_lm_crypted = &hash2;
    1675             :         r.in.nt_present = 1;
    1676             :         r.in.old_nt_crypted = &hash3;
    1677             :         r.in.new_nt_crypted = &hash4;
    1678             :         r.in.cross1_present = 1;
    1679             :         r.in.nt_cross = &hash5;
    1680             :         r.in.cross2_present = 1;
    1681             :         r.in.lm_cross = &hash6;
    1682             : 
    1683             :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
    1684             :                 "ChangePasswordUser failed");
    1685             :         if (!NT_STATUS_IS_OK(r.out.result)) {
    1686             :                 torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser failed - %s\n", nt_errstr(r.out.result));
    1687             :                 ret = false;
    1688             :         }
    1689             : 
    1690             :         if (!test_samr_handle_Close(p, tctx, &user_handle)) {
    1691             :                 ret = false;
    1692             :         }
    1693             : 
    1694             :         return ret;
    1695             : }
    1696             : #endif
    1697             : 
    1698           8 : static bool test_ChangePasswordUser(struct dcerpc_binding_handle *b,
    1699             :                                     struct torture_context *tctx,
    1700             :                                     const char *acct_name,
    1701             :                                     struct policy_handle *handle, char **password)
    1702             : {
    1703             :         NTSTATUS status;
    1704             :         struct samr_ChangePasswordUser r;
    1705           8 :         bool ret = true;
    1706             :         struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
    1707             :         struct policy_handle user_handle;
    1708             :         char *oldpass;
    1709             :         uint8_t old_nt_hash[16], new_nt_hash[16];
    1710             :         uint8_t old_lm_hash[16], new_lm_hash[16];
    1711           8 :         bool changed = true;
    1712             : 
    1713             :         char *newpass;
    1714             :         struct samr_GetUserPwInfo pwp;
    1715             :         struct samr_PwInfo info;
    1716           8 :         int policy_min_pw_len = 0;
    1717             : 
    1718           8 :         status = test_OpenUser_byname(b, tctx, handle, acct_name, &user_handle);
    1719           8 :         if (!NT_STATUS_IS_OK(status)) {
    1720           0 :                 return false;
    1721             :         }
    1722           8 :         pwp.in.user_handle = &user_handle;
    1723           8 :         pwp.out.info = &info;
    1724             : 
    1725           8 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
    1726             :                 "GetUserPwInfo failed");
    1727           8 :         if (NT_STATUS_IS_OK(pwp.out.result)) {
    1728           8 :                 policy_min_pw_len = pwp.out.info->min_password_length;
    1729             :         }
    1730           8 :         newpass = samr_rand_pass(tctx, policy_min_pw_len);
    1731             : 
    1732           8 :         torture_comment(tctx, "Testing ChangePasswordUser\n");
    1733             : 
    1734           8 :         torture_assert(tctx, *password != NULL,
    1735             :                                    "Failing ChangePasswordUser as old password was NULL.  Previous test failed?");
    1736             : 
    1737           8 :         oldpass = *password;
    1738             : 
    1739           8 :         E_md4hash(oldpass, old_nt_hash);
    1740           8 :         E_md4hash(newpass, new_nt_hash);
    1741           8 :         E_deshash(oldpass, old_lm_hash);
    1742           8 :         E_deshash(newpass, new_lm_hash);
    1743             : 
    1744           8 :         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
    1745           8 :         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
    1746           8 :         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
    1747           8 :         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
    1748           8 :         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
    1749           8 :         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
    1750             : 
    1751           8 :         r.in.user_handle = &user_handle;
    1752           8 :         r.in.lm_present = 1;
    1753             :         /* Break the NT hash */
    1754           8 :         hash3.hash[0]++;
    1755           8 :         r.in.old_lm_crypted = &hash1;
    1756           8 :         r.in.new_lm_crypted = &hash2;
    1757           8 :         r.in.nt_present = 1;
    1758           8 :         r.in.old_nt_crypted = &hash3;
    1759           8 :         r.in.new_nt_crypted = &hash4;
    1760           8 :         r.in.cross1_present = 1;
    1761           8 :         r.in.nt_cross = &hash5;
    1762           8 :         r.in.cross2_present = 1;
    1763           8 :         r.in.lm_cross = &hash6;
    1764             : 
    1765           8 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
    1766             :                 "ChangePasswordUser failed");
    1767           8 :         torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
    1768             :                         __location__, __FUNCTION__,
    1769             :                         oldpass, newpass, nt_errstr(r.out.result));
    1770             : 
    1771             :         /* Do not proceed if this call has been removed */
    1772           8 :         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_IMPLEMENTED)) {
    1773           8 :                 torture_skip(tctx, "ValidatePassword not supported by server\n");
    1774             :         }
    1775             : 
    1776           0 :         if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
    1777           0 :                 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_WRONG_PASSWORD,
    1778             :                         "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
    1779             :         }
    1780             : 
    1781             :         /* Unbreak the NT hash */
    1782           0 :         hash3.hash[0]--;
    1783             : 
    1784           0 :         r.in.user_handle = &user_handle;
    1785           0 :         r.in.lm_present = 1;
    1786           0 :         r.in.old_lm_crypted = &hash1;
    1787           0 :         r.in.new_lm_crypted = &hash2;
    1788             :         /* Break the LM hash */
    1789           0 :         hash1.hash[0]--;
    1790           0 :         r.in.nt_present = 1;
    1791           0 :         r.in.old_nt_crypted = &hash3;
    1792           0 :         r.in.new_nt_crypted = &hash4;
    1793           0 :         r.in.cross1_present = 1;
    1794           0 :         r.in.nt_cross = &hash5;
    1795           0 :         r.in.cross2_present = 1;
    1796           0 :         r.in.lm_cross = &hash6;
    1797             : 
    1798           0 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
    1799             :                 "ChangePasswordUser failed");
    1800           0 :         torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
    1801             :                         __location__, __FUNCTION__,
    1802             :                         oldpass, newpass, nt_errstr(r.out.result));
    1803           0 :         if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
    1804           0 :                 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_WRONG_PASSWORD,
    1805             :                         "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
    1806             :         }
    1807             : 
    1808             :         /* Unbreak the NT hash */
    1809           0 :         hash3.hash[0]--;
    1810             : 
    1811           0 :         r.in.user_handle = &user_handle;
    1812           0 :         r.in.lm_present = 1;
    1813           0 :         r.in.old_lm_crypted = &hash1;
    1814           0 :         r.in.new_lm_crypted = &hash2;
    1815           0 :         r.in.nt_present = 1;
    1816           0 :         r.in.old_nt_crypted = &hash3;
    1817           0 :         r.in.new_nt_crypted = &hash4;
    1818           0 :         r.in.cross1_present = 1;
    1819           0 :         r.in.nt_cross = &hash5;
    1820           0 :         r.in.cross2_present = 1;
    1821             :         /* Break the LM cross */
    1822           0 :         hash6.hash[0]++;
    1823           0 :         r.in.lm_cross = &hash6;
    1824             : 
    1825           0 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
    1826             :                 "ChangePasswordUser failed");
    1827           0 :         torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
    1828             :                         __location__, __FUNCTION__,
    1829             :                         oldpass, newpass, nt_errstr(r.out.result));
    1830           0 :         if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD) &&
    1831           0 :             !NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION))
    1832             :         {
    1833           0 :                 torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD or NT_STATUS_PASSWORD_RESTRICTION because we broke the LM cross-hash, got %s\n", nt_errstr(r.out.result));
    1834           0 :                 ret = false;
    1835             :         }
    1836             : 
    1837             :         /* Unbreak the LM cross */
    1838           0 :         hash6.hash[0]--;
    1839             : 
    1840           0 :         r.in.user_handle = &user_handle;
    1841           0 :         r.in.lm_present = 1;
    1842           0 :         r.in.old_lm_crypted = &hash1;
    1843           0 :         r.in.new_lm_crypted = &hash2;
    1844           0 :         r.in.nt_present = 1;
    1845           0 :         r.in.old_nt_crypted = &hash3;
    1846           0 :         r.in.new_nt_crypted = &hash4;
    1847           0 :         r.in.cross1_present = 1;
    1848             :         /* Break the NT cross */
    1849           0 :         hash5.hash[0]++;
    1850           0 :         r.in.nt_cross = &hash5;
    1851           0 :         r.in.cross2_present = 1;
    1852           0 :         r.in.lm_cross = &hash6;
    1853             : 
    1854           0 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
    1855             :                 "ChangePasswordUser failed");
    1856           0 :         torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
    1857             :                         __location__, __FUNCTION__,
    1858             :                         oldpass, newpass, nt_errstr(r.out.result));
    1859           0 :         if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD) &&
    1860           0 :             !NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION))
    1861             :         {
    1862           0 :                 torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD or NT_STATUS_PASSWORD_RESTRICTION because we broke the NT cross-hash, got %s\n", nt_errstr(r.out.result));
    1863           0 :                 ret = false;
    1864             :         }
    1865             : 
    1866             :         /* Unbreak the NT cross */
    1867           0 :         hash5.hash[0]--;
    1868             : 
    1869             : 
    1870             :         /* Reset the hashes to not broken values */
    1871           0 :         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
    1872           0 :         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
    1873           0 :         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
    1874           0 :         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
    1875           0 :         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
    1876           0 :         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
    1877             : 
    1878           0 :         r.in.user_handle = &user_handle;
    1879           0 :         r.in.lm_present = 1;
    1880           0 :         r.in.old_lm_crypted = &hash1;
    1881           0 :         r.in.new_lm_crypted = &hash2;
    1882           0 :         r.in.nt_present = 1;
    1883           0 :         r.in.old_nt_crypted = &hash3;
    1884           0 :         r.in.new_nt_crypted = &hash4;
    1885           0 :         r.in.cross1_present = 1;
    1886           0 :         r.in.nt_cross = &hash5;
    1887           0 :         r.in.cross2_present = 0;
    1888           0 :         r.in.lm_cross = NULL;
    1889             : 
    1890           0 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
    1891             :                 "ChangePasswordUser failed");
    1892           0 :         torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
    1893             :                         __location__, __FUNCTION__,
    1894             :                         oldpass, newpass, nt_errstr(r.out.result));
    1895           0 :         if (NT_STATUS_IS_OK(r.out.result)) {
    1896           0 :                 changed = true;
    1897           0 :                 *password = newpass;
    1898           0 :         } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, r.out.result)) {
    1899           0 :                 torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(r.out.result));
    1900           0 :                 ret = false;
    1901             :         }
    1902             : 
    1903           0 :         oldpass = newpass;
    1904           0 :         newpass = samr_rand_pass(tctx, policy_min_pw_len);
    1905             : 
    1906           0 :         E_md4hash(oldpass, old_nt_hash);
    1907           0 :         E_md4hash(newpass, new_nt_hash);
    1908           0 :         E_deshash(oldpass, old_lm_hash);
    1909           0 :         E_deshash(newpass, new_lm_hash);
    1910             : 
    1911             : 
    1912             :         /* Reset the hashes to not broken values */
    1913           0 :         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
    1914           0 :         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
    1915           0 :         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
    1916           0 :         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
    1917           0 :         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
    1918           0 :         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
    1919             : 
    1920           0 :         r.in.user_handle = &user_handle;
    1921           0 :         r.in.lm_present = 1;
    1922           0 :         r.in.old_lm_crypted = &hash1;
    1923           0 :         r.in.new_lm_crypted = &hash2;
    1924           0 :         r.in.nt_present = 1;
    1925           0 :         r.in.old_nt_crypted = &hash3;
    1926           0 :         r.in.new_nt_crypted = &hash4;
    1927           0 :         r.in.cross1_present = 0;
    1928           0 :         r.in.nt_cross = NULL;
    1929           0 :         r.in.cross2_present = 1;
    1930           0 :         r.in.lm_cross = &hash6;
    1931             : 
    1932           0 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
    1933             :                 "ChangePasswordUser failed");
    1934           0 :         torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
    1935             :                         __location__, __FUNCTION__,
    1936             :                         oldpass, newpass, nt_errstr(r.out.result));
    1937           0 :         if (NT_STATUS_IS_OK(r.out.result)) {
    1938           0 :                 changed = true;
    1939           0 :                 *password = newpass;
    1940           0 :         } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, r.out.result)) {
    1941           0 :                 torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(r.out.result));
    1942           0 :                 ret = false;
    1943             :         }
    1944             : 
    1945           0 :         oldpass = newpass;
    1946           0 :         newpass = samr_rand_pass(tctx, policy_min_pw_len);
    1947             : 
    1948           0 :         E_md4hash(oldpass, old_nt_hash);
    1949           0 :         E_md4hash(newpass, new_nt_hash);
    1950           0 :         E_deshash(oldpass, old_lm_hash);
    1951           0 :         E_deshash(newpass, new_lm_hash);
    1952             : 
    1953             : 
    1954             :         /* Reset the hashes to not broken values */
    1955           0 :         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
    1956           0 :         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
    1957           0 :         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
    1958           0 :         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
    1959           0 :         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
    1960           0 :         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
    1961             : 
    1962           0 :         r.in.user_handle = &user_handle;
    1963           0 :         r.in.lm_present = 1;
    1964           0 :         r.in.old_lm_crypted = &hash1;
    1965           0 :         r.in.new_lm_crypted = &hash2;
    1966           0 :         r.in.nt_present = 1;
    1967           0 :         r.in.old_nt_crypted = &hash3;
    1968           0 :         r.in.new_nt_crypted = &hash4;
    1969           0 :         r.in.cross1_present = 1;
    1970           0 :         r.in.nt_cross = &hash5;
    1971           0 :         r.in.cross2_present = 1;
    1972           0 :         r.in.lm_cross = &hash6;
    1973             : 
    1974           0 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
    1975             :                 "ChangePasswordUser failed");
    1976           0 :         torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
    1977             :                         __location__, __FUNCTION__,
    1978             :                         oldpass, newpass, nt_errstr(r.out.result));
    1979           0 :         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
    1980           0 :                 torture_comment(tctx, "ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r.out.result));
    1981           0 :         } else  if (!NT_STATUS_IS_OK(r.out.result)) {
    1982           0 :                 torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser failed - %s\n", nt_errstr(r.out.result));
    1983           0 :                 ret = false;
    1984             :         } else {
    1985           0 :                 changed = true;
    1986           0 :                 *password = newpass;
    1987             :         }
    1988             : 
    1989           0 :         r.in.user_handle = &user_handle;
    1990           0 :         r.in.lm_present = 1;
    1991           0 :         r.in.old_lm_crypted = &hash1;
    1992           0 :         r.in.new_lm_crypted = &hash2;
    1993           0 :         r.in.nt_present = 1;
    1994           0 :         r.in.old_nt_crypted = &hash3;
    1995           0 :         r.in.new_nt_crypted = &hash4;
    1996           0 :         r.in.cross1_present = 1;
    1997           0 :         r.in.nt_cross = &hash5;
    1998           0 :         r.in.cross2_present = 1;
    1999           0 :         r.in.lm_cross = &hash6;
    2000             : 
    2001           0 :         if (changed) {
    2002           0 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
    2003             :                         "ChangePasswordUser failed");
    2004           0 :                 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
    2005             :                                 __location__, __FUNCTION__,
    2006             :                                 oldpass, newpass, nt_errstr(r.out.result));
    2007           0 :                 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
    2008           0 :                         torture_comment(tctx, "ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r.out.result));
    2009           0 :                 } else if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
    2010           0 :                         torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(r.out.result));
    2011           0 :                         ret = false;
    2012             :                 }
    2013             :         }
    2014             : 
    2015             : 
    2016           0 :         if (!test_samr_handle_Close(b, tctx, &user_handle)) {
    2017           0 :                 ret = false;
    2018             :         }
    2019             : 
    2020           0 :         return ret;
    2021             : }
    2022             : 
    2023             : 
    2024           8 : static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p,
    2025             :                                         struct torture_context *tctx,
    2026             :                                         const char *acct_name,
    2027             :                                         struct policy_handle *handle, char **password)
    2028             : {
    2029             :         struct samr_OemChangePasswordUser2 r;
    2030           8 :         bool ret = true;
    2031             :         struct samr_Password lm_verifier;
    2032             :         struct samr_CryptPassword lm_pass;
    2033             :         struct lsa_AsciiString server, account, account_bad;
    2034             :         char *oldpass;
    2035             :         char *newpass;
    2036           8 :         struct dcerpc_binding_handle *b = p->binding_handle;
    2037             :         uint8_t old_lm_hash[16], new_lm_hash[16];
    2038           8 :         gnutls_cipher_hd_t cipher_hnd = NULL;
    2039           8 :         gnutls_datum_t session_key = {
    2040             :                 .data = old_lm_hash,
    2041             :                 .size = 16
    2042             :         };
    2043             : 
    2044             :         struct samr_GetDomPwInfo dom_pw_info;
    2045             :         struct samr_PwInfo info;
    2046           8 :         int policy_min_pw_len = 0;
    2047             : 
    2048             :         struct lsa_String domain_name;
    2049             : 
    2050           8 :         domain_name.string = "";
    2051           8 :         dom_pw_info.in.domain_name = &domain_name;
    2052           8 :         dom_pw_info.out.info = &info;
    2053             : 
    2054           8 :         torture_comment(tctx, "Testing OemChangePasswordUser2\n");
    2055             : 
    2056           8 :         torture_assert(tctx, *password != NULL,
    2057             :                                    "Failing OemChangePasswordUser2 as old password was NULL.  Previous test failed?");
    2058             : 
    2059           8 :         oldpass = *password;
    2060             : 
    2061           8 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &dom_pw_info),
    2062             :                 "GetDomPwInfo failed");
    2063           8 :         if (NT_STATUS_IS_OK(dom_pw_info.out.result)) {
    2064           8 :                 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
    2065             :         }
    2066             : 
    2067           8 :         newpass = samr_rand_pass(tctx, policy_min_pw_len);
    2068             : 
    2069           8 :         server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
    2070           8 :         account.string = acct_name;
    2071             : 
    2072           8 :         E_deshash(oldpass, old_lm_hash);
    2073           8 :         E_deshash(newpass, new_lm_hash);
    2074             : 
    2075           8 :         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
    2076             : 
    2077           8 :         gnutls_cipher_init(&cipher_hnd,
    2078             :                            GNUTLS_CIPHER_ARCFOUR_128,
    2079             :                            &session_key,
    2080             :                            NULL);
    2081           8 :         gnutls_cipher_encrypt(cipher_hnd, lm_pass.data, 516);
    2082           8 :         gnutls_cipher_deinit(cipher_hnd);
    2083           8 :         E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
    2084             : 
    2085           8 :         r.in.server = &server;
    2086           8 :         r.in.account = &account;
    2087           8 :         r.in.password = &lm_pass;
    2088           8 :         r.in.hash = &lm_verifier;
    2089             : 
    2090             :         /* Break the verification */
    2091           8 :         lm_verifier.hash[0]++;
    2092             : 
    2093           8 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
    2094             :                 "OemChangePasswordUser2 failed");
    2095           8 :         torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
    2096             :                         __location__, __FUNCTION__,
    2097             :                         oldpass, newpass, nt_errstr(r.out.result));
    2098             : 
    2099           8 :         if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)
    2100           8 :             && !NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
    2101           0 :                 torture_result(tctx, TORTURE_FAIL, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
    2102             :                         nt_errstr(r.out.result));
    2103           0 :                 ret = false;
    2104             :         }
    2105             : 
    2106           8 :         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
    2107             :         /* Break the old password */
    2108           8 :         old_lm_hash[0]++;
    2109           8 :         gnutls_cipher_init(&cipher_hnd,
    2110             :                            GNUTLS_CIPHER_ARCFOUR_128,
    2111             :                            &session_key,
    2112             :                            NULL);
    2113           8 :         gnutls_cipher_encrypt(cipher_hnd, lm_pass.data, 516);
    2114           8 :         gnutls_cipher_deinit(cipher_hnd);
    2115             :         /* unbreak it for the next operation */
    2116           8 :         old_lm_hash[0]--;
    2117           8 :         E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
    2118             : 
    2119           8 :         r.in.server = &server;
    2120           8 :         r.in.account = &account;
    2121           8 :         r.in.password = &lm_pass;
    2122           8 :         r.in.hash = &lm_verifier;
    2123             : 
    2124           8 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
    2125             :                 "OemChangePasswordUser2 failed");
    2126           8 :         torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
    2127             :                         __location__, __FUNCTION__,
    2128             :                         oldpass, newpass, nt_errstr(r.out.result));
    2129             : 
    2130           8 :         if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)
    2131           8 :             && !NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
    2132           0 :                 torture_result(tctx, TORTURE_FAIL, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrypted password - %s\n",
    2133             :                         nt_errstr(r.out.result));
    2134           0 :                 ret = false;
    2135             :         }
    2136             : 
    2137           8 :         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
    2138           8 :         gnutls_cipher_init(&cipher_hnd,
    2139             :                            GNUTLS_CIPHER_ARCFOUR_128,
    2140             :                            &session_key,
    2141             :                            NULL);
    2142           8 :         gnutls_cipher_encrypt(cipher_hnd, lm_pass.data, 516);
    2143           8 :         gnutls_cipher_deinit(cipher_hnd);
    2144             : 
    2145           8 :         r.in.server = &server;
    2146           8 :         r.in.account = &account;
    2147           8 :         r.in.password = &lm_pass;
    2148           8 :         r.in.hash = NULL;
    2149             : 
    2150           8 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
    2151             :                 "OemChangePasswordUser2 failed");
    2152           8 :         torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
    2153             :                         __location__, __FUNCTION__,
    2154             :                         oldpass, newpass, nt_errstr(r.out.result));
    2155             : 
    2156           8 :         if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)
    2157           8 :             && !NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
    2158           0 :                 torture_result(tctx, TORTURE_FAIL, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
    2159             :                         nt_errstr(r.out.result));
    2160           0 :                 ret = false;
    2161             :         }
    2162             : 
    2163             :         /* This shouldn't be a valid name */
    2164           8 :         account_bad.string = TEST_ACCOUNT_NAME "XX";
    2165           8 :         r.in.account = &account_bad;
    2166             : 
    2167           8 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
    2168             :                 "OemChangePasswordUser2 failed");
    2169           8 :         torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
    2170             :                         __location__, __FUNCTION__,
    2171             :                         oldpass, newpass, nt_errstr(r.out.result));
    2172             : 
    2173           8 :         if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
    2174           0 :                 torture_result(tctx, TORTURE_FAIL, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
    2175             :                         nt_errstr(r.out.result));
    2176           0 :                 ret = false;
    2177             :         }
    2178             : 
    2179             :         /* This shouldn't be a valid name */
    2180           8 :         account_bad.string = TEST_ACCOUNT_NAME "XX";
    2181           8 :         r.in.account = &account_bad;
    2182           8 :         r.in.password = &lm_pass;
    2183           8 :         r.in.hash = &lm_verifier;
    2184             : 
    2185           8 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
    2186             :                 "OemChangePasswordUser2 failed");
    2187           8 :         torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
    2188             :                         __location__, __FUNCTION__,
    2189             :                         oldpass, newpass, nt_errstr(r.out.result));
    2190             : 
    2191           8 :         if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
    2192           0 :                 torture_result(tctx, TORTURE_FAIL, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
    2193             :                         nt_errstr(r.out.result));
    2194           0 :                 ret = false;
    2195             :         }
    2196             : 
    2197             :         /* This shouldn't be a valid name */
    2198           8 :         account_bad.string = TEST_ACCOUNT_NAME "XX";
    2199           8 :         r.in.account = &account_bad;
    2200           8 :         r.in.password = NULL;
    2201           8 :         r.in.hash = &lm_verifier;
    2202             : 
    2203           8 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
    2204             :                 "OemChangePasswordUser2 failed");
    2205           8 :         torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
    2206             :                         __location__, __FUNCTION__,
    2207             :                         oldpass, newpass, nt_errstr(r.out.result));
    2208             : 
    2209           8 :         if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
    2210           0 :                 torture_result(tctx, TORTURE_FAIL, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
    2211             :                         nt_errstr(r.out.result));
    2212           0 :                 ret = false;
    2213             :         }
    2214             : 
    2215           8 :         E_deshash(oldpass, old_lm_hash);
    2216           8 :         E_deshash(newpass, new_lm_hash);
    2217             : 
    2218           8 :         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
    2219           8 :         gnutls_cipher_init(&cipher_hnd,
    2220             :                            GNUTLS_CIPHER_ARCFOUR_128,
    2221             :                            &session_key,
    2222             :                            NULL);
    2223           8 :         gnutls_cipher_encrypt(cipher_hnd, lm_pass.data, 516);
    2224           8 :         gnutls_cipher_deinit(cipher_hnd);
    2225           8 :         E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
    2226             : 
    2227           8 :         r.in.server = &server;
    2228           8 :         r.in.account = &account;
    2229           8 :         r.in.password = &lm_pass;
    2230           8 :         r.in.hash = &lm_verifier;
    2231             : 
    2232           8 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
    2233             :                 "OemChangePasswordUser2 failed");
    2234           8 :         torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
    2235             :                         __location__, __FUNCTION__,
    2236             :                         oldpass, newpass, nt_errstr(r.out.result));
    2237             : 
    2238           8 :         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
    2239           4 :                 torture_comment(tctx, "OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r.out.result));
    2240           4 :         } else if (!NT_STATUS_IS_OK(r.out.result)) {
    2241           0 :                 torture_result(tctx, TORTURE_FAIL, "OemChangePasswordUser2 failed - %s\n", nt_errstr(r.out.result));
    2242           0 :                 ret = false;
    2243             :         } else {
    2244           4 :                 *password = newpass;
    2245             :         }
    2246             : 
    2247           8 :         return ret;
    2248             : }
    2249             : 
    2250             : 
    2251          24 : static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
    2252             :                                      const char *acct_name,
    2253             :                                      char **password,
    2254             :                                      char *newpass, bool allow_password_restriction)
    2255             : {
    2256             :         struct samr_ChangePasswordUser2 r;
    2257          24 :         bool ret = true;
    2258             :         struct lsa_String server, account;
    2259             :         struct samr_CryptPassword nt_pass, lm_pass;
    2260             :         struct samr_Password nt_verifier, lm_verifier;
    2261             :         char *oldpass;
    2262          24 :         struct dcerpc_binding_handle *b = p->binding_handle;
    2263          24 :         uint8_t old_nt_hash[16] = { 0 }, new_nt_hash[16];
    2264             :         uint8_t old_lm_hash[16], new_lm_hash[16];
    2265          23 :         DATA_BLOB old_nt_hash_blob
    2266           1 :                 = data_blob_const(old_nt_hash, sizeof(old_nt_hash));
    2267             :         struct samr_GetDomPwInfo dom_pw_info;
    2268             :         struct samr_PwInfo info;
    2269             : 
    2270             :         struct lsa_String domain_name;
    2271             :         NTSTATUS status;
    2272             : 
    2273          24 :         gnutls_cipher_hd_t cipher_hnd = NULL;
    2274          24 :         gnutls_datum_t old_lm_key = {
    2275             :                 .data = old_lm_hash,
    2276             :                 .size = sizeof(old_lm_hash),
    2277             :         };
    2278             : 
    2279          24 :         domain_name.string = "";
    2280          24 :         dom_pw_info.in.domain_name = &domain_name;
    2281          24 :         dom_pw_info.out.info = &info;
    2282             : 
    2283          24 :         torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
    2284             : 
    2285          24 :         torture_assert(tctx, *password != NULL,
    2286             :                                    "Failing ChangePasswordUser2 as old password was NULL.  Previous test failed?");
    2287          24 :         oldpass = *password;
    2288             : 
    2289          24 :         if (!newpass) {
    2290          20 :                 int policy_min_pw_len = 0;
    2291          20 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &dom_pw_info),
    2292             :                         "GetDomPwInfo failed");
    2293          20 :                 if (NT_STATUS_IS_OK(dom_pw_info.out.result)) {
    2294          20 :                         policy_min_pw_len = dom_pw_info.out.info->min_password_length;
    2295             :                 }
    2296             : 
    2297          20 :                 newpass = samr_rand_pass(tctx, policy_min_pw_len);
    2298             :         }
    2299             : 
    2300          24 :         server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
    2301          24 :         init_lsa_String(&account, acct_name);
    2302             : 
    2303          24 :         E_md4hash(oldpass, old_nt_hash);
    2304          24 :         E_md4hash(newpass, new_nt_hash);
    2305             : 
    2306          24 :         E_deshash(oldpass, old_lm_hash);
    2307          24 :         E_deshash(newpass, new_lm_hash);
    2308             : 
    2309          24 :         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
    2310             : 
    2311          24 :         gnutls_cipher_init(&cipher_hnd,
    2312             :                            GNUTLS_CIPHER_ARCFOUR_128,
    2313             :                            &old_lm_key,
    2314             :                            NULL);
    2315          24 :         gnutls_cipher_encrypt(cipher_hnd,
    2316             :                               lm_pass.data,
    2317             :                               516);
    2318          24 :         gnutls_cipher_deinit(cipher_hnd);
    2319             : 
    2320          24 :         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
    2321             : 
    2322          24 :         status = init_samr_CryptPassword(newpass,
    2323             :                                          &old_nt_hash_blob,
    2324             :                                          &nt_pass);
    2325          24 :         torture_assert_ntstatus_ok(tctx,
    2326             :                                    status,
    2327             :                                    "init_samr_CryptPassword failed");
    2328             : 
    2329          24 :         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
    2330             : 
    2331          24 :         r.in.server = &server;
    2332          24 :         r.in.account = &account;
    2333          24 :         r.in.nt_password = &nt_pass;
    2334          24 :         r.in.nt_verifier = &nt_verifier;
    2335          24 :         r.in.lm_change = 1;
    2336          24 :         r.in.lm_password = &lm_pass;
    2337          24 :         r.in.lm_verifier = &lm_verifier;
    2338             : 
    2339          24 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser2_r(b, tctx, &r),
    2340             :                 "ChangePasswordUser2 failed");
    2341          24 :         torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
    2342             :                         __location__, __FUNCTION__,
    2343             :                         oldpass, newpass, nt_errstr(r.out.result));
    2344             : 
    2345          24 :         if (allow_password_restriction && NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
    2346           4 :                 torture_comment(tctx, "ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r.out.result));
    2347          20 :         } else if (!NT_STATUS_IS_OK(r.out.result)) {
    2348           0 :                 torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser2 failed - %s\n", nt_errstr(r.out.result));
    2349           0 :                 ret = false;
    2350             :         } else {
    2351          20 :                 *password = newpass;
    2352             :         }
    2353             : 
    2354          24 :         return ret;
    2355             : }
    2356             : 
    2357             : 
    2358         112 : static bool test_ChangePasswordUser2_ntstatus(struct dcerpc_pipe *p, struct torture_context *tctx,
    2359             :                                               const char *acct_name,
    2360             :                                               const char *password, NTSTATUS status)
    2361             : {
    2362             :         struct samr_ChangePasswordUser2 r;
    2363             :         struct lsa_String server, account;
    2364             :         struct samr_CryptPassword nt_pass, lm_pass;
    2365             :         struct samr_Password nt_verifier, lm_verifier;
    2366             :         const char *oldpass;
    2367         112 :         struct dcerpc_binding_handle *b = p->binding_handle;
    2368         112 :         uint8_t old_nt_hash[16] = { 0 }, new_nt_hash[16];
    2369             :         uint8_t old_lm_hash[16], new_lm_hash[16];
    2370         112 :         DATA_BLOB old_nt_hash_blob
    2371           0 :                 = data_blob_const(old_nt_hash, sizeof(old_nt_hash));
    2372         112 :         gnutls_cipher_hd_t cipher_hnd = NULL;
    2373         112 :         gnutls_datum_t old_lm_key = {
    2374             :                 .data = old_lm_hash,
    2375             :                 .size = sizeof(old_lm_hash),
    2376             :         };
    2377             : 
    2378             :         struct samr_GetDomPwInfo dom_pw_info;
    2379             :         struct samr_PwInfo info;
    2380             : 
    2381             :         struct lsa_String domain_name;
    2382             :         NTSTATUS crypt_status;
    2383             : 
    2384             :         char *newpass;
    2385         112 :         int policy_min_pw_len = 0;
    2386             : 
    2387         112 :         domain_name.string = "";
    2388         112 :         dom_pw_info.in.domain_name = &domain_name;
    2389         112 :         dom_pw_info.out.info = &info;
    2390             : 
    2391         112 :         torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
    2392             : 
    2393         112 :         oldpass = password;
    2394             : 
    2395         112 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &dom_pw_info),
    2396             :                                    "GetDomPwInfo failed");
    2397         112 :         if (NT_STATUS_IS_OK(dom_pw_info.out.result)) {
    2398         112 :                 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
    2399             :         }
    2400             : 
    2401         112 :         newpass = samr_rand_pass(tctx, policy_min_pw_len);
    2402             : 
    2403         112 :         server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
    2404         112 :         init_lsa_String(&account, acct_name);
    2405             : 
    2406         112 :         E_md4hash(oldpass, old_nt_hash);
    2407         112 :         E_md4hash(newpass, new_nt_hash);
    2408             : 
    2409         112 :         E_deshash(oldpass, old_lm_hash);
    2410         112 :         E_deshash(newpass, new_lm_hash);
    2411             : 
    2412         112 :         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
    2413             : 
    2414         112 :         gnutls_cipher_init(&cipher_hnd,
    2415             :                            GNUTLS_CIPHER_ARCFOUR_128,
    2416             :                            &old_lm_key,
    2417             :                            NULL);
    2418         112 :         gnutls_cipher_encrypt(cipher_hnd,
    2419             :                               lm_pass.data,
    2420             :                               516);
    2421         112 :         gnutls_cipher_deinit(cipher_hnd);
    2422             : 
    2423         112 :         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
    2424             : 
    2425         112 :         crypt_status = init_samr_CryptPassword(newpass,
    2426             :                                                &old_nt_hash_blob,
    2427             :                                                &nt_pass);
    2428         112 :         torture_assert_ntstatus_ok(tctx,
    2429             :                                    crypt_status,
    2430             :                                    "init_samr_CryptPassword failed");
    2431             : 
    2432         112 :         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
    2433             : 
    2434         112 :         r.in.server = &server;
    2435         112 :         r.in.account = &account;
    2436         112 :         r.in.nt_password = &nt_pass;
    2437         112 :         r.in.nt_verifier = &nt_verifier;
    2438         112 :         r.in.lm_change = 1;
    2439         112 :         r.in.lm_password = &lm_pass;
    2440         112 :         r.in.lm_verifier = &lm_verifier;
    2441             : 
    2442         112 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser2_r(b, tctx, &r),
    2443             :                 "ChangePasswordUser2 failed");
    2444         112 :         torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
    2445             :                         __location__, __FUNCTION__,
    2446             :                         oldpass, newpass, nt_errstr(r.out.result));
    2447             : 
    2448         112 :         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
    2449           0 :                 torture_comment(tctx, "ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r.out.result));
    2450             :         } else {
    2451         112 :                 torture_assert_ntstatus_equal(tctx, r.out.result, status, "ChangePasswordUser2 returned unexpected value");
    2452             :         }
    2453             : 
    2454         112 :         return true;
    2455             : }
    2456             : 
    2457             : 
    2458         127 : bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx,
    2459             :                               const char *account_string,
    2460             :                               int policy_min_pw_len,
    2461             :                               char **password,
    2462             :                               const char *newpass,
    2463             :                               NTTIME last_password_change,
    2464             :                               bool handle_reject_reason)
    2465             : {
    2466             :         struct samr_ChangePasswordUser3 r;
    2467         127 :         bool ret = true;
    2468             :         struct lsa_String server, account, account_bad;
    2469             :         struct samr_CryptPassword nt_pass, lm_pass;
    2470             :         struct samr_Password nt_verifier, lm_verifier;
    2471             :         char *oldpass;
    2472         127 :         struct dcerpc_binding_handle *b = p->binding_handle;
    2473         127 :         uint8_t old_nt_hash[16] = { 0 }, new_nt_hash[16];
    2474             :         uint8_t old_lm_hash[16], new_lm_hash[16];
    2475             :         NTTIME t;
    2476         127 :         struct samr_DomInfo1 *dominfo = NULL;
    2477         127 :         struct userPwdChangeFailureInformation *reject = NULL;
    2478         127 :         DATA_BLOB old_nt_hash_blob = data_blob_const(old_nt_hash, 16);
    2479             :         NTSTATUS status;
    2480             : 
    2481         127 :         torture_comment(tctx, "Testing ChangePasswordUser3\n");
    2482             : 
    2483         127 :         if (newpass == NULL) {
    2484             :                 do {
    2485         114 :                         if (policy_min_pw_len == 0) {
    2486          96 :                                 newpass = samr_rand_pass(tctx, policy_min_pw_len);
    2487             :                         } else {
    2488          18 :                                 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
    2489             :                         }
    2490         114 :                 } while (check_password_quality(newpass) == false);
    2491             :         } else {
    2492          16 :                 torture_comment(tctx, "Using password '%s'\n", newpass);
    2493             :         }
    2494             : 
    2495         127 :         torture_assert(tctx, *password != NULL,
    2496             :                                    "Failing ChangePasswordUser3 as old password was NULL.  Previous test failed?");
    2497             : 
    2498         127 :         oldpass = *password;
    2499         127 :         server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
    2500         127 :         init_lsa_String(&account, account_string);
    2501             : 
    2502         127 :         E_md4hash(oldpass, old_nt_hash);
    2503         127 :         E_md4hash(newpass, new_nt_hash);
    2504             : 
    2505         127 :         E_deshash(oldpass, old_lm_hash);
    2506         127 :         E_deshash(newpass, new_lm_hash);
    2507             : 
    2508             :         /*
    2509             :          * The new plaintext password is encrypted using RC4 with the
    2510             :          * old NT password hash (directly, with no confounder).  The
    2511             :          * password is at the end of the random padded buffer,
    2512             :          * offering a little protection.
    2513             :          *
    2514             :          * This is almost certainly wrong, it should be the old LM
    2515             :          * hash, it was switched in an unrelated commit
    2516             :          * 579c13da43d5b40ac6d6c1436399fbc1d8dfd054 in 2004.
    2517             :          */
    2518         127 :         status = init_samr_CryptPassword(newpass,
    2519             :                                          &old_nt_hash_blob,
    2520             :                                          &lm_pass);
    2521         127 :         torture_assert_ntstatus_ok(tctx,
    2522             :                                    status,
    2523             :                                    "init_samr_CryptPassword");
    2524             : 
    2525             :         /*
    2526             :          * Now we prepare a DES cross-hash of the old LM and new NT
    2527             :          * passwords to link the two buffers
    2528             :          */
    2529         127 :         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
    2530             : 
    2531             :         /*
    2532             :          * The new plaintext password is also encrypted using RC4 with
    2533             :          * the old NT password hash (directly, with no confounder).
    2534             :          * The password is at the end of the random padded buffer,
    2535             :          * offering a little protection.
    2536             :          */
    2537         127 :         status = init_samr_CryptPassword(newpass,
    2538             :                                          &old_nt_hash_blob,
    2539             :                                          &nt_pass);
    2540         127 :         torture_assert_ntstatus_ok(tctx,
    2541             :                                    status,
    2542             :                                    "init_samr_CryptPassword");
    2543             : 
    2544             :         /*
    2545             :          * Another DES based cross-hash
    2546             :          */
    2547         127 :         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
    2548             : 
    2549             :         /* Break the verification */
    2550         127 :         nt_verifier.hash[0]++;
    2551             : 
    2552         127 :         r.in.server = &server;
    2553         127 :         r.in.account = &account;
    2554         127 :         r.in.nt_password = &nt_pass;
    2555         127 :         r.in.nt_verifier = &nt_verifier;
    2556         127 :         r.in.lm_change = 1;
    2557         127 :         r.in.lm_password = &lm_pass;
    2558         127 :         r.in.lm_verifier = &lm_verifier;
    2559         127 :         r.in.password3 = NULL;
    2560         127 :         r.out.dominfo = &dominfo;
    2561         127 :         r.out.reject = &reject;
    2562             : 
    2563         127 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
    2564             :                 "ChangePasswordUser3 failed");
    2565         127 :         torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
    2566             :                         __location__, __FUNCTION__,
    2567             :                         oldpass, newpass, nt_errstr(r.out.result));
    2568         238 :         if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION) &&
    2569         127 :             (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD))) {
    2570           0 :                 torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
    2571             :                         nt_errstr(r.out.result));
    2572           0 :                 ret = false;
    2573             :         }
    2574             : 
    2575         127 :         status = init_samr_CryptPassword(newpass,
    2576             :                                          &old_nt_hash_blob,
    2577             :                                          &lm_pass);
    2578         127 :         torture_assert_ntstatus_ok(tctx,
    2579             :                                    status,
    2580             :                                    "init_samr_CryptPassword");
    2581             : 
    2582         127 :         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
    2583             : 
    2584             :         /* Break the NT Hash */
    2585         127 :         old_nt_hash[0]++;
    2586             : 
    2587         127 :         status = init_samr_CryptPassword(newpass,
    2588             :                                          &old_nt_hash_blob,
    2589             :                                          &nt_pass);
    2590         127 :         torture_assert_ntstatus_ok(tctx,
    2591             :                                    status,
    2592             :                                    "init_samr_CryptPassword");
    2593             : 
    2594             :         /* Unbreak it again */
    2595         127 :         old_nt_hash[0]--;
    2596             : 
    2597         127 :         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
    2598             : 
    2599         127 :         r.in.server = &server;
    2600         127 :         r.in.account = &account;
    2601         127 :         r.in.nt_password = &nt_pass;
    2602         127 :         r.in.nt_verifier = &nt_verifier;
    2603         127 :         r.in.lm_change = 1;
    2604         127 :         r.in.lm_password = &lm_pass;
    2605         127 :         r.in.lm_verifier = &lm_verifier;
    2606         127 :         r.in.password3 = NULL;
    2607         127 :         r.out.dominfo = &dominfo;
    2608         127 :         r.out.reject = &reject;
    2609             : 
    2610         127 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
    2611             :                 "ChangePasswordUser3 failed");
    2612         127 :         torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
    2613             :                         __location__, __FUNCTION__,
    2614             :                         oldpass, newpass, nt_errstr(r.out.result));
    2615         238 :         if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION) &&
    2616         127 :             (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD))) {
    2617           0 :                 torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrypted password - %s\n",
    2618             :                         nt_errstr(r.out.result));
    2619           0 :                 ret = false;
    2620             :         }
    2621             : 
    2622             :         /* This shouldn't be a valid name */
    2623         127 :         init_lsa_String(&account_bad, talloc_asprintf(tctx, "%sXX", account_string));
    2624             : 
    2625         127 :         r.in.account = &account_bad;
    2626         127 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
    2627             :                 "ChangePasswordUser3 failed");
    2628         127 :         torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
    2629             :                         __location__, __FUNCTION__,
    2630             :                         oldpass, newpass, nt_errstr(r.out.result));
    2631         127 :         if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
    2632           0 :                 torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
    2633             :                         nt_errstr(r.out.result));
    2634           0 :                 ret = false;
    2635             :         }
    2636             : 
    2637         127 :         E_md4hash(oldpass, old_nt_hash);
    2638         127 :         E_md4hash(newpass, new_nt_hash);
    2639             : 
    2640         127 :         E_deshash(oldpass, old_lm_hash);
    2641         127 :         E_deshash(newpass, new_lm_hash);
    2642             : 
    2643         127 :         status = init_samr_CryptPassword(newpass,
    2644             :                                          &old_nt_hash_blob,
    2645             :                                          &lm_pass);
    2646         127 :         torture_assert_ntstatus_ok(tctx,
    2647             :                                    status,
    2648             :                                    "init_samr_CryptPassword");
    2649             : 
    2650         127 :         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
    2651             : 
    2652         127 :         status = init_samr_CryptPassword(newpass,
    2653             :                                          &old_nt_hash_blob,
    2654             :                                          &nt_pass);
    2655         127 :         torture_assert_ntstatus_ok(tctx,
    2656             :                                    status,
    2657             :                                    "init_samr_CryptPassword");
    2658             : 
    2659         127 :         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
    2660             : 
    2661         127 :         r.in.server = &server;
    2662         127 :         r.in.account = &account;
    2663         127 :         r.in.nt_password = &nt_pass;
    2664         127 :         r.in.nt_verifier = &nt_verifier;
    2665         127 :         r.in.lm_change = 1;
    2666         127 :         r.in.lm_password = &lm_pass;
    2667         127 :         r.in.lm_verifier = &lm_verifier;
    2668         127 :         r.in.password3 = NULL;
    2669         127 :         r.out.dominfo = &dominfo;
    2670         127 :         r.out.reject = &reject;
    2671             : 
    2672         127 :         unix_to_nt_time(&t, time(NULL));
    2673             : 
    2674         127 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
    2675             :                 "ChangePasswordUser3 failed");
    2676         127 :         torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
    2677             :                         __location__, __FUNCTION__,
    2678             :                         oldpass, newpass, nt_errstr(r.out.result));
    2679             : 
    2680         540 :         torture_comment(tctx, "(%s): dominfo[%s], reject[%s], handle_reject_reason[%s], "
    2681             :                         "last_password_change[%s], dominfo->min_password_age[%lld]\n",
    2682             :                         __location__,
    2683         127 :                         (dominfo == NULL)? "NULL" : "present",
    2684         127 :                         reject ? "true" : "false",
    2685             :                         handle_reject_reason ? "true" : "false",
    2686         127 :                         null_nttime(last_password_change) ? "null" : "not null",
    2687         174 :                         dominfo ? (long long)dominfo->min_password_age : (long long)0);
    2688             : 
    2689         127 :         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)
    2690          62 :             && dominfo
    2691          62 :             && reject
    2692          62 :             && handle_reject_reason
    2693          26 :             && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
    2694          10 :                 if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
    2695             : 
    2696           0 :                         if (reject && (reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR)) {
    2697           0 :                                 torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
    2698           0 :                                         SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
    2699           1 :                                 return false;
    2700             :                         }
    2701             :                 }
    2702             : 
    2703             :                 /* We tested the order of precendence which is as follows:
    2704             : 
    2705             :                 * pwd min_age
    2706             :                 * pwd length
    2707             :                 * pwd complexity
    2708             :                 * pwd history
    2709             : 
    2710             :                 Guenther */
    2711             : 
    2712          13 :                 if ((dominfo->min_password_age < 0) && !null_nttime(last_password_change) &&
    2713           4 :                            (last_password_change - dominfo->min_password_age > t)) {
    2714             : 
    2715           7 :                         if (reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
    2716           0 :                                 torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
    2717           0 :                                         SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
    2718           0 :                                 return false;
    2719             :                         }
    2720             : 
    2721          11 :                 } else if ((dominfo->min_password_length > 0) &&
    2722           6 :                            (strlen(newpass) < dominfo->min_password_length)) {
    2723             : 
    2724          11 :                         if (reject->extendedFailureReason != SAM_PWD_CHANGE_PASSWORD_TOO_SHORT) {
    2725           0 :                                 torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_PASSWORD_TOO_SHORT (%d), got %d\n",
    2726           0 :                                         SAM_PWD_CHANGE_PASSWORD_TOO_SHORT, reject->extendedFailureReason);
    2727           0 :                                 return false;
    2728             :                         }
    2729             : 
    2730           0 :                 } else if ((dominfo->password_history_length > 0) &&
    2731           0 :                             strequal(oldpass, newpass)) {
    2732             : 
    2733           0 :                         if (reject->extendedFailureReason != SAM_PWD_CHANGE_PWD_IN_HISTORY) {
    2734           0 :                                 torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_PWD_IN_HISTORY (%d), got %d\n",
    2735           0 :                                         SAM_PWD_CHANGE_PWD_IN_HISTORY, reject->extendedFailureReason);
    2736           0 :                                 return false;
    2737             :                         }
    2738           0 :                 } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
    2739             : 
    2740           0 :                         if (reject->extendedFailureReason != SAM_PWD_CHANGE_NOT_COMPLEX) {
    2741           0 :                                 torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_NOT_COMPLEX (%d), got %d\n",
    2742           0 :                                         SAM_PWD_CHANGE_NOT_COMPLEX, reject->extendedFailureReason);
    2743           0 :                                 return false;
    2744             :                         }
    2745             : 
    2746             :                 }
    2747             : 
    2748          13 :                 if (reject->extendedFailureReason == SAM_PWD_CHANGE_PASSWORD_TOO_SHORT) {
    2749             :                         /* retry with adjusted size */
    2750           6 :                         return test_ChangePasswordUser3(p, tctx, account_string,
    2751           6 :                                                         dominfo->min_password_length,
    2752             :                                                         password, NULL, 0, false);
    2753             : 
    2754             :                 }
    2755             : 
    2756         117 :         } else if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
    2757          52 :                 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
    2758           0 :                         torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
    2759           0 :                                SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
    2760           0 :                         return false;
    2761             :                 }
    2762             :                 /* Perhaps the server has a 'min password age' set? */
    2763             : 
    2764             :         } else {
    2765          65 :                 torture_assert_ntstatus_ok(tctx, r.out.result, "ChangePasswordUser3");
    2766             : 
    2767          65 :                 *password = talloc_strdup(tctx, newpass);
    2768             :         }
    2769             : 
    2770         121 :         return ret;
    2771             : }
    2772             : 
    2773           2 : bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
    2774             :                                     const char *account_string,
    2775             :                                     struct policy_handle *handle,
    2776             :                                     char **password)
    2777             : {
    2778             :         NTSTATUS status;
    2779             :         struct samr_ChangePasswordUser3 r;
    2780             :         struct samr_SetUserInfo s;
    2781             :         union samr_UserInfo u;
    2782             :         DATA_BLOB session_key;
    2783             : 
    2784           2 :         bool ret = true;
    2785             :         struct lsa_String server, account;
    2786             :         struct samr_CryptPassword nt_pass;
    2787             :         struct samr_Password nt_verifier;
    2788             :         DATA_BLOB new_random_pass;
    2789             :         char *newpass;
    2790             :         char *oldpass;
    2791           2 :         struct dcerpc_binding_handle *b = p->binding_handle;
    2792           2 :         uint8_t old_nt_hash[16] = { 0 }, new_nt_hash[16];
    2793           2 :         DATA_BLOB old_nt_hash_blob
    2794           0 :                 = data_blob_const(old_nt_hash,
    2795             :                                   sizeof(old_nt_hash));
    2796             :         NTTIME t;
    2797           2 :         struct samr_DomInfo1 *dominfo = NULL;
    2798           2 :         struct userPwdChangeFailureInformation *reject = NULL;
    2799           2 :         gnutls_cipher_hd_t cipher_hnd = NULL;
    2800           2 :         uint8_t _confounder[16] = {0};
    2801           2 :         DATA_BLOB confounder
    2802           0 :                 = data_blob_const(_confounder,
    2803             :                                   sizeof(_confounder));
    2804             :         DATA_BLOB pw_data;
    2805           2 :         gnutls_datum_t old_nt_key = {
    2806             :                 .data = old_nt_hash,
    2807             :                 .size = sizeof(old_nt_hash),
    2808             :         };
    2809             : 
    2810           2 :         new_random_pass = samr_very_rand_pass(tctx, 128);
    2811             : 
    2812           2 :         torture_assert(tctx, *password != NULL,
    2813             :                                    "Failing ChangePasswordUser3 as old password was NULL.  Previous test failed?");
    2814             : 
    2815           2 :         oldpass = *password;
    2816           2 :         server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
    2817           2 :         init_lsa_String(&account, account_string);
    2818             : 
    2819           2 :         s.in.user_handle = handle;
    2820           2 :         s.in.info = &u;
    2821           2 :         s.in.level = 25;
    2822             : 
    2823           2 :         ZERO_STRUCT(u);
    2824             : 
    2825           2 :         u.info25.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT;
    2826             : 
    2827           2 :         set_pw_in_buffer(u.info25.password.data, &new_random_pass);
    2828             : 
    2829           2 :         pw_data = data_blob_const(u.info25.password.data, 516);
    2830             : 
    2831           2 :         status = dcerpc_fetch_session_key(p, &session_key);
    2832           2 :         if (!NT_STATUS_IS_OK(status)) {
    2833           0 :                 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u - no session key - %s\n",
    2834           0 :                        s.in.level, nt_errstr(status));
    2835           0 :                 return false;
    2836             :         }
    2837             : 
    2838           2 :         generate_random_buffer(_confounder,
    2839             :                                sizeof(_confounder));
    2840             : 
    2841           2 :         samba_gnutls_arcfour_confounded_md5(&confounder,
    2842             :                                             &session_key,
    2843             :                                             &pw_data,
    2844             :                                             SAMBA_GNUTLS_ENCRYPT);
    2845             : 
    2846           2 :         memcpy(&u.info25.password.data[516], _confounder, sizeof(_confounder));
    2847             : 
    2848           2 :         torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
    2849             : 
    2850           2 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
    2851             :                 "SetUserInfo failed");
    2852           2 :         torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
    2853             :                         __location__, __FUNCTION__,
    2854             :                         oldpass, "RANDOM", nt_errstr(s.out.result));
    2855           2 :         if (!NT_STATUS_IS_OK(s.out.result)) {
    2856           0 :                 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u failed - %s\n",
    2857           0 :                        s.in.level, nt_errstr(s.out.result));
    2858           0 :                 ret = false;
    2859             :         }
    2860             : 
    2861           2 :         torture_comment(tctx, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
    2862             : 
    2863           2 :         mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
    2864             : 
    2865           2 :         new_random_pass = samr_very_rand_pass(tctx, 128);
    2866             : 
    2867           2 :         mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
    2868             : 
    2869           2 :         set_pw_in_buffer(nt_pass.data, &new_random_pass);
    2870             : 
    2871           2 :         gnutls_cipher_init(&cipher_hnd,
    2872             :                            GNUTLS_CIPHER_ARCFOUR_128,
    2873             :                            &old_nt_key,
    2874             :                            NULL);
    2875           2 :         gnutls_cipher_encrypt(cipher_hnd,
    2876             :                               nt_pass.data,
    2877             :                               516);
    2878           2 :         gnutls_cipher_deinit(cipher_hnd);
    2879             : 
    2880           2 :         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
    2881             : 
    2882           2 :         r.in.server = &server;
    2883           2 :         r.in.account = &account;
    2884           2 :         r.in.nt_password = &nt_pass;
    2885           2 :         r.in.nt_verifier = &nt_verifier;
    2886           2 :         r.in.lm_change = 0;
    2887           2 :         r.in.lm_password = NULL;
    2888           2 :         r.in.lm_verifier = NULL;
    2889           2 :         r.in.password3 = NULL;
    2890           2 :         r.out.dominfo = &dominfo;
    2891           2 :         r.out.reject = &reject;
    2892             : 
    2893           2 :         unix_to_nt_time(&t, time(NULL));
    2894             : 
    2895           2 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
    2896             :                 "ChangePasswordUser3 failed");
    2897           2 :         torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
    2898             :                         __location__, __FUNCTION__,
    2899             :                         oldpass, "RANDOM", nt_errstr(r.out.result));
    2900             : 
    2901           2 :         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
    2902           0 :                 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
    2903           0 :                         torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
    2904           0 :                                SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
    2905           0 :                         return false;
    2906             :                 }
    2907             :                 /* Perhaps the server has a 'min password age' set? */
    2908             : 
    2909           2 :         } else if (!NT_STATUS_IS_OK(r.out.result)) {
    2910           0 :                 torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser3 failed - %s\n", nt_errstr(r.out.result));
    2911           0 :                 ret = false;
    2912             :         }
    2913             : 
    2914           2 :         newpass = samr_rand_pass(tctx, 128);
    2915             : 
    2916           2 :         mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
    2917             : 
    2918           2 :         E_md4hash(newpass, new_nt_hash);
    2919             : 
    2920           2 :         status = init_samr_CryptPassword(newpass,
    2921             :                                          &old_nt_hash_blob,
    2922             :                                          &nt_pass);
    2923           2 :         torture_assert_ntstatus_ok(tctx,
    2924             :                                    status,
    2925             :                                    "init_samr_CryptPassword failed");
    2926             : 
    2927           2 :         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
    2928             : 
    2929           2 :         r.in.server = &server;
    2930           2 :         r.in.account = &account;
    2931           2 :         r.in.nt_password = &nt_pass;
    2932           2 :         r.in.nt_verifier = &nt_verifier;
    2933           2 :         r.in.lm_change = 0;
    2934           2 :         r.in.lm_password = NULL;
    2935           2 :         r.in.lm_verifier = NULL;
    2936           2 :         r.in.password3 = NULL;
    2937           2 :         r.out.dominfo = &dominfo;
    2938           2 :         r.out.reject = &reject;
    2939             : 
    2940           2 :         unix_to_nt_time(&t, time(NULL));
    2941             : 
    2942           2 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
    2943             :                 "ChangePasswordUser3 failed");
    2944           2 :         torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
    2945             :                         __location__, __FUNCTION__,
    2946             :                         oldpass, newpass, nt_errstr(r.out.result));
    2947             : 
    2948           2 :         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
    2949           0 :                 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
    2950           0 :                         torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
    2951           0 :                                SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
    2952           0 :                         return false;
    2953             :                 }
    2954             :                 /* Perhaps the server has a 'min password age' set? */
    2955             : 
    2956             :         } else {
    2957           2 :                 torture_assert_ntstatus_ok(tctx, r.out.result, "ChangePasswordUser3 (on second random password)");
    2958           2 :                 *password = talloc_strdup(tctx, newpass);
    2959             :         }
    2960             : 
    2961           2 :         return ret;
    2962             : }
    2963             : 
    2964             : 
    2965         141 : static bool test_GetMembersInAlias(struct dcerpc_binding_handle *b,
    2966             :                                    struct torture_context *tctx,
    2967             :                                    struct policy_handle *alias_handle)
    2968             : {
    2969             :         struct samr_GetMembersInAlias r;
    2970             :         struct lsa_SidArray sids;
    2971             : 
    2972         141 :         torture_comment(tctx, "Testing GetMembersInAlias\n");
    2973             : 
    2974         141 :         r.in.alias_handle = alias_handle;
    2975         141 :         r.out.sids = &sids;
    2976             : 
    2977         141 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetMembersInAlias_r(b, tctx, &r),
    2978             :                 "GetMembersInAlias failed");
    2979         141 :         torture_assert_ntstatus_ok(tctx, r.out.result, "GetMembersInAlias failed");
    2980             : 
    2981         141 :         return true;
    2982             : }
    2983             : 
    2984           7 : static bool test_AddMemberToAlias(struct dcerpc_binding_handle *b,
    2985             :                                   struct torture_context *tctx,
    2986             :                                   struct policy_handle *alias_handle,
    2987             :                                   const struct dom_sid *domain_sid)
    2988             : {
    2989             :         struct samr_AddAliasMember r;
    2990             :         struct samr_DeleteAliasMember d;
    2991             :         struct dom_sid *sid;
    2992             : 
    2993           7 :         sid = dom_sid_add_rid(tctx, domain_sid, 512);
    2994             : 
    2995           7 :         torture_comment(tctx, "Testing AddAliasMember\n");
    2996           7 :         r.in.alias_handle = alias_handle;
    2997           7 :         r.in.sid = sid;
    2998             : 
    2999           7 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddAliasMember_r(b, tctx, &r),
    3000             :                 "AddAliasMember failed");
    3001           7 :         torture_assert_ntstatus_ok(tctx, r.out.result, "AddAliasMember failed");
    3002             : 
    3003           7 :         d.in.alias_handle = alias_handle;
    3004           7 :         d.in.sid = sid;
    3005             : 
    3006           7 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteAliasMember_r(b, tctx, &d),
    3007             :                 "DeleteAliasMember failed");
    3008           7 :         torture_assert_ntstatus_ok(tctx, d.out.result, "DelAliasMember failed");
    3009             : 
    3010           7 :         return true;
    3011             : }
    3012             : 
    3013           0 : static bool test_AddMultipleMembersToAlias(struct dcerpc_binding_handle *b,
    3014             :                                            struct torture_context *tctx,
    3015             :                                            struct policy_handle *alias_handle)
    3016             : {
    3017             :         struct samr_AddMultipleMembersToAlias a;
    3018             :         struct samr_RemoveMultipleMembersFromAlias r;
    3019             :         struct lsa_SidArray sids;
    3020             : 
    3021           0 :         torture_comment(tctx, "Testing AddMultipleMembersToAlias\n");
    3022           0 :         a.in.alias_handle = alias_handle;
    3023           0 :         a.in.sids = &sids;
    3024             : 
    3025           0 :         sids.num_sids = 3;
    3026           0 :         sids.sids = talloc_array(tctx, struct lsa_SidPtr, 3);
    3027             : 
    3028           0 :         sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
    3029           0 :         sids.sids[1].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-2");
    3030           0 :         sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-3");
    3031             : 
    3032           0 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddMultipleMembersToAlias_r(b, tctx, &a),
    3033             :                 "AddMultipleMembersToAlias failed");
    3034           0 :         torture_assert_ntstatus_ok(tctx, a.out.result, "AddMultipleMembersToAlias");
    3035             : 
    3036             : 
    3037           0 :         torture_comment(tctx, "Testing RemoveMultipleMembersFromAlias\n");
    3038           0 :         r.in.alias_handle = alias_handle;
    3039           0 :         r.in.sids = &sids;
    3040             : 
    3041           0 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMultipleMembersFromAlias_r(b, tctx, &r),
    3042             :                 "RemoveMultipleMembersFromAlias failed");
    3043           0 :         torture_assert_ntstatus_ok(tctx, r.out.result, "RemoveMultipleMembersFromAlias failed");
    3044             : 
    3045             :         /* strange! removing twice doesn't give any error */
    3046           0 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMultipleMembersFromAlias_r(b, tctx, &r),
    3047             :                 "RemoveMultipleMembersFromAlias failed");
    3048           0 :         torture_assert_ntstatus_ok(tctx, r.out.result, "RemoveMultipleMembersFromAlias failed");
    3049             : 
    3050             :         /* but removing an alias that isn't there does */
    3051           0 :         sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-4");
    3052             : 
    3053           0 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMultipleMembersFromAlias_r(b, tctx, &r),
    3054             :                 "RemoveMultipleMembersFromAlias failed");
    3055           0 :         torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND, "RemoveMultipleMembersFromAlias");
    3056             : 
    3057           0 :         return true;
    3058             : }
    3059             : 
    3060          14 : static bool test_GetAliasMembership(struct dcerpc_binding_handle *b,
    3061             :                                     struct torture_context *tctx,
    3062             :                                     struct policy_handle *domain_handle)
    3063             : {
    3064             :         struct samr_GetAliasMembership r;
    3065             :         struct lsa_SidArray sids;
    3066             :         struct samr_Ids rids;
    3067             : 
    3068          14 :         torture_comment(tctx, "Testing GetAliasMembership\n");
    3069             : 
    3070          14 :         r.in.domain_handle      = domain_handle;
    3071          14 :         r.in.sids               = &sids;
    3072          14 :         r.out.rids              = &rids;
    3073             : 
    3074          14 :         sids.num_sids = 0;
    3075          14 :         sids.sids = talloc_zero_array(tctx, struct lsa_SidPtr, sids.num_sids);
    3076             : 
    3077          14 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetAliasMembership_r(b, tctx, &r),
    3078             :                 "GetAliasMembership failed");
    3079          14 :         torture_assert_ntstatus_ok(tctx, r.out.result,
    3080             :                 "samr_GetAliasMembership failed");
    3081             : 
    3082          14 :         torture_assert_int_equal(tctx, sids.num_sids, rids.count,
    3083             :                 "protocol misbehaviour");
    3084             : 
    3085          14 :         sids.num_sids = 1;
    3086          14 :         sids.sids = talloc_zero_array(tctx, struct lsa_SidPtr, sids.num_sids);
    3087          14 :         sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
    3088             : 
    3089          14 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetAliasMembership_r(b, tctx, &r),
    3090             :                 "samr_GetAliasMembership failed");
    3091          14 :         torture_assert_ntstatus_ok(tctx, r.out.result,
    3092             :                 "samr_GetAliasMembership failed");
    3093             : 
    3094             : #if 0
    3095             :         /* only true for w2k8 it seems
    3096             :          * win7, xp, w2k3 will return a 0 length array pointer */
    3097             : 
    3098             :         if (rids.ids && (rids.count == 0)) {
    3099             :                 torture_fail(tctx, "samr_GetAliasMembership returned 0 count and a rids array");
    3100             :         }
    3101             : #endif
    3102          14 :         if (!rids.ids && rids.count) {
    3103           0 :                 torture_fail(tctx, "samr_GetAliasMembership returned non-0 count but no rids");
    3104             :         }
    3105             : 
    3106          14 :         return true;
    3107             : }
    3108             : 
    3109          16 : static bool test_TestPrivateFunctionsUser(struct dcerpc_binding_handle *b,
    3110             :                                           struct torture_context *tctx,
    3111             :                                           struct policy_handle *user_handle)
    3112             : {
    3113             :         struct samr_TestPrivateFunctionsUser r;
    3114             : 
    3115          16 :         torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
    3116             : 
    3117          16 :         r.in.user_handle = user_handle;
    3118             : 
    3119          16 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_TestPrivateFunctionsUser_r(b, tctx, &r),
    3120             :                 "TestPrivateFunctionsUser failed");
    3121          14 :         torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
    3122             : 
    3123          14 :         return true;
    3124             : }
    3125             : 
    3126         608 : static bool test_QueryUserInfo_pwdlastset(struct dcerpc_binding_handle *b,
    3127             :                                           struct torture_context *tctx,
    3128             :                                           struct policy_handle *handle,
    3129             :                                           bool use_info2,
    3130             :                                           NTTIME *pwdlastset)
    3131             : {
    3132             :         NTSTATUS status;
    3133         608 :         uint16_t levels[] = { /* 3, */ 5, 21 };
    3134             :         int i;
    3135             :         /* NTTIME pwdlastset3 = 0; */
    3136         608 :         NTTIME pwdlastset5 = 0;
    3137         608 :         NTTIME pwdlastset21 = 0;
    3138             : 
    3139         608 :         torture_comment(tctx, "Testing QueryUserInfo%s level 5 and 21 call ",
    3140             :                         use_info2 ? "2":"");
    3141             : 
    3142        1824 :         for (i=0; i<ARRAY_SIZE(levels); i++) {
    3143             : 
    3144             :                 struct samr_QueryUserInfo r;
    3145             :                 struct samr_QueryUserInfo2 r2;
    3146             :                 union samr_UserInfo *info;
    3147             : 
    3148        1216 :                 if (use_info2) {
    3149           0 :                         r2.in.user_handle = handle;
    3150           0 :                         r2.in.level = levels[i];
    3151           0 :                         r2.out.info = &info;
    3152           0 :                         torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo2_r(b, tctx, &r2),
    3153             :                                 "QueryUserInfo2 failed");
    3154           0 :                         status = r2.out.result;
    3155             : 
    3156             :                 } else {
    3157        1216 :                         r.in.user_handle = handle;
    3158        1216 :                         r.in.level = levels[i];
    3159        1216 :                         r.out.info = &info;
    3160        1216 :                         torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
    3161             :                                 "QueryUserInfo failed");
    3162        1216 :                         status = r.out.result;
    3163             :                 }
    3164             : 
    3165        1216 :                 if (!NT_STATUS_IS_OK(status) &&
    3166           0 :                     !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
    3167           0 :                         torture_result(tctx, TORTURE_FAIL, "QueryUserInfo%s level %u failed - %s\n",
    3168           0 :                                use_info2 ? "2":"", levels[i], nt_errstr(status));
    3169           0 :                         return false;
    3170             :                 }
    3171             : 
    3172        1216 :                 switch (levels[i]) {
    3173           0 :                 case 3:
    3174             :                         /* pwdlastset3 = info->info3.last_password_change; */
    3175           0 :                         break;
    3176         608 :                 case 5:
    3177         608 :                         pwdlastset5 = info->info5.last_password_change;
    3178         608 :                         break;
    3179         608 :                 case 21:
    3180         608 :                         pwdlastset21 = info->info21.last_password_change;
    3181         608 :                         break;
    3182           0 :                 default:
    3183           0 :                         return false;
    3184             :                 }
    3185             :         }
    3186             :         /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
    3187             :                                     "pwdlastset mixup"); */
    3188         608 :         torture_assert_int_equal(tctx, pwdlastset5, pwdlastset21,
    3189             :                                  "pwdlastset mixup");
    3190             : 
    3191         608 :         *pwdlastset = pwdlastset21;
    3192             : 
    3193         608 :         torture_comment(tctx, "(pwdlastset: %llu)\n",
    3194             :                         (unsigned long long) *pwdlastset);
    3195             : 
    3196         608 :         return true;
    3197             : }
    3198             : 
    3199        1174 : static bool test_SamLogon(struct torture_context *tctx,
    3200             :                           struct dcerpc_pipe *p,
    3201             :                           struct cli_credentials *machine_credentials,
    3202             :                           struct cli_credentials *test_credentials,
    3203             :                           NTSTATUS expected_result,
    3204             :                           bool interactive)
    3205             : {
    3206             :         NTSTATUS status;
    3207             :         struct netr_LogonSamLogonEx r;
    3208             :         union netr_LogonLevel logon;
    3209             :         union netr_Validation validation;
    3210             :         uint8_t authoritative;
    3211             :         struct netr_IdentityInfo identity;
    3212             :         struct netr_NetworkInfo ninfo;
    3213             :         struct netr_PasswordInfo pinfo;
    3214             :         DATA_BLOB names_blob, chal, lm_resp, nt_resp;
    3215        1174 :         int flags = CLI_CRED_NTLM_AUTH;
    3216        1174 :         uint32_t samlogon_flags = 0;
    3217             :         struct netlogon_creds_CredentialState *creds;
    3218             :         struct netr_Authenticator a;
    3219        1174 :         struct dcerpc_binding_handle *b = p->binding_handle;
    3220             : 
    3221        1174 :         torture_assert(tctx, (creds = cli_credentials_get_netlogon_creds(machine_credentials)), "");
    3222             : 
    3223        1174 :         if (lpcfg_client_lanman_auth(tctx->lp_ctx)) {
    3224        1174 :                 flags |= CLI_CRED_LANMAN_AUTH;
    3225             :         }
    3226             : 
    3227        1174 :         if (lpcfg_client_ntlmv2_auth(tctx->lp_ctx)) {
    3228        1174 :                 flags |= CLI_CRED_NTLMv2_AUTH;
    3229             :         }
    3230             : 
    3231        1174 :         cli_credentials_get_ntlm_username_domain(test_credentials, tctx,
    3232             :                                                  &identity.account_name.string,
    3233             :                                                  &identity.domain_name.string);
    3234             : 
    3235        1174 :         identity.parameter_control =
    3236             :                 MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT |
    3237             :                 MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
    3238        1174 :         identity.logon_id = 0;
    3239        1174 :         identity.workstation.string = cli_credentials_get_workstation(test_credentials);
    3240             : 
    3241        1174 :         if (interactive) {
    3242         304 :                 netlogon_creds_client_authenticator(creds, &a);
    3243             : 
    3244         304 :                 if (!E_deshash(cli_credentials_get_password(test_credentials), pinfo.lmpassword.hash)) {
    3245           0 :                         ZERO_STRUCT(pinfo.lmpassword.hash);
    3246             :                 }
    3247         304 :                 E_md4hash(cli_credentials_get_password(test_credentials), pinfo.ntpassword.hash);
    3248             : 
    3249         304 :                 if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
    3250         304 :                         netlogon_creds_aes_encrypt(creds, pinfo.lmpassword.hash, 16);
    3251         304 :                         netlogon_creds_aes_encrypt(creds, pinfo.ntpassword.hash, 16);
    3252           0 :                 } else if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
    3253           0 :                         netlogon_creds_arcfour_crypt(creds, pinfo.lmpassword.hash, 16);
    3254           0 :                         netlogon_creds_arcfour_crypt(creds, pinfo.ntpassword.hash, 16);
    3255             :                 } else {
    3256           0 :                         netlogon_creds_des_encrypt(creds, &pinfo.lmpassword);
    3257           0 :                         netlogon_creds_des_encrypt(creds, &pinfo.ntpassword);
    3258             :                 }
    3259             : 
    3260         304 :                 pinfo.identity_info = identity;
    3261         304 :                 logon.password = &pinfo;
    3262             : 
    3263         304 :                 r.in.logon_level = NetlogonInteractiveInformation;
    3264             :         } else {
    3265         870 :                 generate_random_buffer(ninfo.challenge,
    3266             :                                        sizeof(ninfo.challenge));
    3267         870 :                 chal = data_blob_const(ninfo.challenge,
    3268             :                                        sizeof(ninfo.challenge));
    3269             : 
    3270         870 :                 names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(test_credentials),
    3271             :                                                         cli_credentials_get_domain(test_credentials));
    3272             : 
    3273         870 :                 status = cli_credentials_get_ntlm_response(test_credentials, tctx,
    3274             :                                                            &flags,
    3275             :                                                            chal,
    3276             :                                                            NULL, /* server_timestamp */
    3277             :                                                            names_blob,
    3278             :                                                            &lm_resp, &nt_resp,
    3279             :                                                            NULL, NULL);
    3280         870 :                 torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
    3281             : 
    3282         870 :                 ninfo.lm.data = lm_resp.data;
    3283         870 :                 ninfo.lm.length = lm_resp.length;
    3284             : 
    3285         870 :                 ninfo.nt.data = nt_resp.data;
    3286         870 :                 ninfo.nt.length = nt_resp.length;
    3287             : 
    3288         870 :                 ninfo.identity_info = identity;
    3289         870 :                 logon.network = &ninfo;
    3290             : 
    3291         870 :                 r.in.logon_level = NetlogonNetworkInformation;
    3292             :         }
    3293             : 
    3294        1174 :         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
    3295        1174 :         r.in.computer_name = cli_credentials_get_workstation(test_credentials);
    3296        1174 :         r.in.logon = &logon;
    3297        1174 :         r.in.flags = &samlogon_flags;
    3298        1174 :         r.out.flags = &samlogon_flags;
    3299        1174 :         r.out.validation = &validation;
    3300        1174 :         r.out.authoritative = &authoritative;
    3301             : 
    3302        1174 :         torture_comment(tctx, "Testing LogonSamLogon with name %s\n", identity.account_name.string);
    3303             : 
    3304        1174 :         r.in.validation_level = 6;
    3305             : 
    3306        1174 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogonEx_r(b, tctx, &r),
    3307             :                 "netr_LogonSamLogonEx failed");
    3308        1174 :         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_INFO_CLASS)) {
    3309         290 :                 r.in.validation_level = 3;
    3310         290 :                 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogonEx_r(b, tctx, &r),
    3311             :                         "netr_LogonSamLogonEx failed");
    3312             :         }
    3313        1174 :         if (!NT_STATUS_IS_OK(r.out.result)) {
    3314         972 :                 torture_assert_ntstatus_equal(tctx, r.out.result, expected_result, "LogonSamLogonEx failed");
    3315         968 :                 return true;
    3316             :         } else {
    3317         202 :                 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogonEx failed");
    3318             :         }
    3319             : 
    3320         202 :         return true;
    3321             : }
    3322             : 
    3323        1174 : static bool test_SamLogon_with_creds(struct torture_context *tctx,
    3324             :                                      struct dcerpc_pipe *p,
    3325             :                                      struct cli_credentials *machine_creds,
    3326             :                                      const char *acct_name,
    3327             :                                      const char *password,
    3328             :                                      NTSTATUS expected_samlogon_result,
    3329             :                                      bool interactive)
    3330             : {
    3331        1174 :         bool ret = true;
    3332             :         struct cli_credentials *test_credentials;
    3333             : 
    3334        1174 :         test_credentials = cli_credentials_init(tctx);
    3335             : 
    3336        1174 :         cli_credentials_set_workstation(test_credentials,
    3337             :                                         cli_credentials_get_workstation(machine_creds), CRED_SPECIFIED);
    3338        1174 :         cli_credentials_set_domain(test_credentials,
    3339             :                                    cli_credentials_get_domain(machine_creds), CRED_SPECIFIED);
    3340        1174 :         cli_credentials_set_username(test_credentials,
    3341             :                                      acct_name, CRED_SPECIFIED);
    3342        1174 :         cli_credentials_set_password(test_credentials,
    3343             :                                      password, CRED_SPECIFIED);
    3344             : 
    3345        1174 :         torture_comment(tctx, "Testing samlogon (%s) as %s password: %s\n",
    3346             :                 interactive ? "interactive" : "network", acct_name, password);
    3347             : 
    3348        1174 :         if (!test_SamLogon(tctx, p, machine_creds, test_credentials,
    3349             :                             expected_samlogon_result, interactive)) {
    3350           4 :                 torture_result(tctx, TORTURE_FAIL, "new password did not work\n");
    3351           4 :                 ret = false;
    3352             :         }
    3353             : 
    3354        1174 :         return ret;
    3355             : }
    3356             : 
    3357         608 : static bool test_SetPassword_level(struct dcerpc_pipe *p,
    3358             :                                    struct dcerpc_pipe *np,
    3359             :                                    struct torture_context *tctx,
    3360             :                                    struct policy_handle *handle,
    3361             :                                    uint16_t level,
    3362             :                                    uint32_t fields_present,
    3363             :                                    uint8_t password_expired,
    3364             :                                    bool *matched_expected_error,
    3365             :                                    bool use_setinfo2,
    3366             :                                    const char *acct_name,
    3367             :                                    char **password,
    3368             :                                    struct cli_credentials *machine_creds,
    3369             :                                    bool use_queryinfo2,
    3370             :                                    NTTIME *pwdlastset,
    3371             :                                    NTSTATUS expected_samlogon_result)
    3372             : {
    3373         608 :         const char *fields = NULL;
    3374         608 :         bool ret = true;
    3375         608 :         struct dcerpc_binding_handle *b = p->binding_handle;
    3376             : 
    3377         608 :         switch (level) {
    3378         480 :         case 21:
    3379             :         case 23:
    3380             :         case 25:
    3381         480 :                 fields = talloc_asprintf(tctx, "(fields_present: 0x%08x)",
    3382             :                                          fields_present);
    3383         480 :                 break;
    3384         128 :         default:
    3385         128 :                 break;
    3386             :         }
    3387             : 
    3388         608 :         torture_comment(tctx, "Testing SetUserInfo%s level %d call "
    3389             :                 "(password_expired: %d) %s\n",
    3390             :                 use_setinfo2 ? "2":"", level, password_expired,
    3391             :                 fields ? fields : "");
    3392             : 
    3393         608 :         if (!test_SetUserPass_level_ex(p, tctx, handle, level,
    3394             :                                        fields_present,
    3395             :                                        password,
    3396             :                                        password_expired,
    3397             :                                        use_setinfo2,
    3398             :                                        matched_expected_error)) {
    3399           0 :                 ret = false;
    3400             :         }
    3401             : 
    3402         608 :         if (!test_QueryUserInfo_pwdlastset(b, tctx, handle,
    3403             :                                            use_queryinfo2,
    3404             :                                            pwdlastset)) {
    3405           0 :                 ret = false;
    3406             :         }
    3407             : 
    3408         608 :         if (*matched_expected_error == true) {
    3409          96 :                 return ret;
    3410             :         }
    3411             : 
    3412         512 :         if (!test_SamLogon_with_creds(tctx, np,
    3413             :                                       machine_creds,
    3414             :                                       acct_name,
    3415             :                                       *password,
    3416             :                                       expected_samlogon_result,
    3417             :                                       false)) {
    3418           0 :                 ret = false;
    3419             :         }
    3420             : 
    3421         512 :         return ret;
    3422             : }
    3423             : 
    3424          22 : static bool setup_schannel_netlogon_pipe(struct torture_context *tctx,
    3425             :                                          struct cli_credentials *credentials,
    3426             :                                          struct dcerpc_pipe **p)
    3427             : {
    3428             :         struct dcerpc_binding *b;
    3429             :         NTSTATUS status;
    3430             : 
    3431          22 :         torture_assert_ntstatus_ok(tctx, torture_rpc_binding(tctx, &b),
    3432             :                 "failed to get rpc binding");
    3433             : 
    3434             :         /* We have to use schannel, otherwise the SamLogonEx fails
    3435             :          * with INTERNAL_ERROR */
    3436             : 
    3437          22 :         status = dcerpc_binding_set_flags(b,
    3438             :                                           DCERPC_SCHANNEL |
    3439             :                                           DCERPC_SIGN | DCERPC_SEAL |
    3440             :                                           DCERPC_SCHANNEL_AUTO,
    3441             :                                           DCERPC_AUTH_OPTIONS);
    3442          22 :         torture_assert_ntstatus_ok(tctx, status, "set flags");
    3443             : 
    3444          22 :         torture_assert_ntstatus_ok(tctx,
    3445             :                 dcerpc_pipe_connect_b(tctx, p, b, &ndr_table_netlogon,
    3446             :                                       credentials, tctx->ev, tctx->lp_ctx),
    3447             :                 "failed to bind to netlogon");
    3448             : 
    3449          22 :         return true;
    3450             : }
    3451             : 
    3452           8 : static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
    3453             :                                         struct torture_context *tctx,
    3454             :                                         uint32_t acct_flags,
    3455             :                                         const char *acct_name,
    3456             :                                         struct policy_handle *handle,
    3457             :                                         char **password,
    3458             :                                         struct cli_credentials *machine_credentials)
    3459             : {
    3460           8 :         int s = 0, q = 0, f = 0, l = 0, z = 0;
    3461           8 :         bool ret = true;
    3462           8 :         int delay = 50000;
    3463           8 :         bool set_levels[] = { false, true };
    3464           8 :         bool query_levels[] = { false, true };
    3465           8 :         uint32_t levels[] = { 18, 21, 26, 23, 24, 25 }; /* Second half only used when TEST_ALL_LEVELS defined */
    3466           8 :         uint32_t nonzeros[] = { 1, 24 };
    3467           8 :         uint32_t fields_present[] = {
    3468             :                 0,
    3469             :                 SAMR_FIELD_EXPIRED_FLAG,
    3470             :                 SAMR_FIELD_LAST_PWD_CHANGE,
    3471             :                 SAMR_FIELD_EXPIRED_FLAG | SAMR_FIELD_LAST_PWD_CHANGE,
    3472             :                 SAMR_FIELD_COMMENT,
    3473             :                 SAMR_FIELD_NT_PASSWORD_PRESENT,
    3474             :                 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
    3475             :                 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
    3476             :                 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
    3477             :                 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
    3478             :                 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
    3479             :                 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE | SAMR_FIELD_EXPIRED_FLAG
    3480             :         };
    3481           8 :         struct dcerpc_pipe *np = NULL;
    3482             : 
    3483          12 :         if (torture_setting_bool(tctx, "samba3", false) ||
    3484           4 :             torture_setting_bool(tctx, "samba4", false)) {
    3485           8 :                 delay = 999999;
    3486           8 :                 torture_comment(tctx, "Samba3 has second granularity, setting delay to: %d\n",
    3487             :                         delay);
    3488             :         }
    3489             : 
    3490           8 :         torture_assert(tctx, setup_schannel_netlogon_pipe(tctx, machine_credentials, &np), "");
    3491             : 
    3492             :         /* set to 1 to enable testing for all possible opcode
    3493             :            (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
    3494             :            combinations */
    3495             : #if 0
    3496             : #define TEST_ALL_LEVELS 1
    3497             : #define TEST_SET_LEVELS 1
    3498             : #define TEST_QUERY_LEVELS 1
    3499             : #endif
    3500             : #ifdef TEST_ALL_LEVELS
    3501             :         for (l=0; l<ARRAY_SIZE(levels); l++) {
    3502             : #else
    3503          32 :         for (l=0; l<(ARRAY_SIZE(levels))/2; l++) {
    3504             : #endif
    3505          72 :         for (z=0; z<ARRAY_SIZE(nonzeros); z++) {
    3506         272 :         for (f=0; f<ARRAY_SIZE(fields_present); f++) {
    3507             : #ifdef TEST_SET_LEVELS
    3508             :         for (s=0; s<ARRAY_SIZE(set_levels); s++) {
    3509             : #endif
    3510             : #ifdef TEST_QUERY_LEVELS
    3511             :         for (q=0; q<ARRAY_SIZE(query_levels); q++) {
    3512             : #endif
    3513         224 :                 NTTIME pwdlastset_old = 0;
    3514         224 :                 NTTIME pwdlastset_new = 0;
    3515         224 :                 bool matched_expected_error = false;
    3516         224 :                 NTSTATUS expected_samlogon_result = NT_STATUS_ACCOUNT_DISABLED;
    3517             : 
    3518         224 :                 torture_comment(tctx, "------------------------------\n"
    3519             :                                 "Testing pwdLastSet attribute for flags: 0x%08x "
    3520             :                                 "(s: %d (l: %d), q: %d)\n",
    3521             :                                 acct_flags, s, levels[l], q);
    3522             : 
    3523         224 :                 switch (levels[l]) {
    3524         192 :                 case 21:
    3525             :                 case 23:
    3526             :                 case 25:
    3527         262 :                         if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
    3528          80 :                               (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT))) {
    3529          80 :                                 expected_samlogon_result = NT_STATUS_WRONG_PASSWORD;
    3530             :                         }
    3531         192 :                         break;
    3532             :                 }
    3533             : 
    3534             : 
    3535             :                 /* set #1 */
    3536             : 
    3537             :                 /* set a password and force password change (pwdlastset 0) by
    3538             :                  * setting the password expired flag to a non-0 value */
    3539             : 
    3540         812 :                 if (!test_SetPassword_level(p, np, tctx, handle,
    3541         224 :                                             levels[l],
    3542             :                                             fields_present[f],
    3543         224 :                                             nonzeros[z],
    3544             :                                             &matched_expected_error,
    3545         224 :                                             set_levels[s],
    3546             :                                             acct_name,
    3547             :                                             password,
    3548             :                                             machine_credentials,
    3549         224 :                                             query_levels[q],
    3550             :                                             &pwdlastset_new,
    3551             :                                             expected_samlogon_result)) {
    3552           0 :                         ret = false;
    3553             :                 }
    3554             : 
    3555         224 :                 if (matched_expected_error == true) {
    3556             :                         /* skipping on expected failure */
    3557          96 :                         continue;
    3558             :                 }
    3559             : 
    3560             :                 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
    3561             :                  * set without the SAMR_FIELD_EXPIRED_FLAG */
    3562             : 
    3563         128 :                 switch (levels[l]) {
    3564          96 :                 case 21:
    3565             :                 case 23:
    3566             :                 case 25:
    3567         124 :                         if ((pwdlastset_new != 0) &&
    3568          32 :                             !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
    3569          32 :                                 torture_comment(tctx, "not considering a non-0 "
    3570             :                                         "pwdLastSet as a an error as the "
    3571             :                                         "SAMR_FIELD_EXPIRED_FLAG has not "
    3572             :                                         "been set\n");
    3573          32 :                                 break;
    3574             :                         }
    3575          64 :                         break;
    3576          32 :                 default:
    3577          32 :                         if (pwdlastset_new != 0) {
    3578           0 :                                 torture_result(tctx, TORTURE_FAIL, "pwdLastSet test failed: "
    3579             :                                         "expected pwdLastSet 0 but got %llu\n",
    3580             :                                         (unsigned long long) pwdlastset_old);
    3581           0 :                                 ret = false;
    3582             :                         }
    3583          32 :                         break;
    3584             :                 }
    3585             : 
    3586         128 :                 switch (levels[l]) {
    3587          96 :                 case 21:
    3588             :                 case 23:
    3589             :                 case 25:
    3590         124 :                         if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
    3591          96 :                              (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
    3592           0 :                              (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
    3593           0 :                              (pwdlastset_old >= pwdlastset_new)) {
    3594           0 :                                 torture_result(tctx, TORTURE_FAIL, "pwdlastset not increasing\n");
    3595           0 :                                 ret = false;
    3596             :                         }
    3597          96 :                         break;
    3598             :                 }
    3599             : 
    3600         128 :                 pwdlastset_old = pwdlastset_new;
    3601             : 
    3602         128 :                 usleep(delay);
    3603             : 
    3604             :                 /* set #2 */
    3605             : 
    3606             :                 /* set a password, pwdlastset needs to get updated (increased
    3607             :                  * value), password_expired value used here is 0 */
    3608             : 
    3609         352 :                 if (!test_SetPassword_level(p, np, tctx, handle,
    3610         128 :                                             levels[l],
    3611             :                                             fields_present[f],
    3612             :                                             0,
    3613             :                                             &matched_expected_error,
    3614         128 :                                             set_levels[s],
    3615             :                                             acct_name,
    3616             :                                             password,
    3617             :                                             machine_credentials,
    3618         128 :                                             query_levels[q],
    3619             :                                             &pwdlastset_new,
    3620             :                                             expected_samlogon_result)) {
    3621           0 :                         ret = false;
    3622             :                 }
    3623             : 
    3624             :                 /* when a password has been changed, pwdlastset must not be 0 afterwards
    3625             :                  * and must be larger then the old value */
    3626             : 
    3627         128 :                 switch (levels[l]) {
    3628          96 :                 case 21:
    3629             :                 case 23:
    3630             :                 case 25:
    3631             :                         /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
    3632             :                          * password has been changed, old and new pwdlastset
    3633             :                          * need to be the same value */
    3634             : 
    3635         138 :                         if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
    3636          62 :                             !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
    3637          16 :                               (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
    3638             :                         {
    3639          16 :                                 torture_assert_int_equal(tctx, pwdlastset_old,
    3640             :                                         pwdlastset_new, "pwdlastset must be equal");
    3641          16 :                                 break;
    3642             :                         }
    3643          80 :                         break;
    3644          32 :                 default:
    3645          32 :                         if (pwdlastset_old >= pwdlastset_new) {
    3646           0 :                                 torture_result(tctx, TORTURE_FAIL, "pwdLastSet test failed: "
    3647             :                                         "expected last pwdlastset (%llu) < new pwdlastset (%llu)\n",
    3648             :                                         (unsigned long long) pwdlastset_old,
    3649             :                                         (unsigned long long) pwdlastset_new);
    3650           0 :                                 ret = false;
    3651             :                         }
    3652          32 :                         if (pwdlastset_new == 0) {
    3653           0 :                                 torture_result(tctx, TORTURE_FAIL, "pwdLastSet test failed: "
    3654             :                                         "expected non-0 pwdlastset, got: %llu\n",
    3655             :                                         (unsigned long long) pwdlastset_new);
    3656           0 :                                 ret = false;
    3657             :                         }
    3658          32 :                         break;
    3659             :                 }
    3660             : 
    3661         128 :                 switch (levels[l]) {
    3662          96 :                 case 21:
    3663             :                 case 23:
    3664             :                 case 25:
    3665         124 :                         if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
    3666          96 :                              (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
    3667          60 :                              (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
    3668          32 :                              (pwdlastset_old >= pwdlastset_new)) {
    3669           0 :                                 torture_result(tctx, TORTURE_FAIL, "pwdlastset not increasing\n");
    3670           0 :                                 ret = false;
    3671             :                         }
    3672          96 :                         break;
    3673             :                 }
    3674             : 
    3675         128 :                 pwdlastset_old = pwdlastset_new;
    3676             : 
    3677         128 :                 usleep(delay);
    3678             : 
    3679             :                 /* set #2b */
    3680             : 
    3681             :                 /* set a password, pwdlastset needs to get updated (increased
    3682             :                  * value), password_expired value used here is 0 */
    3683             : 
    3684         352 :                 if (!test_SetPassword_level(p, np, tctx, handle,
    3685         128 :                                             levels[l],
    3686             :                                             fields_present[f],
    3687             :                                             0,
    3688             :                                             &matched_expected_error,
    3689         128 :                                             set_levels[s],
    3690             :                                             acct_name,
    3691             :                                             password,
    3692             :                                             machine_credentials,
    3693         128 :                                             query_levels[q],
    3694             :                                             &pwdlastset_new,
    3695             :                                             expected_samlogon_result)) {
    3696           0 :                         ret = false;
    3697             :                 }
    3698             : 
    3699             :                 /* when a password has been changed, pwdlastset must not be 0 afterwards
    3700             :                  * and must be larger then the old value */
    3701             : 
    3702         128 :                 switch (levels[l]) {
    3703          96 :                 case 21:
    3704             :                 case 23:
    3705             :                 case 25:
    3706             : 
    3707             :                         /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
    3708             :                          * password has been changed, old and new pwdlastset
    3709             :                          * need to be the same value */
    3710             : 
    3711         138 :                         if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
    3712          62 :                             !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
    3713          16 :                               (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
    3714             :                         {
    3715          16 :                                 torture_assert_int_equal(tctx, pwdlastset_old,
    3716             :                                         pwdlastset_new, "pwdlastset must be equal");
    3717          16 :                                 break;
    3718             :                         }
    3719          80 :                         break;
    3720          32 :                 default:
    3721          32 :                         if (pwdlastset_old >= pwdlastset_new) {
    3722           0 :                                 torture_result(tctx, TORTURE_FAIL, "pwdLastSet test failed: "
    3723             :                                         "expected last pwdlastset (%llu) < new pwdlastset (%llu)\n",
    3724             :                                         (unsigned long long) pwdlastset_old,
    3725             :                                         (unsigned long long) pwdlastset_new);
    3726           0 :                                 ret = false;
    3727             :                         }
    3728          32 :                         if (pwdlastset_new == 0) {
    3729           0 :                                 torture_result(tctx, TORTURE_FAIL, "pwdLastSet test failed: "
    3730             :                                         "expected non-0 pwdlastset, got: %llu\n",
    3731             :                                         (unsigned long long) pwdlastset_new);
    3732           0 :                                 ret = false;
    3733             :                         }
    3734          32 :                         break;
    3735             :                 }
    3736             : 
    3737         128 :                 switch (levels[l]) {
    3738          96 :                 case 21:
    3739             :                 case 23:
    3740             :                 case 25:
    3741         124 :                         if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
    3742          96 :                              (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
    3743         120 :                              (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
    3744          64 :                              (pwdlastset_old >= pwdlastset_new)) {
    3745           0 :                                 torture_result(tctx, TORTURE_FAIL, "pwdlastset not increasing\n");
    3746           0 :                                 ret = false;
    3747             :                         }
    3748          96 :                         break;
    3749             :                 }
    3750             : 
    3751         128 :                 pwdlastset_old = pwdlastset_new;
    3752             : 
    3753         128 :                 usleep(delay);
    3754             : 
    3755             :                 /* set #3 */
    3756             : 
    3757             :                 /* set a password and force password change (pwdlastset 0) by
    3758             :                  * setting the password expired flag to a non-0 value */
    3759             : 
    3760         464 :                 if (!test_SetPassword_level(p, np, tctx, handle,
    3761         128 :                                             levels[l],
    3762             :                                             fields_present[f],
    3763         128 :                                             nonzeros[z],
    3764             :                                             &matched_expected_error,
    3765         128 :                                             set_levels[s],
    3766             :                                             acct_name,
    3767             :                                             password,
    3768             :                                             machine_credentials,
    3769         128 :                                             query_levels[q],
    3770             :                                             &pwdlastset_new,
    3771             :                                             expected_samlogon_result)) {
    3772           0 :                         ret = false;
    3773             :                 }
    3774             : 
    3775             :                 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
    3776             :                  * set without the SAMR_FIELD_EXPIRED_FLAG */
    3777             : 
    3778         128 :                 switch (levels[l]) {
    3779          96 :                 case 21:
    3780             :                 case 23:
    3781             :                 case 25:
    3782         124 :                         if ((pwdlastset_new != 0) &&
    3783          32 :                             !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
    3784          32 :                                 torture_comment(tctx, "not considering a non-0 "
    3785             :                                         "pwdLastSet as a an error as the "
    3786             :                                         "SAMR_FIELD_EXPIRED_FLAG has not "
    3787             :                                         "been set\n");
    3788          32 :                                 break;
    3789             :                         }
    3790             : 
    3791             :                         /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
    3792             :                          * password has been changed, old and new pwdlastset
    3793             :                          * need to be the same value */
    3794             : 
    3795          78 :                         if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
    3796          30 :                             !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
    3797          16 :                               (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
    3798             :                         {
    3799          16 :                                 torture_assert_int_equal(tctx, pwdlastset_old,
    3800             :                                         pwdlastset_new, "pwdlastset must be equal");
    3801          16 :                                 break;
    3802             :                         }
    3803          48 :                         break;
    3804          32 :                 default:
    3805          32 :                         if (pwdlastset_new != 0) {
    3806           0 :                                 torture_result(tctx, TORTURE_FAIL, "pwdLastSet test failed: "
    3807             :                                         "expected pwdLastSet 0, got %llu\n",
    3808             :                                         (unsigned long long) pwdlastset_old);
    3809           0 :                                 ret = false;
    3810             :                         }
    3811          32 :                         break;
    3812             :                 }
    3813             : 
    3814         128 :                 switch (levels[l]) {
    3815          96 :                 case 21:
    3816             :                 case 23:
    3817             :                 case 25:
    3818         124 :                         if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
    3819          96 :                              (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
    3820          92 :                              (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
    3821          32 :                              (pwdlastset_old >= pwdlastset_new)) {
    3822           0 :                                 torture_result(tctx, TORTURE_FAIL, "pwdlastset not increasing\n");
    3823           0 :                                 ret = false;
    3824             :                         }
    3825          96 :                         break;
    3826             :                 }
    3827             : 
    3828             :                 /* if the level we are testing does not have a fields_present
    3829             :                  * field, skip all fields present tests by setting f to to
    3830             :                  * arraysize */
    3831         128 :                 switch (levels[l]) {
    3832          32 :                 case 18:
    3833             :                 case 24:
    3834             :                 case 26:
    3835          32 :                         f = ARRAY_SIZE(fields_present);
    3836          32 :                         break;
    3837             :                 }
    3838             : 
    3839             : #ifdef TEST_QUERY_LEVELS
    3840             :         }
    3841             : #endif
    3842             : #ifdef TEST_SET_LEVELS
    3843             :         }
    3844             : #endif
    3845             :         } /* fields present */
    3846             :         } /* nonzeros */
    3847             :         } /* levels */
    3848             : 
    3849             : #undef TEST_SET_LEVELS
    3850             : #undef TEST_QUERY_LEVELS
    3851             : 
    3852           8 :         talloc_free(np);
    3853             : 
    3854           8 :         return ret;
    3855             : }
    3856             : 
    3857         566 : static bool test_QueryUserInfo_badpwdcount(struct dcerpc_binding_handle *b,
    3858             :                                            struct torture_context *tctx,
    3859             :                                            struct policy_handle *handle,
    3860             :                                            uint32_t *badpwdcount)
    3861             : {
    3862             :         union samr_UserInfo *info;
    3863             :         struct samr_QueryUserInfo r;
    3864             : 
    3865         566 :         r.in.user_handle = handle;
    3866         566 :         r.in.level = 3;
    3867         566 :         r.out.info = &info;
    3868             : 
    3869         566 :         torture_comment(tctx, "Testing QueryUserInfo level %d", r.in.level);
    3870             : 
    3871         566 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
    3872             :                 "failed to query userinfo");
    3873         566 :         torture_assert_ntstatus_ok(tctx, r.out.result,
    3874             :                 "failed to query userinfo");
    3875             : 
    3876         566 :         *badpwdcount = info->info3.bad_password_count;
    3877             : 
    3878         566 :         torture_comment(tctx, " (bad password count: %d)\n", *badpwdcount);
    3879             : 
    3880         566 :         return true;
    3881             : }
    3882             : 
    3883          76 : static bool test_SetUserInfo_acct_flags(struct dcerpc_binding_handle *b,
    3884             :                                         struct torture_context *tctx,
    3885             :                                         struct policy_handle *user_handle,
    3886             :                                         uint32_t acct_flags)
    3887             : {
    3888             :         struct samr_SetUserInfo r;
    3889             :         union samr_UserInfo user_info;
    3890             : 
    3891          76 :         torture_comment(tctx, "Testing SetUserInfo level 16\n");
    3892             : 
    3893          76 :         user_info.info16.acct_flags = acct_flags;
    3894             : 
    3895          76 :         r.in.user_handle = user_handle;
    3896          76 :         r.in.level = 16;
    3897          76 :         r.in.info = &user_info;
    3898             : 
    3899          76 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &r),
    3900             :                 "failed to set account flags");
    3901          76 :         torture_assert_ntstatus_ok(tctx, r.out.result,
    3902             :                 "failed to set account flags");
    3903             : 
    3904          76 :         return true;
    3905             : }
    3906             : 
    3907          38 : static bool test_reset_badpwdcount(struct dcerpc_pipe *p,
    3908             :                                    struct torture_context *tctx,
    3909             :                                    struct policy_handle *user_handle,
    3910             :                                    uint32_t acct_flags,
    3911             :                                    char **password)
    3912             : {
    3913          38 :         struct dcerpc_binding_handle *b = p->binding_handle;
    3914             : 
    3915          38 :         torture_assert(tctx, test_SetUserPass(p, tctx, user_handle, password),
    3916             :                 "failed to set password");
    3917             : 
    3918          38 :         torture_comment(tctx, "Testing SetUserInfo level 16 (enable account)\n");
    3919             : 
    3920          38 :         torture_assert(tctx,
    3921             :                        test_SetUserInfo_acct_flags(b, tctx, user_handle,
    3922             :                                                    acct_flags & ~ACB_DISABLED),
    3923             :                        "failed to enable user");
    3924             : 
    3925          38 :         torture_assert(tctx, test_SetUserPass(p, tctx, user_handle, password),
    3926             :                 "failed to set password");
    3927             : 
    3928          38 :         return true;
    3929             : }
    3930             : 
    3931         130 : static bool test_SetDomainInfo(struct dcerpc_binding_handle *b,
    3932             :                                struct torture_context *tctx,
    3933             :                                struct policy_handle *domain_handle,
    3934             :                                enum samr_DomainInfoClass level,
    3935             :                                union samr_DomainInfo *info)
    3936             : {
    3937             :         struct samr_SetDomainInfo r;
    3938             : 
    3939         130 :         r.in.domain_handle = domain_handle;
    3940         130 :         r.in.level = level;
    3941         130 :         r.in.info = info;
    3942             : 
    3943         130 :         torture_assert_ntstatus_ok(tctx,
    3944             :                                    dcerpc_samr_SetDomainInfo_r(b, tctx, &r),
    3945             :                                    "failed to set domain info");
    3946         130 :         torture_assert_ntstatus_ok(tctx, r.out.result,
    3947             :                                    "failed to set domain info");
    3948             : 
    3949         130 :         return true;
    3950             : }
    3951             : 
    3952          14 : static bool test_SetDomainInfo_ntstatus(struct dcerpc_binding_handle *b,
    3953             :                                         struct torture_context *tctx,
    3954             :                                         struct policy_handle *domain_handle,
    3955             :                                         enum samr_DomainInfoClass level,
    3956             :                                         union samr_DomainInfo *info,
    3957             :                                         NTSTATUS expected)
    3958             : {
    3959             :         struct samr_SetDomainInfo r;
    3960             : 
    3961          14 :         r.in.domain_handle = domain_handle;
    3962          14 :         r.in.level = level;
    3963          14 :         r.in.info = info;
    3964             : 
    3965          14 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &r),
    3966             :                 "SetDomainInfo failed");
    3967          14 :         torture_assert_ntstatus_equal(tctx, r.out.result, expected, "");
    3968             : 
    3969          14 :         return true;
    3970             : }
    3971             : 
    3972          28 : static bool test_QueryDomainInfo2_level(struct dcerpc_binding_handle *b,
    3973             :                                         struct torture_context *tctx,
    3974             :                                         struct policy_handle *domain_handle,
    3975             :                                         enum samr_DomainInfoClass level,
    3976             :                                         union samr_DomainInfo **q_info)
    3977             : {
    3978             :         struct samr_QueryDomainInfo2 r;
    3979             : 
    3980          28 :         r.in.domain_handle = domain_handle;
    3981          28 :         r.in.level = level;
    3982          28 :         r.out.info = q_info;
    3983             : 
    3984          28 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo2_r(b, tctx, &r),
    3985             :                 "failed to query domain info");
    3986          28 :         torture_assert_ntstatus_ok(tctx, r.out.result,
    3987             :                 "failed to query domain info");
    3988             : 
    3989          28 :         return true;
    3990             : }
    3991             : 
    3992          24 : static bool test_Password_badpwdcount(struct dcerpc_pipe *p,
    3993             :                                       struct dcerpc_pipe *np,
    3994             :                                       struct torture_context *tctx,
    3995             :                                       uint32_t acct_flags,
    3996             :                                       const char *acct_name,
    3997             :                                       struct policy_handle *domain_handle,
    3998             :                                       struct policy_handle *user_handle,
    3999             :                                       char **password,
    4000             :                                       struct cli_credentials *machine_credentials,
    4001             :                                       const char *comment,
    4002             :                                       bool disable,
    4003             :                                       bool interactive,
    4004             :                                       NTSTATUS expected_success_status,
    4005             :                                       struct samr_DomInfo1 *info1,
    4006             :                                       struct samr_DomInfo12 *info12)
    4007             : {
    4008             :         union samr_DomainInfo info;
    4009             :         char **passwords;
    4010             :         int i;
    4011             :         uint32_t badpwdcount, tmp;
    4012          24 :         uint32_t password_history_length = 12;
    4013          24 :         uint32_t lockout_threshold = 15;
    4014          24 :         uint32_t lockout_seconds = 5;
    4015          24 :         uint64_t delta_time_factor = 10 * 1000 * 1000;
    4016          24 :         struct dcerpc_binding_handle *b = p->binding_handle;
    4017             : 
    4018          24 :         if (torture_setting_bool(tctx, "samba3", false)) {
    4019          16 :                 lockout_seconds = 60;
    4020             :         }
    4021             : 
    4022          24 :         torture_comment(tctx, "\nTesting bad pwd count with: %s\n", comment);
    4023             : 
    4024          24 :         torture_assert(tctx, password_history_length < lockout_threshold,
    4025             :                 "password history length needs to be smaller than account lockout threshold for this test");
    4026             : 
    4027             : 
    4028             :         /* set policies */
    4029             : 
    4030          24 :         info.info1 = *info1;
    4031          24 :         info.info1.password_history_length = password_history_length;
    4032          24 :         info.info1.min_password_age = 0;
    4033             : 
    4034          24 :         torture_assert(tctx,
    4035             :                        test_SetDomainInfo(b, tctx, domain_handle,
    4036             :                                           DomainPasswordInformation, &info),
    4037             :                        "failed to set password history length and min passwd age");
    4038             : 
    4039          24 :         info.info12 = *info12;
    4040          24 :         info.info12.lockout_threshold = lockout_threshold;
    4041             : 
    4042             :         /* set lockout duration of 5 seconds */
    4043          24 :         info.info12.lockout_duration = ~(lockout_seconds * delta_time_factor);
    4044          24 :         info.info12.lockout_window = ~(lockout_seconds * delta_time_factor);
    4045             : 
    4046          24 :         torture_assert(tctx,
    4047             :                        test_SetDomainInfo(b, tctx, domain_handle,
    4048             :                                           DomainLockoutInformation, &info),
    4049             :                        "failed to set lockout threshold");
    4050             : 
    4051             :         /* reset bad pwd count */
    4052             : 
    4053          24 :         torture_assert(tctx,
    4054             :                 test_reset_badpwdcount(p, tctx, user_handle, acct_flags, password), "");
    4055             : 
    4056             : 
    4057             :         /* enable or disable account */
    4058          24 :         if (disable) {
    4059          12 :                 torture_assert(tctx,
    4060             :                                test_SetUserInfo_acct_flags(b, tctx, user_handle,
    4061             :                                                 acct_flags | ACB_DISABLED),
    4062             :                                "failed to disable user");
    4063             :         } else {
    4064          12 :                 torture_assert(tctx,
    4065             :                                test_SetUserInfo_acct_flags(b, tctx, user_handle,
    4066             :                                                 acct_flags & ~ACB_DISABLED),
    4067             :                                "failed to enable user");
    4068             :         }
    4069             : 
    4070             : 
    4071             :         /* setup password history */
    4072             : 
    4073          24 :         passwords = talloc_array(tctx, char *, password_history_length);
    4074             : 
    4075         288 :         for (i=0; i < password_history_length; i++) {
    4076             : 
    4077         266 :                 torture_assert(tctx, test_SetUserPass(p, tctx, user_handle, password),
    4078             :                         "failed to set password");
    4079         266 :                 passwords[i] = talloc_strdup(tctx, *password);
    4080             : 
    4081         484 :                 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
    4082         266 :                                               acct_name, passwords[i],
    4083             :                                               expected_success_status, interactive)) {
    4084           0 :                         torture_fail(tctx, "failed to auth with latest password");
    4085             :                 }
    4086             : 
    4087         266 :                 torture_assert(tctx,
    4088             :                         test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
    4089             : 
    4090         266 :                 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
    4091             :         }
    4092             : 
    4093             : 
    4094             :         /* test with wrong password */
    4095             : 
    4096          40 :         if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
    4097             :                                       acct_name, "random_crap",
    4098          22 :                                       NT_STATUS_WRONG_PASSWORD, interactive)) {
    4099           0 :                 torture_fail(tctx, "succeeded to authenticate with wrong password");
    4100             :         }
    4101             : 
    4102          22 :         torture_assert(tctx,
    4103             :                 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
    4104             : 
    4105          22 :         torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
    4106             : 
    4107             : 
    4108             :         /* test with latest good password */
    4109             : 
    4110          40 :         if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
    4111          22 :                                       passwords[password_history_length-1],
    4112             :                                       expected_success_status, interactive)) {
    4113           0 :                 torture_fail(tctx, "succeeded to authenticate with wrong password");
    4114             :         }
    4115             : 
    4116          22 :         torture_assert(tctx,
    4117             :                 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
    4118             : 
    4119          22 :         if (disable) {
    4120          10 :                 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
    4121             :         } else {
    4122             :                 /* only enabled accounts get the bad pwd count reset upon
    4123             :                  * successful logon */
    4124          12 :                 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
    4125             :         }
    4126             : 
    4127          22 :         tmp = badpwdcount;
    4128             : 
    4129             : 
    4130             :         /* test password history */
    4131             : 
    4132         278 :         for (i=0; i < password_history_length; i++) {
    4133             : 
    4134         260 :                 torture_comment(tctx, "Testing bad password count behavior with "
    4135             :                                       "password #%d of #%d\n", i, password_history_length);
    4136             : 
    4137             :                 /* - network samlogon will succeed auth and not
    4138             :                  *   increase badpwdcount for 2 last entries
    4139             :                  * - interactive samlogon only for the last one */
    4140             : 
    4141         458 :                 if (i == password_history_length - 1 ||
    4142         260 :                     (i == password_history_length - 2 && !interactive)) {
    4143             : 
    4144          54 :                         if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
    4145          30 :                                                       acct_name, passwords[i],
    4146             :                                                       expected_success_status, interactive)) {
    4147           4 :                                 torture_fail(tctx, talloc_asprintf(tctx, "did not successfully to obtain %s for %s login with old password (#%d of #%d in history)",
    4148             :                                                                    nt_errstr(expected_success_status),
    4149             :                                                                    interactive ? "interactive" : "network", i, password_history_length));
    4150             :                         }
    4151             : 
    4152          26 :                         torture_assert(tctx,
    4153             :                                 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
    4154             : 
    4155          26 :                         if (disable) {
    4156             :                                 /* torture_comment(tctx, "expecting bad pwd count to *NOT INCREASE* for pwd history entry %d\n", i); */
    4157          12 :                                 torture_assert_int_equal(tctx, badpwdcount, tmp, "unexpected badpwdcount");
    4158             :                         } else {
    4159             :                                 /* torture_comment(tctx, "expecting bad pwd count to be 0 for pwd history entry %d\n", i); */
    4160          14 :                                 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
    4161             :                         }
    4162             : 
    4163          26 :                         tmp = badpwdcount;
    4164             : 
    4165          26 :                         continue;
    4166             :                 }
    4167             : 
    4168         418 :                 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
    4169         230 :                                               acct_name, passwords[i],
    4170         230 :                                               NT_STATUS_WRONG_PASSWORD, interactive)) {
    4171           0 :                         torture_fail(tctx, talloc_asprintf(tctx, "succeeded to authenticate with old password (#%d of #%d in history)", i, password_history_length));
    4172             :                 }
    4173             : 
    4174         230 :                 torture_assert(tctx,
    4175             :                         test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
    4176             : 
    4177             :                 /* - network samlogon will fail auth but not increase
    4178             :                  *   badpwdcount for 3rd last entry
    4179             :                  * - interactive samlogon for 3rd and 2nd last entry */
    4180             : 
    4181         400 :                 if (i == password_history_length - 3 ||
    4182         216 :                     (i == password_history_length - 2 && interactive)) {
    4183             :                         /* torture_comment(tctx, "expecting bad pwd count to *NOT INCREASE * by one for pwd history entry %d\n", i); */
    4184          32 :                         torture_assert_int_equal(tctx, badpwdcount, tmp, "unexpected badpwdcount");
    4185             :                 } else {
    4186             :                         /* torture_comment(tctx, "expecting bad pwd count to increase by one for pwd history entry %d\n", i); */
    4187         198 :                         torture_assert_int_equal(tctx, badpwdcount, tmp + 1, "unexpected badpwdcount");
    4188             :                 }
    4189             : 
    4190         230 :                 tmp = badpwdcount;
    4191             :         }
    4192             : 
    4193          18 :         return true;
    4194             : }
    4195             : 
    4196           8 : static bool test_Password_badpwdcount_wrap(struct dcerpc_pipe *p,
    4197             :                                            struct torture_context *tctx,
    4198             :                                            uint32_t acct_flags,
    4199             :                                            const char *acct_name,
    4200             :                                            struct policy_handle *domain_handle,
    4201             :                                            struct policy_handle *user_handle,
    4202             :                                            char **password,
    4203             :                                            struct cli_credentials *machine_credentials)
    4204             : {
    4205             :         union samr_DomainInfo *q_info, s_info;
    4206             :         struct samr_DomInfo1 info1, _info1;
    4207             :         struct samr_DomInfo12 info12, _info12;
    4208           8 :         bool ret = true;
    4209           8 :         struct dcerpc_binding_handle *b = p->binding_handle;
    4210             :         struct dcerpc_pipe *np;
    4211             :         int i;
    4212             : 
    4213             :         struct {
    4214             :                 const char *comment;
    4215             :                 bool disabled;
    4216             :                 bool interactive;
    4217             :                 NTSTATUS expected_success_status;
    4218           8 :         } creds[] = {
    4219             :                 {
    4220             :                         .comment                = "network logon (disabled account)",
    4221             :                         .disabled               = true,
    4222             :                         .interactive            = false,
    4223             :                         .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
    4224             :                 },
    4225             :                 {
    4226             :                         .comment                = "network logon (enabled account)",
    4227             :                         .disabled               = false,
    4228             :                         .interactive            = false,
    4229             :                         .expected_success_status= NT_STATUS_OK
    4230             :                 },
    4231             :                 {
    4232             :                         .comment                = "interactive logon (disabled account)",
    4233             :                         .disabled               = true,
    4234             :                         .interactive            = true,
    4235             :                         .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
    4236             :                 },
    4237             :                 {
    4238             :                         .comment                = "interactive logon (enabled account)",
    4239             :                         .disabled               = false,
    4240             :                         .interactive            = true,
    4241             :                         .expected_success_status= NT_STATUS_OK
    4242             :                 },
    4243             :         };
    4244             : 
    4245           8 :         torture_assert(tctx, setup_schannel_netlogon_pipe(tctx, machine_credentials, &np), "");
    4246             : 
    4247             :         /* backup old policies */
    4248             : 
    4249           8 :         torture_assert(tctx,
    4250             :                 test_QueryDomainInfo2_level(b, tctx, domain_handle,
    4251             :                                             DomainPasswordInformation, &q_info),
    4252             :                 "failed to query domain info level 1");
    4253             : 
    4254           8 :         info1 = q_info->info1;
    4255           8 :         _info1 = info1;
    4256             : 
    4257           8 :         torture_assert(tctx,
    4258             :                 test_QueryDomainInfo2_level(b, tctx, domain_handle,
    4259             :                                             DomainLockoutInformation, &q_info),
    4260             :                 "failed to query domain info level 12");
    4261             : 
    4262           8 :         info12 = q_info->info12;
    4263           8 :         _info12 = info12;
    4264             : 
    4265             :         /* run tests */
    4266             : 
    4267          40 :         for (i=0; i < ARRAY_SIZE(creds); i++) {
    4268             : 
    4269             :                 /* skip trust tests for now */
    4270          56 :                 if (acct_flags & ACB_WSTRUST ||
    4271          48 :                     acct_flags & ACB_SVRTRUST ||
    4272          24 :                     acct_flags & ACB_DOMTRUST) {
    4273           8 :                         continue;
    4274             :                 }
    4275             : 
    4276          44 :                 if (!test_Password_badpwdcount(p, np, tctx, acct_flags, acct_name,
    4277             :                                                domain_handle, user_handle, password,
    4278             :                                                machine_credentials,
    4279             :                                                creds[i].comment,
    4280          24 :                                                creds[i].disabled,
    4281          24 :                                                creds[i].interactive,
    4282             :                                                creds[i].expected_success_status,
    4283             :                                                &_info1, &_info12)) {
    4284           6 :                         torture_result(tctx, TORTURE_FAIL, "TEST #%d (%s) failed\n", i, creds[i].comment);
    4285           6 :                         ret = false;
    4286             :                 } else {
    4287          18 :                         torture_comment(tctx, "TEST #%d (%s) succeeded\n", i, creds[i].comment);
    4288             :                 }
    4289             :         }
    4290             : 
    4291             :         /* restore policies */
    4292             : 
    4293           8 :         s_info.info1 = info1;
    4294             : 
    4295           8 :         torture_assert(tctx,
    4296             :                        test_SetDomainInfo(b, tctx, domain_handle,
    4297             :                                           DomainPasswordInformation, &s_info),
    4298             :                        "failed to set password information");
    4299             : 
    4300           8 :         s_info.info12 = info12;
    4301             : 
    4302           8 :         torture_assert(tctx,
    4303             :                        test_SetDomainInfo(b, tctx, domain_handle,
    4304             :                                           DomainLockoutInformation, &s_info),
    4305             :                        "failed to set lockout information");
    4306             : 
    4307           8 :         return ret;
    4308             : }
    4309             : 
    4310         266 : static bool test_QueryUserInfo_lockout(struct dcerpc_binding_handle *b,
    4311             :                                        struct torture_context *tctx,
    4312             :                                        struct policy_handle *domain_handle,
    4313             :                                        const char *acct_name,
    4314             :                                        uint16_t raw_bad_password_count,
    4315             :                                        uint16_t effective_bad_password_count,
    4316             :                                        uint32_t effective_acb_lockout)
    4317             : {
    4318             :         struct policy_handle user_handle;
    4319             :         union samr_UserInfo *i;
    4320             :         struct samr_QueryUserInfo r;
    4321             : 
    4322         266 :         NTSTATUS status = test_OpenUser_byname(b, tctx, domain_handle, acct_name, &user_handle);
    4323         266 :         if (!NT_STATUS_IS_OK(status)) {
    4324           0 :                 return false;
    4325             :         }
    4326             : 
    4327         266 :         r.in.user_handle = &user_handle;
    4328         266 :         r.in.level = 3;
    4329         266 :         r.out.info = &i;
    4330         266 :         torture_comment(tctx, "Testing QueryUserInfo level %d", r.in.level);
    4331         266 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
    4332             :                 "failed to query userinfo");
    4333         266 :         torture_assert_ntstatus_ok(tctx, r.out.result,
    4334             :                 "failed to query userinfo");
    4335         532 :         torture_comment(tctx, "  (acct_flags: 0x%08x) (raw_bad_pwd_count: %u)\n",
    4336         532 :                         i->info3.acct_flags, i->info3.bad_password_count);
    4337         266 :         torture_assert_int_equal(tctx, i->info3.bad_password_count,
    4338             :                                  raw_bad_password_count,
    4339             :                                  "raw badpwdcount");
    4340         264 :         torture_assert_int_equal(tctx, i->info3.acct_flags & ACB_AUTOLOCK,
    4341             :                                  effective_acb_lockout,
    4342             :                                  "effective acb_lockout");
    4343         264 :         TALLOC_FREE(i);
    4344             : 
    4345         264 :         r.in.user_handle = &user_handle;
    4346         264 :         r.in.level = 5;
    4347         264 :         r.out.info = &i;
    4348         264 :         torture_comment(tctx, "Testing QueryUserInfo level %d", r.in.level);
    4349         264 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
    4350             :                 "failed to query userinfo");
    4351         264 :         torture_assert_ntstatus_ok(tctx, r.out.result,
    4352             :                 "failed to query userinfo");
    4353         528 :         torture_comment(tctx, "  (acct_flags: 0x%08x) (effective_bad_pwd_count: %u)\n",
    4354         528 :                         i->info5.acct_flags, i->info5.bad_password_count);
    4355         264 :         torture_assert_int_equal(tctx, i->info5.bad_password_count,
    4356             :                                  effective_bad_password_count,
    4357             :                                  "effective badpwdcount");
    4358         264 :         torture_assert_int_equal(tctx, i->info5.acct_flags & ACB_AUTOLOCK,
    4359             :                                  effective_acb_lockout,
    4360             :                                  "effective acb_lockout");
    4361         264 :         TALLOC_FREE(i);
    4362             : 
    4363         264 :         r.in.user_handle = &user_handle;
    4364         264 :         r.in.level = 16;
    4365         264 :         r.out.info = &i;
    4366         264 :         torture_comment(tctx, "Testing QueryUserInfo level %d", r.in.level);
    4367         264 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
    4368             :                 "failed to query userinfo");
    4369         264 :         torture_assert_ntstatus_ok(tctx, r.out.result,
    4370             :                 "failed to query userinfo");
    4371         264 :         torture_comment(tctx, "  (acct_flags: 0x%08x)\n",
    4372         264 :                         i->info16.acct_flags);
    4373         264 :         torture_assert_int_equal(tctx, i->info16.acct_flags & ACB_AUTOLOCK,
    4374             :                                  effective_acb_lockout,
    4375             :                                  "effective acb_lockout");
    4376         264 :         TALLOC_FREE(i);
    4377             : 
    4378         264 :         r.in.user_handle = &user_handle;
    4379         264 :         r.in.level = 21;
    4380         264 :         r.out.info = &i;
    4381         264 :         torture_comment(tctx, "Testing QueryUserInfo level %d", r.in.level);
    4382         264 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
    4383             :                 "failed to query userinfo");
    4384         264 :         torture_assert_ntstatus_ok(tctx, r.out.result,
    4385             :                 "failed to query userinfo");
    4386         528 :         torture_comment(tctx, "  (acct_flags: 0x%08x) (effective_bad_pwd_count: %u)\n",
    4387         528 :                         i->info21.acct_flags, i->info21.bad_password_count);
    4388         264 :         torture_assert_int_equal(tctx, i->info21.bad_password_count,
    4389             :                                  effective_bad_password_count,
    4390             :                                  "effective badpwdcount");
    4391         264 :         torture_assert_int_equal(tctx, i->info21.acct_flags & ACB_AUTOLOCK,
    4392             :                                  effective_acb_lockout,
    4393             :                                  "effective acb_lockout");
    4394         264 :         TALLOC_FREE(i);
    4395             : 
    4396         264 :         if (!test_samr_handle_Close(b, tctx, &user_handle)) {
    4397           0 :                 return false;
    4398             :         }
    4399             : 
    4400         264 :         return true;
    4401             : }
    4402             : 
    4403          14 : static bool test_Password_lockout(struct dcerpc_pipe *p,
    4404             :                                   struct dcerpc_pipe *np,
    4405             :                                   struct torture_context *tctx,
    4406             :                                   uint32_t acct_flags,
    4407             :                                   const char *acct_name,
    4408             :                                   struct policy_handle *domain_handle,
    4409             :                                   struct policy_handle *user_handle,
    4410             :                                   char **password,
    4411             :                                   struct cli_credentials *machine_credentials,
    4412             :                                   const char *comment,
    4413             :                                   bool disable,
    4414             :                                   bool interactive,
    4415             :                                   uint32_t password_history_length,
    4416             :                                   NTSTATUS expected_success_status,
    4417             :                                   struct samr_DomInfo1 *info1,
    4418             :                                   struct samr_DomInfo12 *info12)
    4419             : {
    4420             :         union samr_DomainInfo info;
    4421          14 :         uint64_t lockout_threshold = 1;
    4422          14 :         uint32_t lockout_seconds = 5;
    4423          14 :         uint64_t delta_time_factor = 10 * 1000 * 1000;
    4424          14 :         struct dcerpc_binding_handle *b = p->binding_handle;
    4425             : 
    4426          14 :         if (torture_setting_bool(tctx, "samba3", false)) {
    4427           2 :                 lockout_seconds = 60;
    4428             :         }
    4429             : 
    4430          14 :         torture_comment(tctx, "\nTesting account lockout: %s\n", comment);
    4431             : 
    4432             :         /* set policies */
    4433             : 
    4434          14 :         info.info1 = *info1;
    4435             : 
    4436          14 :         torture_comment(tctx, "setting password history length to %d.\n", password_history_length);
    4437          14 :         info.info1.password_history_length = password_history_length;
    4438             : 
    4439          14 :         torture_comment(tctx, "setting min password again.\n");
    4440          14 :         info.info1.min_password_age = 0;
    4441             : 
    4442          14 :         torture_assert(tctx,
    4443             :                        test_SetDomainInfo(b, tctx, domain_handle,
    4444             :                                           DomainPasswordInformation, &info),
    4445             :                        "failed to set password history length");
    4446             : 
    4447          14 :         info.info12 = *info12;
    4448          14 :         info.info12.lockout_threshold = lockout_threshold;
    4449             : 
    4450             :         /* set lockout duration < lockout window: should fail */
    4451          14 :         info.info12.lockout_duration = ~(lockout_seconds * delta_time_factor);
    4452          14 :         info.info12.lockout_window = ~((lockout_seconds + 1) * delta_time_factor);
    4453             : 
    4454          14 :         torture_assert(tctx,
    4455             :                 test_SetDomainInfo_ntstatus(b, tctx, domain_handle,
    4456             :                                             DomainLockoutInformation, &info,
    4457             :                                             NT_STATUS_INVALID_PARAMETER),
    4458             :                 "setting lockout duration < lockout window gave unexpected result");
    4459             : 
    4460          14 :         info.info12.lockout_duration = 0;
    4461          14 :         info.info12.lockout_window = 0;
    4462             : 
    4463          14 :         torture_assert(tctx,
    4464             :                        test_SetDomainInfo(b, tctx, domain_handle,
    4465             :                                           DomainLockoutInformation, &info),
    4466             :                        "failed to set lockout window and duration to 0");
    4467             : 
    4468             : 
    4469             :         /* set lockout duration of 5 seconds */
    4470          14 :         info.info12.lockout_duration = ~(lockout_seconds * delta_time_factor);
    4471          14 :         info.info12.lockout_window = ~(lockout_seconds * delta_time_factor);
    4472             : 
    4473          14 :         torture_assert(tctx,
    4474             :                        test_SetDomainInfo(b, tctx, domain_handle,
    4475             :                                           DomainLockoutInformation, &info),
    4476             :                        "failed to set lockout window and duration to 5 seconds");
    4477             : 
    4478             :         /* reset bad pwd count */
    4479             : 
    4480          14 :         torture_assert(tctx,
    4481             :                 test_reset_badpwdcount(p, tctx, user_handle, acct_flags, password), "");
    4482             : 
    4483             : 
    4484             :         /* enable or disable account */
    4485             : 
    4486          14 :         if (disable) {
    4487           6 :                 torture_assert(tctx,
    4488             :                                test_SetUserInfo_acct_flags(b, tctx, user_handle,
    4489             :                                                 acct_flags | ACB_DISABLED),
    4490             :                                "failed to disable user");
    4491             :         } else {
    4492           8 :                 torture_assert(tctx,
    4493             :                                test_SetUserInfo_acct_flags(b, tctx, user_handle,
    4494             :                                                 acct_flags & ~ACB_DISABLED),
    4495             :                                "failed to enable user");
    4496             :         }
    4497             : 
    4498             : 
    4499             :         /* test logon with right password */
    4500             : 
    4501          14 :         if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
    4502             :                                       acct_name, *password,
    4503             :                                       expected_success_status, interactive)) {
    4504           0 :                 torture_fail(tctx, "failed to auth with latest password");
    4505             :         }
    4506             : 
    4507          14 :         torture_assert(tctx,
    4508             :                 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
    4509             :                         0, 0, 0),
    4510             :                 "expected account to not be locked");
    4511             : 
    4512             :         /* test with wrong password ==> lockout */
    4513             : 
    4514          28 :         if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
    4515             :                                       acct_name, "random_crap",
    4516          14 :                                       NT_STATUS_WRONG_PASSWORD, interactive)) {
    4517           0 :                 torture_fail(tctx, "succeeded to authenticate with wrong password");
    4518             :         }
    4519             : 
    4520             :         /*
    4521             :          * curiously, windows does _not_ return fresh values of
    4522             :          * effective bad_password_count and ACB_AUTOLOCK.
    4523             :          */
    4524          14 :         torture_assert(tctx,
    4525             :                 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
    4526             :                         1, 1, ACB_AUTOLOCK),
    4527             :                 "expected account to not be locked");
    4528             : 
    4529             :         /* test with good password */
    4530             : 
    4531          28 :         if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
    4532             :                                      *password,
    4533          14 :                                      NT_STATUS_ACCOUNT_LOCKED_OUT, interactive))
    4534             :         {
    4535           0 :                 torture_fail(tctx, "authenticate did not return NT_STATUS_ACCOUNT_LOCKED_OUT");
    4536             :         }
    4537             : 
    4538             :         /* bad pwd count should not get updated */
    4539          14 :         torture_assert(tctx,
    4540             :                 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
    4541             :                         1, 1, ACB_AUTOLOCK),
    4542             :                 "expected account to be locked");
    4543             : 
    4544          14 :         torture_assert(tctx,
    4545             :                        test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, *password,
    4546             :                                                          NT_STATUS_ACCOUNT_LOCKED_OUT),
    4547             :                        "got wrong status from ChangePasswordUser2");
    4548             : 
    4549             :         /* bad pwd count should not get updated */
    4550          14 :         torture_assert(tctx,
    4551             :                 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
    4552             :                         1, 1, ACB_AUTOLOCK),
    4553             :                 "expected account to be locked");
    4554             : 
    4555          14 :         torture_assert(tctx,
    4556             :                        test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, "random_crap", NT_STATUS_ACCOUNT_LOCKED_OUT),
    4557             :                        "got wrong status from ChangePasswordUser2");
    4558             : 
    4559             :         /* bad pwd count should not get updated */
    4560          14 :         torture_assert(tctx,
    4561             :                 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
    4562             :                         1, 1, ACB_AUTOLOCK),
    4563             :                 "expected account to be locked");
    4564             : 
    4565             :         /* with bad password */
    4566             : 
    4567          28 :         if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
    4568             :                                       acct_name, "random_crap2",
    4569          14 :                                       NT_STATUS_ACCOUNT_LOCKED_OUT, interactive))
    4570             :         {
    4571           0 :                 torture_fail(tctx, "authenticate did not return NT_STATUS_ACCOUNT_LOCKED_OUT");
    4572             :         }
    4573             : 
    4574             :         /* bad pwd count should not get updated */
    4575          14 :         torture_assert(tctx,
    4576             :                 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
    4577             :                         1, 1, ACB_AUTOLOCK),
    4578             :                 "expected account to be locked");
    4579             : 
    4580             :         /* let lockout duration expire ==> unlock */
    4581             : 
    4582          14 :         torture_comment(tctx, "let lockout duration expire...\n");
    4583          14 :         sleep(lockout_seconds + 1);
    4584             : 
    4585          14 :         torture_assert(tctx,
    4586             :                 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
    4587             :                         1, 0, 0),
    4588             :                 "expected account to not be locked");
    4589             : 
    4590          12 :         if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
    4591             :                                      *password,
    4592             :                                      expected_success_status, interactive))
    4593             :         {
    4594           0 :                 torture_fail(tctx, "failed to authenticate after lockout expired");
    4595             :         }
    4596             : 
    4597          12 :         if (NT_STATUS_IS_OK(expected_success_status)) {
    4598           8 :                 torture_assert(tctx,
    4599             :                         test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
    4600             :                                 0, 0, 0),
    4601             :                         "expected account to not be locked");
    4602             :         } else {
    4603           4 :                 torture_assert(tctx,
    4604             :                         test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
    4605             :                                 1, 0, 0),
    4606             :                         "expected account to not be locked");
    4607             :         }
    4608             : 
    4609          12 :         torture_assert(tctx,
    4610             :                        test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, "random_crap", NT_STATUS_WRONG_PASSWORD),
    4611             :                        "got wrong status from ChangePasswordUser2");
    4612             : 
    4613          12 :         torture_assert(tctx,
    4614             :                 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
    4615             :                         1, 1, ACB_AUTOLOCK),
    4616             :                 "expected account to be locked");
    4617             : 
    4618          12 :         torture_assert(tctx,
    4619             :                        test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, *password, NT_STATUS_ACCOUNT_LOCKED_OUT),
    4620             :                        "got wrong status from ChangePasswordUser2");
    4621             : 
    4622          12 :         torture_assert(tctx,
    4623             :                 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
    4624             :                         1, 1, ACB_AUTOLOCK),
    4625             :                 "expected account to be locked");
    4626             : 
    4627          12 :         torture_assert(tctx,
    4628             :                        test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, "random_crap", NT_STATUS_ACCOUNT_LOCKED_OUT),
    4629             :                        "got wrong status from ChangePasswordUser2");
    4630             : 
    4631          12 :         torture_assert(tctx,
    4632             :                 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
    4633             :                         1, 1, ACB_AUTOLOCK),
    4634             :                 "expected account to be locked");
    4635             : 
    4636             :         /* let lockout duration expire ==> unlock */
    4637             : 
    4638          12 :         torture_comment(tctx, "let lockout duration expire...\n");
    4639          12 :         sleep(lockout_seconds + 1);
    4640             : 
    4641          12 :         torture_assert(tctx,
    4642             :                 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
    4643             :                         1, 0, 0),
    4644             :                 "expected account to not be locked");
    4645             : 
    4646          12 :         if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
    4647             :                                      *password,
    4648             :                                      expected_success_status, interactive))
    4649             :         {
    4650           0 :                 torture_fail(tctx, "failed to authenticate after lockout expired");
    4651             :         }
    4652             : 
    4653          12 :         if (NT_STATUS_IS_OK(expected_success_status)) {
    4654           8 :                 torture_assert(tctx,
    4655             :                         test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
    4656             :                                 0, 0, 0),
    4657             :                         "expected account to not be locked");
    4658             :         } else {
    4659           4 :                 torture_assert(tctx,
    4660             :                         test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
    4661             :                                 1, 0, 0),
    4662             :                         "expected account to not be locked");
    4663             :         }
    4664             : 
    4665             :         /* Testing ChangePasswordUser behaviour with 3 attempts */
    4666          12 :         info.info12.lockout_threshold = 3;
    4667             : 
    4668          12 :         torture_assert(tctx,
    4669             :                        test_SetDomainInfo(b, tctx, domain_handle,
    4670             :                                           DomainLockoutInformation, &info),
    4671             :                        "failed to set lockout threshold to 3");
    4672             : 
    4673          12 :         if (NT_STATUS_IS_OK(expected_success_status)) {
    4674           8 :                 torture_assert(tctx,
    4675             :                         test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
    4676             :                                 0, 0, 0),
    4677             :                         "expected account to not be locked");
    4678             :         } else {
    4679           4 :                 torture_assert(tctx,
    4680             :                         test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
    4681             :                                 1, 0, 0),
    4682             :                         "expected account to not be locked");
    4683             :         }
    4684             : 
    4685          12 :         torture_assert(tctx,
    4686             :                        test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, "random_crap", NT_STATUS_WRONG_PASSWORD),
    4687             :                        "got wrong status from ChangePasswordUser2");
    4688             : 
    4689             :         /* bad pwd count will get updated */
    4690          12 :         torture_assert(tctx,
    4691             :                 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
    4692             :                         1, 1, 0),
    4693             :                 "expected account to not be locked");
    4694             : 
    4695          12 :         torture_assert(tctx,
    4696             :                        test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, "random_crap", NT_STATUS_WRONG_PASSWORD),
    4697             :                        "got wrong status from ChangePasswordUser2");
    4698             : 
    4699             :         /* bad pwd count will get updated */
    4700          12 :         torture_assert(tctx,
    4701             :                 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
    4702             :                         2, 2, 0),
    4703             :                 "expected account to not be locked");
    4704             : 
    4705          12 :         torture_assert(tctx,
    4706             :                        test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, "random_crap", NT_STATUS_WRONG_PASSWORD),
    4707             :                        "got wrong status from ChangePasswordUser2");
    4708             : 
    4709             :         /* bad pwd count should get updated */
    4710          12 :         torture_assert(tctx,
    4711             :                 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
    4712             :                         3, 3, ACB_AUTOLOCK),
    4713             :                 "expected account to be locked");
    4714             : 
    4715          12 :         torture_assert(tctx,
    4716             :                        test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, *password, NT_STATUS_ACCOUNT_LOCKED_OUT),
    4717             :                        "got wrong status from ChangePasswordUser2");
    4718             : 
    4719             :         /* bad pwd count should not get updated */
    4720          12 :         torture_assert(tctx,
    4721             :                 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
    4722             :                         3, 3, ACB_AUTOLOCK),
    4723             :                 "expected account to be locked");
    4724             : 
    4725             :         /* let lockout duration expire ==> unlock */
    4726             : 
    4727          12 :         torture_comment(tctx, "let lockout duration expire...\n");
    4728          12 :         sleep(lockout_seconds + 1);
    4729             : 
    4730          12 :         torture_assert(tctx,
    4731             :                 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
    4732             :                         3, 0, 0),
    4733             :                 "expected account to not be locked");
    4734             : 
    4735          12 :         torture_assert(tctx,
    4736             :                        test_ChangePasswordUser2(p, tctx, acct_name, password, NULL, false),
    4737             :                        "got wrong status from ChangePasswordUser2");
    4738             : 
    4739          12 :         torture_assert(tctx,
    4740             :                 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
    4741             :                         3, 0, 0),
    4742             :                 "expected account to not be locked");
    4743             : 
    4744             :         /* Used to reset the badPwdCount for the other tests */
    4745          12 :         if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
    4746             :                                       *password,
    4747             :                                       expected_success_status, interactive))
    4748             :         {
    4749           0 :                 torture_fail(tctx, "failed to authenticate after lockout expired");
    4750             :         }
    4751             : 
    4752          12 :         if (NT_STATUS_IS_OK(expected_success_status)) {
    4753           8 :                 torture_assert(tctx,
    4754             :                         test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
    4755             :                                 0, 0, 0),
    4756             :                         "expected account to not be locked");
    4757             :         } else {
    4758           4 :                 torture_assert(tctx,
    4759             :                         test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
    4760             :                                 3, 0, 0),
    4761             :                         "expected account to not be locked");
    4762             :         }
    4763             : 
    4764          12 :         return true;
    4765             : }
    4766             : 
    4767           6 : static bool test_Password_lockout_wrap(struct dcerpc_pipe *p,
    4768             :                                        struct torture_context *tctx,
    4769             :                                        uint32_t acct_flags,
    4770             :                                        const char *acct_name,
    4771             :                                        struct policy_handle *domain_handle,
    4772             :                                        struct policy_handle *user_handle,
    4773             :                                        char **password,
    4774             :                                        struct cli_credentials *machine_credentials)
    4775             : {
    4776             :         union samr_DomainInfo *q_info, s_info;
    4777             :         struct samr_DomInfo1 info1, _info1;
    4778             :         struct samr_DomInfo12 info12, _info12;
    4779           6 :         bool ret = true;
    4780           6 :         struct dcerpc_binding_handle *b = p->binding_handle;
    4781             :         struct dcerpc_pipe *np;
    4782             :         int i;
    4783             : 
    4784             :         struct {
    4785             :                 const char *comment;
    4786             :                 bool disabled;
    4787             :                 bool interactive;
    4788             :                 uint32_t password_history_length;
    4789             :                 NTSTATUS expected_success_status;
    4790           6 :         } creds[] = {
    4791             :                 {
    4792             :                         .comment                = "network logon (disabled account)",
    4793             :                         .disabled               = true,
    4794             :                         .interactive            = false,
    4795             :                         .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
    4796             :                 },
    4797             :                 {
    4798             :                         .comment                = "network logon (enabled account)",
    4799             :                         .disabled               = false,
    4800             :                         .interactive            = false,
    4801             :                         .expected_success_status= NT_STATUS_OK
    4802             :                 },
    4803             :                 {
    4804             :                         .comment                = "network logon (enabled account, history len = 1)",
    4805             :                         .disabled               = false,
    4806             :                         .interactive            = false,
    4807             :                         .expected_success_status= NT_STATUS_OK,
    4808             :                         .password_history_length = 1
    4809             :                 },
    4810             :                 {
    4811             :                         .comment                = "interactive logon (disabled account)",
    4812             :                         .disabled               = true,
    4813             :                         .interactive            = true,
    4814             :                         .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
    4815             :                 },
    4816             :                 {
    4817             :                         .comment                = "interactive logon (enabled account)",
    4818             :                         .disabled               = false,
    4819             :                         .interactive            = true,
    4820             :                         .expected_success_status= NT_STATUS_OK
    4821             :                 },
    4822             :                 {
    4823             :                         .comment                = "interactive logon (enabled account, history len = 1)",
    4824             :                         .disabled               = false,
    4825             :                         .interactive            = true,
    4826             :                         .expected_success_status= NT_STATUS_OK,
    4827             :                         .password_history_length = 1
    4828             :                 },
    4829             :         };
    4830             : 
    4831           6 :         torture_assert(tctx, setup_schannel_netlogon_pipe(tctx, machine_credentials, &np), "");
    4832             : 
    4833             :         /* backup old policies */
    4834             : 
    4835           6 :         torture_assert(tctx,
    4836             :                 test_QueryDomainInfo2_level(b, tctx, domain_handle,
    4837             :                                             DomainPasswordInformation, &q_info),
    4838             :                 "failed to query domain info level 1");
    4839             : 
    4840           6 :         info1 = q_info->info1;
    4841           6 :         _info1 = info1;
    4842             : 
    4843           6 :         torture_assert(tctx,
    4844             :                 test_QueryDomainInfo2_level(b, tctx, domain_handle,
    4845             :                                             DomainLockoutInformation, &q_info),
    4846             :                 "failed to query domain info level 12");
    4847             : 
    4848           6 :         info12 = q_info->info12;
    4849           6 :         _info12 = info12;
    4850             : 
    4851             :         /* run tests */
    4852             : 
    4853          30 :         for (i=0; i < ARRAY_SIZE(creds); i++) {
    4854             :                 bool test_passed;
    4855             :                 /* skip trust tests for now */
    4856          46 :                 if (acct_flags & ACB_WSTRUST ||
    4857          34 :                     acct_flags & ACB_SVRTRUST ||
    4858          14 :                     acct_flags & ACB_DOMTRUST) {
    4859          12 :                         continue;
    4860             :                 }
    4861             : 
    4862          42 :                 test_passed = test_Password_lockout(p, np, tctx, acct_flags, acct_name,
    4863             :                                              domain_handle, user_handle, password,
    4864             :                                              machine_credentials,
    4865             :                                              creds[i].comment,
    4866          14 :                                              creds[i].disabled,
    4867          14 :                                              creds[i].interactive,
    4868             :                                              creds[i].password_history_length,
    4869             :                                              creds[i].expected_success_status,
    4870             :                                              &_info1, &_info12);
    4871          14 :                 ret &= test_passed;
    4872          14 :                 if (!test_passed) {
    4873           2 :                         torture_result(tctx, TORTURE_FAIL, "TEST #%d (%s) failed\n", i, creds[i].comment);
    4874           2 :                         break;
    4875             :                 } else {
    4876          12 :                         torture_comment(tctx, "TEST #%d (%s) succeeded\n", i, creds[i].comment);
    4877             :                 }
    4878             :         }
    4879             : 
    4880             :         /* restore policies */
    4881             : 
    4882           6 :         s_info.info1 = info1;
    4883             : 
    4884           6 :         torture_assert(tctx,
    4885             :                        test_SetDomainInfo(b, tctx, domain_handle,
    4886             :                                           DomainPasswordInformation, &s_info),
    4887             :                        "failed to set password information");
    4888             : 
    4889           6 :         s_info.info12 = info12;
    4890             : 
    4891           6 :         torture_assert(tctx,
    4892             :                        test_SetDomainInfo(b, tctx, domain_handle,
    4893             :                                           DomainLockoutInformation, &s_info),
    4894             :                        "failed to set lockout information");
    4895             : 
    4896           6 :         return ret;
    4897             : }
    4898             : 
    4899           8 : static bool test_DeleteUser_with_privs(struct dcerpc_pipe *p,
    4900             :                                        struct dcerpc_pipe *lp,
    4901             :                                        struct torture_context *tctx,
    4902             :                                        struct policy_handle *domain_handle,
    4903             :                                        struct policy_handle *lsa_handle,
    4904             :                                        struct policy_handle *user_handle,
    4905             :                                        const struct dom_sid *domain_sid,
    4906             :                                        uint32_t rid,
    4907             :                                        struct cli_credentials *machine_credentials)
    4908             : {
    4909           8 :         bool ret = true;
    4910           8 :         struct dcerpc_binding_handle *b = p->binding_handle;
    4911           8 :         struct dcerpc_binding_handle *lb = lp->binding_handle;
    4912             : 
    4913             :         struct policy_handle lsa_acct_handle;
    4914             :         struct dom_sid *user_sid;
    4915             : 
    4916           8 :         user_sid = dom_sid_add_rid(tctx, domain_sid, rid);
    4917             : 
    4918             :         {
    4919             :                 struct lsa_EnumAccountRights r;
    4920             :                 struct lsa_RightSet rights;
    4921             : 
    4922           8 :                 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
    4923             : 
    4924           8 :                 r.in.handle = lsa_handle;
    4925           8 :                 r.in.sid = user_sid;
    4926           8 :                 r.out.rights = &rights;
    4927             : 
    4928           8 :                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
    4929             :                         "lsa_EnumAccountRights failed");
    4930           8 :                 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND,
    4931             :                         "Expected enum rights for account to fail");
    4932             :         }
    4933             : 
    4934             :         {
    4935             :                 struct lsa_RightSet rights;
    4936             :                 struct lsa_StringLarge names[2];
    4937             :                 struct lsa_AddAccountRights r;
    4938             : 
    4939           8 :                 torture_comment(tctx, "Testing LSA AddAccountRights\n");
    4940             : 
    4941           8 :                 init_lsa_StringLarge(&names[0], "SeMachineAccountPrivilege");
    4942           8 :                 init_lsa_StringLarge(&names[1], NULL);
    4943             : 
    4944           8 :                 rights.count = 1;
    4945           8 :                 rights.names = names;
    4946             : 
    4947           8 :                 r.in.handle = lsa_handle;
    4948           8 :                 r.in.sid = user_sid;
    4949           8 :                 r.in.rights = &rights;
    4950             : 
    4951           8 :                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_AddAccountRights_r(lb, tctx, &r),
    4952             :                         "lsa_AddAccountRights failed");
    4953           8 :                 torture_assert_ntstatus_ok(tctx, r.out.result,
    4954             :                         "Failed to add privileges");
    4955             :         }
    4956             : 
    4957             :         {
    4958             :                 struct lsa_RightSet rights;
    4959             :                 struct lsa_StringLarge names[2];
    4960             :                 struct lsa_AddAccountRights r;
    4961             : 
    4962           8 :                 torture_comment(tctx, "Testing LSA AddAccountRights 1\n");
    4963             : 
    4964           8 :                 init_lsa_StringLarge(&names[0], "SeInteractiveLogonRight");
    4965           8 :                 init_lsa_StringLarge(&names[1], NULL);
    4966             : 
    4967           8 :                 rights.count = 1;
    4968           8 :                 rights.names = names;
    4969             : 
    4970           8 :                 r.in.handle = lsa_handle;
    4971           8 :                 r.in.sid = user_sid;
    4972           8 :                 r.in.rights = &rights;
    4973             : 
    4974           8 :                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_AddAccountRights_r(lb, tctx, &r),
    4975             :                         "lsa_AddAccountRights 1 failed");
    4976             : 
    4977           8 :                 if (torture_setting_bool(tctx, "nt4_dc", false)) {
    4978             :                         /*
    4979             :                          * The NT4 DC doesn't implement Rights.
    4980             :                          */
    4981           2 :                         torture_assert_ntstatus_equal(tctx, r.out.result,
    4982             :                                 NT_STATUS_NO_SUCH_PRIVILEGE,
    4983             :                                 "Add rights failed with incorrect error");
    4984             :                 } else {
    4985           6 :                         torture_assert_ntstatus_ok(tctx, r.out.result,
    4986             :                                 "Failed to add rights");
    4987             : 
    4988             :                 }
    4989             :         }
    4990             : 
    4991             : 
    4992             :         {
    4993             :                 struct lsa_EnumAccounts r;
    4994           8 :                 uint32_t resume_handle = 0;
    4995             :                 struct lsa_SidArray lsa_sid_array;
    4996             :                 int i;
    4997           8 :                 bool found_sid = false;
    4998             : 
    4999           8 :                 torture_comment(tctx, "Testing LSA EnumAccounts\n");
    5000             : 
    5001           8 :                 r.in.handle = lsa_handle;
    5002           8 :                 r.in.num_entries = 0x1000;
    5003           8 :                 r.in.resume_handle = &resume_handle;
    5004           8 :                 r.out.sids = &lsa_sid_array;
    5005           8 :                 r.out.resume_handle = &resume_handle;
    5006             : 
    5007           8 :                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(lb, tctx, &r),
    5008             :                         "lsa_EnumAccounts failed");
    5009           8 :                 torture_assert_ntstatus_ok(tctx, r.out.result,
    5010             :                         "Failed to enum accounts");
    5011             : 
    5012          64 :                 for (i=0; i < lsa_sid_array.num_sids; i++) {
    5013          56 :                         if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
    5014           8 :                                 found_sid = true;
    5015             :                         }
    5016             :                 }
    5017             : 
    5018           8 :                 torture_assert(tctx, found_sid,
    5019             :                         "failed to list privileged account");
    5020             :         }
    5021             : 
    5022             :         {
    5023             :                 struct lsa_EnumAccountRights r;
    5024             :                 struct lsa_RightSet user_rights;
    5025           8 :                 uint32_t expected_count = 2;
    5026             : 
    5027           8 :                 if (torture_setting_bool(tctx, "nt4_dc", false)) {
    5028             :                         /*
    5029             :                          * NT4 DC doesn't store rights.
    5030             :                          */
    5031           2 :                         expected_count = 1;
    5032             :                 }
    5033             : 
    5034           8 :                 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
    5035             : 
    5036           8 :                 r.in.handle = lsa_handle;
    5037           8 :                 r.in.sid = user_sid;
    5038           8 :                 r.out.rights = &user_rights;
    5039             : 
    5040           8 :                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
    5041             :                         "lsa_EnumAccountRights failed");
    5042           8 :                 torture_assert_ntstatus_ok(tctx, r.out.result,
    5043             :                         "Failed to enum rights for account");
    5044             : 
    5045           8 :                 if (user_rights.count < expected_count) {
    5046           0 :                         torture_result(tctx, TORTURE_FAIL, "failed to find newly added rights");
    5047           0 :                         return false;
    5048             :                 }
    5049             :         }
    5050             : 
    5051             :         {
    5052             :                 struct lsa_OpenAccount r;
    5053             : 
    5054           8 :                 torture_comment(tctx, "Testing LSA OpenAccount\n");
    5055             : 
    5056           8 :                 r.in.handle = lsa_handle;
    5057           8 :                 r.in.sid = user_sid;
    5058           8 :                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    5059           8 :                 r.out.acct_handle = &lsa_acct_handle;
    5060             : 
    5061           8 :                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenAccount_r(lb, tctx, &r),
    5062             :                         "lsa_OpenAccount failed");
    5063           8 :                 torture_assert_ntstatus_ok(tctx, r.out.result,
    5064             :                         "Failed to open lsa account");
    5065             :         }
    5066             : 
    5067             :         {
    5068             :                 struct lsa_GetSystemAccessAccount r;
    5069             :                 uint32_t access_mask;
    5070             : 
    5071           8 :                 torture_comment(tctx, "Testing LSA GetSystemAccessAccount\n");
    5072             : 
    5073           8 :                 r.in.handle = &lsa_acct_handle;
    5074           8 :                 r.out.access_mask = &access_mask;
    5075             : 
    5076           8 :                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetSystemAccessAccount_r(lb, tctx, &r),
    5077             :                         "lsa_GetSystemAccessAccount failed");
    5078           8 :                 torture_assert_ntstatus_ok(tctx, r.out.result,
    5079             :                         "Failed to get lsa system access account");
    5080             :         }
    5081             : 
    5082             :         {
    5083             :                 struct lsa_Close r;
    5084             : 
    5085           8 :                 torture_comment(tctx, "Testing LSA Close\n");
    5086             : 
    5087           8 :                 r.in.handle = &lsa_acct_handle;
    5088           8 :                 r.out.handle = &lsa_acct_handle;
    5089             : 
    5090           8 :                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_Close_r(lb, tctx, &r),
    5091             :                         "lsa_Close failed");
    5092           8 :                 torture_assert_ntstatus_ok(tctx, r.out.result,
    5093             :                         "Failed to close lsa");
    5094             :         }
    5095             : 
    5096             :         {
    5097             :                 struct samr_DeleteUser r;
    5098             : 
    5099           8 :                 torture_comment(tctx, "Testing SAMR DeleteUser\n");
    5100             : 
    5101           8 :                 r.in.user_handle = user_handle;
    5102           8 :                 r.out.user_handle = user_handle;
    5103             : 
    5104           8 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, tctx, &r),
    5105             :                         "DeleteUser failed");
    5106           8 :                 torture_assert_ntstatus_ok(tctx, r.out.result,
    5107             :                         "DeleteUser failed");
    5108             :         }
    5109             : 
    5110             :         {
    5111             :                 struct lsa_EnumAccounts r;
    5112           8 :                 uint32_t resume_handle = 0;
    5113             :                 struct lsa_SidArray lsa_sid_array;
    5114             :                 int i;
    5115           8 :                 bool found_sid = false;
    5116             : 
    5117           8 :                 torture_comment(tctx, "Testing LSA EnumAccounts\n");
    5118             : 
    5119           8 :                 r.in.handle = lsa_handle;
    5120           8 :                 r.in.num_entries = 0x1000;
    5121           8 :                 r.in.resume_handle = &resume_handle;
    5122           8 :                 r.out.sids = &lsa_sid_array;
    5123           8 :                 r.out.resume_handle = &resume_handle;
    5124             : 
    5125           8 :                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(lb, tctx, &r),
    5126             :                         "lsa_EnumAccounts failed");
    5127           8 :                 torture_assert_ntstatus_ok(tctx, r.out.result,
    5128             :                         "Failed to enum accounts");
    5129             : 
    5130          64 :                 for (i=0; i < lsa_sid_array.num_sids; i++) {
    5131          56 :                         if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
    5132           8 :                                 found_sid = true;
    5133             :                         }
    5134             :                 }
    5135             : 
    5136           8 :                 torture_assert(tctx, found_sid,
    5137             :                         "failed to list privileged account");
    5138             :         }
    5139             : 
    5140             :         {
    5141             :                 struct lsa_EnumAccountRights r;
    5142             :                 struct lsa_RightSet user_rights;
    5143             : 
    5144           8 :                 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
    5145             : 
    5146           8 :                 r.in.handle = lsa_handle;
    5147           8 :                 r.in.sid = user_sid;
    5148           8 :                 r.out.rights = &user_rights;
    5149             : 
    5150           8 :                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
    5151             :                         "lsa_EnumAccountRights failed");
    5152           8 :                 torture_assert_ntstatus_ok(tctx, r.out.result,
    5153             :                         "Failed to enum rights for account");
    5154             : 
    5155           8 :                 if (user_rights.count < 1) {
    5156           0 :                         torture_result(tctx, TORTURE_FAIL, "failed to find newly added rights");
    5157           0 :                         return false;
    5158             :                 }
    5159             :         }
    5160             : 
    5161             :         {
    5162             :                 struct lsa_OpenAccount r;
    5163             : 
    5164           8 :                 torture_comment(tctx, "Testing LSA OpenAccount\n");
    5165             : 
    5166           8 :                 r.in.handle = lsa_handle;
    5167           8 :                 r.in.sid = user_sid;
    5168           8 :                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    5169           8 :                 r.out.acct_handle = &lsa_acct_handle;
    5170             : 
    5171           8 :                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenAccount_r(lb, tctx, &r),
    5172             :                         "lsa_OpenAccount failed");
    5173           8 :                 torture_assert_ntstatus_ok(tctx, r.out.result,
    5174             :                         "Failed to open lsa account");
    5175             :         }
    5176             : 
    5177             :         {
    5178             :                 struct lsa_GetSystemAccessAccount r;
    5179             :                 uint32_t access_mask;
    5180             : 
    5181           8 :                 torture_comment(tctx, "Testing LSA GetSystemAccessAccount\n");
    5182             : 
    5183           8 :                 r.in.handle = &lsa_acct_handle;
    5184           8 :                 r.out.access_mask = &access_mask;
    5185             : 
    5186           8 :                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetSystemAccessAccount_r(lb, tctx, &r),
    5187             :                         "lsa_GetSystemAccessAccount failed");
    5188           8 :                 torture_assert_ntstatus_ok(tctx, r.out.result,
    5189             :                         "Failed to get lsa system access account");
    5190             :         }
    5191             : 
    5192             :         {
    5193             :                 struct lsa_DeleteObject r;
    5194             : 
    5195           8 :                 torture_comment(tctx, "Testing LSA DeleteObject\n");
    5196             : 
    5197           8 :                 r.in.handle = &lsa_acct_handle;
    5198           8 :                 r.out.handle = &lsa_acct_handle;
    5199             : 
    5200           8 :                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_DeleteObject_r(lb, tctx, &r),
    5201             :                         "lsa_DeleteObject failed");
    5202           8 :                 torture_assert_ntstatus_ok(tctx, r.out.result,
    5203             :                         "Failed to delete object");
    5204             :         }
    5205             : 
    5206             :         {
    5207             :                 struct lsa_EnumAccounts r;
    5208           8 :                 uint32_t resume_handle = 0;
    5209             :                 struct lsa_SidArray lsa_sid_array;
    5210             :                 int i;
    5211           8 :                 bool found_sid = false;
    5212             : 
    5213           8 :                 torture_comment(tctx, "Testing LSA EnumAccounts\n");
    5214             : 
    5215           8 :                 r.in.handle = lsa_handle;
    5216           8 :                 r.in.num_entries = 0x1000;
    5217           8 :                 r.in.resume_handle = &resume_handle;
    5218           8 :                 r.out.sids = &lsa_sid_array;
    5219           8 :                 r.out.resume_handle = &resume_handle;
    5220             : 
    5221           8 :                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(lb, tctx, &r),
    5222             :                         "lsa_EnumAccounts failed");
    5223           8 :                 torture_assert_ntstatus_ok(tctx, r.out.result,
    5224             :                         "Failed to enum accounts");
    5225             : 
    5226          56 :                 for (i=0; i < lsa_sid_array.num_sids; i++) {
    5227          48 :                         if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
    5228           0 :                                 found_sid = true;
    5229             :                         }
    5230             :                 }
    5231             : 
    5232           8 :                 torture_assert(tctx, !found_sid,
    5233             :                         "should not have listed privileged account");
    5234             :         }
    5235             : 
    5236             :         {
    5237             :                 struct lsa_EnumAccountRights r;
    5238             :                 struct lsa_RightSet user_rights;
    5239             : 
    5240           8 :                 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
    5241             : 
    5242           8 :                 r.in.handle = lsa_handle;
    5243           8 :                 r.in.sid = user_sid;
    5244           8 :                 r.out.rights = &user_rights;
    5245             : 
    5246           8 :                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
    5247             :                         "lsa_EnumAccountRights failed");
    5248           8 :                 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND,
    5249             :                         "Failed to enum rights for account");
    5250             :         }
    5251             : 
    5252           8 :         return ret;
    5253             : }
    5254             : 
    5255          61 : static bool test_user_ops(struct dcerpc_pipe *p,
    5256             :                           struct torture_context *tctx,
    5257             :                           struct policy_handle *user_handle,
    5258             :                           struct policy_handle *domain_handle,
    5259             :                           const struct dom_sid *domain_sid,
    5260             :                           uint32_t base_acct_flags,
    5261             :                           const char *base_acct_name, enum torture_samr_choice which_ops,
    5262             :                           struct cli_credentials *machine_credentials)
    5263             : {
    5264          61 :         char *password = NULL;
    5265             :         struct samr_QueryUserInfo q;
    5266             :         union samr_UserInfo *info;
    5267             :         NTSTATUS status;
    5268          61 :         struct dcerpc_binding_handle *b = p->binding_handle;
    5269             : 
    5270          61 :         bool ret = true;
    5271             :         int i;
    5272             :         uint32_t rid;
    5273          61 :         const uint32_t password_fields[] = {
    5274             :                 SAMR_FIELD_NT_PASSWORD_PRESENT,
    5275             :                 SAMR_FIELD_LM_PASSWORD_PRESENT,
    5276             :                 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
    5277             :                 0
    5278             :         };
    5279             : 
    5280          61 :         status = test_LookupName(b, tctx, domain_handle, base_acct_name, &rid);
    5281          61 :         if (!NT_STATUS_IS_OK(status)) {
    5282           0 :                 ret = false;
    5283             :         }
    5284             : 
    5285          61 :         switch (which_ops) {
    5286          16 :         case TORTURE_SAMR_USER_ATTRIBUTES:
    5287          16 :                 if (!test_QuerySecurity(b, tctx, user_handle)) {
    5288           2 :                         ret = false;
    5289             :                 }
    5290             : 
    5291          16 :                 if (!test_QueryUserInfo(b, tctx, user_handle)) {
    5292           0 :                         ret = false;
    5293             :                 }
    5294             : 
    5295          16 :                 if (!test_QueryUserInfo2(b, tctx, user_handle)) {
    5296           0 :                         ret = false;
    5297             :                 }
    5298             : 
    5299          16 :                 if (!test_SetUserInfo(b, tctx, user_handle, base_acct_flags,
    5300             :                                       base_acct_name)) {
    5301           4 :                         ret = false;
    5302             :                 }
    5303             : 
    5304          16 :                 if (!test_GetUserPwInfo(b, tctx, user_handle)) {
    5305           0 :                         ret = false;
    5306             :                 }
    5307             : 
    5308          16 :                 if (!test_TestPrivateFunctionsUser(b, tctx, user_handle)) {
    5309           2 :                         ret = false;
    5310             :                 }
    5311             : 
    5312          16 :                 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
    5313           0 :                         ret = false;
    5314             :                 }
    5315          16 :                 break;
    5316           8 :         case TORTURE_SAMR_PASSWORDS:
    5317           8 :                 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
    5318             :                         char simple_pass[9];
    5319           2 :                         char *v = generate_random_str(tctx, 1);
    5320             : 
    5321           2 :                         ZERO_STRUCT(simple_pass);
    5322           2 :                         memset(simple_pass, *v, sizeof(simple_pass) - 1);
    5323             : 
    5324           2 :                         torture_comment(tctx, "Testing machine account password policy rules\n");
    5325             : 
    5326             :                         /* Workstation trust accounts don't seem to need to honour password quality policy */
    5327           2 :                         if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
    5328           0 :                                 ret = false;
    5329             :                         }
    5330             : 
    5331           2 :                         if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
    5332           0 :                                 ret = false;
    5333             :                         }
    5334             : 
    5335             :                         /* reset again, to allow another 'user' password change */
    5336           2 :                         if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
    5337           0 :                                 ret = false;
    5338             :                         }
    5339             : 
    5340             :                         /* Try a 'short' password */
    5341           2 :                         if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
    5342           0 :                                 ret = false;
    5343             :                         }
    5344             : 
    5345             :                         /* Try a compleatly random password */
    5346           2 :                         if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
    5347           0 :                                 ret = false;
    5348             :                         }
    5349             :                 }
    5350             : 
    5351          32 :                 for (i = 0; password_fields[i]; i++) {
    5352          24 :                         if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
    5353           0 :                                 ret = false;
    5354             :                         }
    5355             : 
    5356             :                         /* check it was set right */
    5357          24 :                         if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
    5358           0 :                                 ret = false;
    5359             :                         }
    5360             :                 }
    5361             : 
    5362          32 :                 for (i = 0; password_fields[i]; i++) {
    5363          24 :                         if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
    5364           0 :                                 ret = false;
    5365             :                         }
    5366             : 
    5367             :                         /* check it was set right */
    5368          24 :                         if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
    5369           0 :                                 ret = false;
    5370             :                         }
    5371             :                 }
    5372             : 
    5373           8 :                 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
    5374           0 :                         ret = false;
    5375             :                 }
    5376             : 
    5377           8 :                 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
    5378           0 :                         ret = false;
    5379             :                 }
    5380             : 
    5381           8 :                 if (!test_SetUserPass_18(p, tctx, user_handle, &password)) {
    5382           0 :                         ret = false;
    5383             :                 }
    5384             : 
    5385           8 :                 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
    5386           0 :                         ret = false;
    5387             :                 }
    5388             : 
    5389          32 :                 for (i = 0; password_fields[i]; i++) {
    5390             : 
    5391          24 :                         if (password_fields[i] == SAMR_FIELD_LM_PASSWORD_PRESENT) {
    5392             :                                 /* we need to skip as that would break
    5393             :                                  * the ChangePasswordUser3 verify */
    5394           8 :                                 continue;
    5395             :                         }
    5396             : 
    5397          16 :                         if (!test_SetUserPass_21(p, tctx, user_handle, password_fields[i], &password)) {
    5398           0 :                                 ret = false;
    5399             :                         }
    5400             : 
    5401             :                         /* check it was set right */
    5402          16 :                         if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
    5403           0 :                                 ret = false;
    5404             :                         }
    5405             :                 }
    5406             : 
    5407           8 :                 q.in.user_handle = user_handle;
    5408           8 :                 q.in.level = 5;
    5409           8 :                 q.out.info = &info;
    5410             : 
    5411           8 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
    5412             :                         "QueryUserInfo failed");
    5413           8 :                 if (!NT_STATUS_IS_OK(q.out.result)) {
    5414           0 :                         torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level %u failed - %s\n",
    5415           0 :                                q.in.level, nt_errstr(q.out.result));
    5416           0 :                         ret = false;
    5417           7 :                 } else {
    5418           8 :                         uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
    5419           8 :                         if ((info->info5.acct_flags) != expected_flags) {
    5420             :                                 /* FIXME: GD */
    5421           2 :                                 if (!torture_setting_bool(tctx, "samba3", false)) {
    5422           0 :                                         torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
    5423           0 :                                                       info->info5.acct_flags,
    5424             :                                                       expected_flags);
    5425           0 :                                         ret = false;
    5426             :                                 }
    5427             :                         }
    5428           8 :                         if (info->info5.rid != rid) {
    5429           0 :                                 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
    5430           0 :                                        info->info5.rid, rid);
    5431             : 
    5432             :                         }
    5433             :                 }
    5434             : 
    5435           8 :                 break;
    5436             : 
    5437           8 :         case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
    5438             : 
    5439             :                 /* test last password change timestamp behaviour */
    5440           8 :                 torture_assert(tctx, test_SetPassword_pwdlastset(p, tctx, base_acct_flags,
    5441             :                                                                  base_acct_name,
    5442             :                                                                  user_handle, &password,
    5443             :                                                                  machine_credentials),
    5444             :                                "pwdLastSet test failed\n");
    5445           8 :                 break;
    5446             : 
    5447           8 :         case TORTURE_SAMR_PASSWORDS_BADPWDCOUNT:
    5448             : 
    5449             :                 /* test bad pwd count change behaviour */
    5450           8 :                 torture_assert(tctx, test_Password_badpwdcount_wrap(p, tctx, base_acct_flags,
    5451             :                                                                     base_acct_name,
    5452             :                                                                     domain_handle,
    5453             :                                                                     user_handle, &password,
    5454             :                                                                     machine_credentials),
    5455             :                                "badPwdCount test failed\n");
    5456           6 :                 break;
    5457             : 
    5458           6 :         case TORTURE_SAMR_PASSWORDS_LOCKOUT:
    5459             : 
    5460           6 :                 torture_assert(tctx, test_Password_lockout_wrap(p, tctx, base_acct_flags,
    5461             :                                                                 base_acct_name,
    5462             :                                                                 domain_handle,
    5463             :                                                                 user_handle, &password,
    5464             :                                                                 machine_credentials),
    5465             :                                "Lockout test failed");
    5466           4 :                 break;
    5467             : 
    5468             : 
    5469           8 :         case TORTURE_SAMR_USER_PRIVILEGES: {
    5470             : 
    5471             :                 struct dcerpc_pipe *lp;
    5472             :                 struct policy_handle *lsa_handle;
    5473             :                 struct dcerpc_binding_handle *lb;
    5474             : 
    5475           8 :                 status = torture_rpc_connection(tctx, &lp, &ndr_table_lsarpc);
    5476           8 :                 torture_assert_ntstatus_ok(tctx, status, "Failed to open LSA pipe");
    5477           8 :                 lb = lp->binding_handle;
    5478             : 
    5479           8 :                 if (!test_lsa_OpenPolicy2(lb, tctx, &lsa_handle)) {
    5480           0 :                         ret = false;
    5481             :                 }
    5482             : 
    5483           8 :                 if (!test_DeleteUser_with_privs(p, lp, tctx,
    5484             :                                                 domain_handle, lsa_handle, user_handle,
    5485             :                                                 domain_sid, rid,
    5486             :                                                 machine_credentials)) {
    5487           0 :                         ret = false;
    5488             :                 }
    5489             : 
    5490           8 :                 if (!test_lsa_Close(lb, tctx, lsa_handle)) {
    5491           0 :                         ret = false;
    5492             :                 }
    5493             : 
    5494           8 :                 if (!ret) {
    5495           0 :                         torture_result(tctx, TORTURE_FAIL, "privileged user delete test failed\n");
    5496             :                 }
    5497             : 
    5498           8 :                 break;
    5499             :         }
    5500           7 :         case TORTURE_SAMR_OTHER:
    5501             :         case TORTURE_SAMR_MANY_ACCOUNTS:
    5502             :         case TORTURE_SAMR_MANY_GROUPS:
    5503             :         case TORTURE_SAMR_MANY_ALIASES:
    5504             :                 /* We just need the account to exist */
    5505           7 :                 break;
    5506             :         }
    5507          57 :         return ret;
    5508             : }
    5509             : 
    5510           7 : static bool test_alias_ops(struct dcerpc_binding_handle *b,
    5511             :                            struct torture_context *tctx,
    5512             :                            struct policy_handle *alias_handle,
    5513             :                            const struct dom_sid *domain_sid)
    5514             : {
    5515           7 :         bool ret = true;
    5516             : 
    5517           7 :         if (!torture_setting_bool(tctx, "samba3", false)) {
    5518           3 :                 if (!test_QuerySecurity(b, tctx, alias_handle)) {
    5519           0 :                         ret = false;
    5520             :                 }
    5521             :         }
    5522             : 
    5523           7 :         if (!test_QueryAliasInfo(b, tctx, alias_handle)) {
    5524           0 :                 ret = false;
    5525             :         }
    5526             : 
    5527           7 :         if (!test_SetAliasInfo(b, tctx, alias_handle)) {
    5528           0 :                 ret = false;
    5529             :         }
    5530             : 
    5531           7 :         if (!test_AddMemberToAlias(b, tctx, alias_handle, domain_sid)) {
    5532           0 :                 ret = false;
    5533             :         }
    5534             : 
    5535          10 :         if (torture_setting_bool(tctx, "samba3", false) ||
    5536           3 :             torture_setting_bool(tctx, "samba4", false)) {
    5537           7 :                 torture_comment(tctx, "skipping MultipleMembers Alias tests against Samba\n");
    5538           7 :                 return ret;
    5539             :         }
    5540             : 
    5541           0 :         if (!test_AddMultipleMembersToAlias(b, tctx, alias_handle)) {
    5542           0 :                 ret = false;
    5543             :         }
    5544             : 
    5545           0 :         return ret;
    5546             : }
    5547             : 
    5548             : 
    5549         482 : static bool test_DeleteUser(struct dcerpc_binding_handle *b,
    5550             :                             struct torture_context *tctx,
    5551             :                             struct policy_handle *user_handle)
    5552             : {
    5553             :         struct samr_DeleteUser d;
    5554         482 :         torture_comment(tctx, "Testing DeleteUser\n");
    5555             : 
    5556         482 :         d.in.user_handle = user_handle;
    5557         482 :         d.out.user_handle = user_handle;
    5558             : 
    5559         482 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, tctx, &d),
    5560             :                 "DeleteUser failed");
    5561         482 :         torture_assert_ntstatus_ok(tctx, d.out.result, "DeleteUser");
    5562             : 
    5563         482 :         return true;
    5564             : }
    5565             : 
    5566           0 : bool test_DeleteUser_byname(struct dcerpc_binding_handle *b,
    5567             :                             struct torture_context *tctx,
    5568             :                             struct policy_handle *handle, const char *name)
    5569             : {
    5570             :         NTSTATUS status;
    5571             :         struct samr_DeleteUser d;
    5572             :         struct policy_handle user_handle;
    5573             :         uint32_t rid;
    5574             : 
    5575           0 :         status = test_LookupName(b, tctx, handle, name, &rid);
    5576           0 :         if (!NT_STATUS_IS_OK(status)) {
    5577           0 :                 goto failed;
    5578             :         }
    5579             : 
    5580           0 :         status = test_OpenUser_byname(b, tctx, handle, name, &user_handle);
    5581           0 :         if (!NT_STATUS_IS_OK(status)) {
    5582           0 :                 goto failed;
    5583             :         }
    5584             : 
    5585           0 :         d.in.user_handle = &user_handle;
    5586           0 :         d.out.user_handle = &user_handle;
    5587           0 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, tctx, &d),
    5588             :                 "DeleteUser failed");
    5589           0 :         if (!NT_STATUS_IS_OK(d.out.result)) {
    5590           0 :                 status = d.out.result;
    5591           0 :                 goto failed;
    5592             :         }
    5593             : 
    5594           0 :         return true;
    5595             : 
    5596           0 : failed:
    5597           0 :         torture_result(tctx, TORTURE_FAIL, "DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
    5598           0 :         return false;
    5599             : }
    5600             : 
    5601             : 
    5602           0 : static bool test_DeleteGroup_byname(struct dcerpc_binding_handle *b,
    5603             :                                     struct torture_context *tctx,
    5604             :                                     struct policy_handle *handle, const char *name)
    5605             : {
    5606             :         NTSTATUS status;
    5607             :         struct samr_OpenGroup r;
    5608             :         struct samr_DeleteDomainGroup d;
    5609             :         struct policy_handle group_handle;
    5610             :         uint32_t rid;
    5611             : 
    5612           0 :         status = test_LookupName(b, tctx, handle, name, &rid);
    5613           0 :         if (!NT_STATUS_IS_OK(status)) {
    5614           0 :                 goto failed;
    5615             :         }
    5616             : 
    5617           0 :         r.in.domain_handle = handle;
    5618           0 :         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    5619           0 :         r.in.rid = rid;
    5620           0 :         r.out.group_handle = &group_handle;
    5621           0 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenGroup_r(b, tctx, &r),
    5622             :                 "OpenGroup failed");
    5623           0 :         if (!NT_STATUS_IS_OK(r.out.result)) {
    5624           0 :                 status = r.out.result;
    5625           0 :                 goto failed;
    5626             :         }
    5627             : 
    5628           0 :         d.in.group_handle = &group_handle;
    5629           0 :         d.out.group_handle = &group_handle;
    5630           0 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomainGroup_r(b, tctx, &d),
    5631             :                 "DeleteDomainGroup failed");
    5632           0 :         if (!NT_STATUS_IS_OK(d.out.result)) {
    5633           0 :                 status = d.out.result;
    5634           0 :                 goto failed;
    5635             :         }
    5636             : 
    5637           0 :         return true;
    5638             : 
    5639           0 : failed:
    5640           0 :         torture_result(tctx, TORTURE_FAIL, "DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
    5641           0 :         return false;
    5642             : }
    5643             : 
    5644             : 
    5645           0 : static bool test_DeleteAlias_byname(struct dcerpc_binding_handle *b,
    5646             :                                     struct torture_context *tctx,
    5647             :                                     struct policy_handle *domain_handle,
    5648             :                                     const char *name)
    5649             : {
    5650             :         NTSTATUS status;
    5651             :         struct samr_OpenAlias r;
    5652             :         struct samr_DeleteDomAlias d;
    5653             :         struct policy_handle alias_handle;
    5654             :         uint32_t rid;
    5655             : 
    5656           0 :         torture_comment(tctx, "Testing DeleteAlias_byname\n");
    5657             : 
    5658           0 :         status = test_LookupName(b, tctx, domain_handle, name, &rid);
    5659           0 :         if (!NT_STATUS_IS_OK(status)) {
    5660           0 :                 goto failed;
    5661             :         }
    5662             : 
    5663           0 :         r.in.domain_handle = domain_handle;
    5664           0 :         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    5665           0 :         r.in.rid = rid;
    5666           0 :         r.out.alias_handle = &alias_handle;
    5667           0 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenAlias_r(b, tctx, &r),
    5668             :                 "OpenAlias failed");
    5669           0 :         if (!NT_STATUS_IS_OK(r.out.result)) {
    5670           0 :                 status = r.out.result;
    5671           0 :                 goto failed;
    5672             :         }
    5673             : 
    5674           0 :         d.in.alias_handle = &alias_handle;
    5675           0 :         d.out.alias_handle = &alias_handle;
    5676           0 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomAlias_r(b, tctx, &d),
    5677             :                 "DeleteDomAlias failed");
    5678           0 :         if (!NT_STATUS_IS_OK(d.out.result)) {
    5679           0 :                 status = d.out.result;
    5680           0 :                 goto failed;
    5681             :         }
    5682             : 
    5683           0 :         return true;
    5684             : 
    5685           0 : failed:
    5686           0 :         torture_result(tctx, TORTURE_FAIL, "DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
    5687           0 :         return false;
    5688             : }
    5689             : 
    5690         457 : static bool test_DeleteAlias(struct dcerpc_binding_handle *b,
    5691             :                              struct torture_context *tctx,
    5692             :                              struct policy_handle *alias_handle)
    5693             : {
    5694             :         struct samr_DeleteDomAlias d;
    5695         457 :         bool ret = true;
    5696             : 
    5697         457 :         torture_comment(tctx, "Testing DeleteAlias\n");
    5698             : 
    5699         457 :         d.in.alias_handle = alias_handle;
    5700         457 :         d.out.alias_handle = alias_handle;
    5701             : 
    5702         457 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomAlias_r(b, tctx, &d),
    5703             :                 "DeleteDomAlias failed");
    5704         457 :         if (!NT_STATUS_IS_OK(d.out.result)) {
    5705           0 :                 torture_result(tctx, TORTURE_FAIL, "DeleteAlias failed - %s\n", nt_errstr(d.out.result));
    5706           0 :                 ret = false;
    5707             :         }
    5708             : 
    5709         457 :         return ret;
    5710             : }
    5711             : 
    5712        2114 : static bool test_CreateAlias(struct dcerpc_binding_handle *b,
    5713             :                              struct torture_context *tctx,
    5714             :                              struct policy_handle *domain_handle,
    5715             :                              const char *alias_name,
    5716             :                              struct policy_handle *alias_handle,
    5717             :                              const struct dom_sid *domain_sid,
    5718             :                              bool test_alias)
    5719             : {
    5720             :         struct samr_CreateDomAlias r;
    5721             :         struct lsa_String name;
    5722             :         uint32_t rid;
    5723        2114 :         bool ret = true;
    5724             : 
    5725        2114 :         init_lsa_String(&name, alias_name);
    5726        2114 :         r.in.domain_handle = domain_handle;
    5727        2114 :         r.in.alias_name = &name;
    5728        2114 :         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    5729        2114 :         r.out.alias_handle = alias_handle;
    5730        2114 :         r.out.rid = &rid;
    5731             : 
    5732        2114 :         torture_comment(tctx, "Testing CreateAlias (%s)\n", r.in.alias_name->string);
    5733             : 
    5734        2114 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomAlias_r(b, tctx, &r),
    5735             :                 "CreateDomAlias failed");
    5736             : 
    5737        2114 :         if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
    5738        1057 :                 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED)) {
    5739        1057 :                         torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.alias_name->string);
    5740        1057 :                         return true;
    5741             :                 } else {
    5742           0 :                         torture_result(tctx, TORTURE_FAIL, "Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
    5743             :                                nt_errstr(r.out.result));
    5744           0 :                         return false;
    5745             :                 }
    5746             :         }
    5747             : 
    5748        1057 :         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ALIAS_EXISTS)) {
    5749           0 :                 if (!test_DeleteAlias_byname(b, tctx, domain_handle, r.in.alias_name->string)) {
    5750           0 :                         return false;
    5751             :                 }
    5752           0 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomAlias_r(b, tctx, &r),
    5753             :                         "CreateDomAlias failed");
    5754             :         }
    5755             : 
    5756        1057 :         if (!NT_STATUS_IS_OK(r.out.result)) {
    5757           0 :                 torture_result(tctx, TORTURE_FAIL, "CreateAlias failed - %s\n", nt_errstr(r.out.result));
    5758           0 :                 return false;
    5759             :         }
    5760             : 
    5761        1057 :         if (!test_alias) {
    5762        1050 :                 return ret;
    5763             :         }
    5764             : 
    5765           7 :         if (!test_alias_ops(b, tctx, alias_handle, domain_sid)) {
    5766           0 :                 ret = false;
    5767             :         }
    5768             : 
    5769           7 :         return ret;
    5770             : }
    5771             : 
    5772           8 : static bool test_ChangePassword(struct dcerpc_pipe *p,
    5773             :                                 struct torture_context *tctx,
    5774             :                                 const char *acct_name,
    5775             :                                 struct policy_handle *domain_handle, char **password)
    5776             : {
    5777           8 :         bool ret = true;
    5778           8 :         struct dcerpc_binding_handle *b = p->binding_handle;
    5779             : 
    5780           8 :         if (!*password) {
    5781           0 :                 return false;
    5782             :         }
    5783             : 
    5784           8 :         if (!test_ChangePasswordUser(b, tctx, acct_name, domain_handle, password)) {
    5785           0 :                 ret = false;
    5786             :         }
    5787             : 
    5788           8 :         if (!test_ChangePasswordUser2(p, tctx, acct_name, password, 0, true)) {
    5789           0 :                 ret = false;
    5790             :         }
    5791             : 
    5792           8 :         if (!test_OemChangePasswordUser2(p, tctx, acct_name, domain_handle, password)) {
    5793           0 :                 ret = false;
    5794             :         }
    5795             : 
    5796             :         /* test what happens when setting the old password again */
    5797           8 :         if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, *password, 0, true)) {
    5798           0 :                 ret = false;
    5799             :         }
    5800             : 
    5801             :         {
    5802             :                 char simple_pass[9];
    5803           8 :                 char *v = generate_random_str(tctx, 1);
    5804             : 
    5805           8 :                 ZERO_STRUCT(simple_pass);
    5806           8 :                 memset(simple_pass, *v, sizeof(simple_pass) - 1);
    5807             : 
    5808             :                 /* test what happens when picking a simple password */
    5809           8 :                 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, simple_pass, 0, true)) {
    5810           0 :                         ret = false;
    5811             :                 }
    5812             :         }
    5813             : 
    5814             :         /* set samr_SetDomainInfo level 1 with min_length 5 */
    5815             :         {
    5816             :                 struct samr_QueryDomainInfo r;
    5817           8 :                 union samr_DomainInfo *info = NULL;
    5818             :                 struct samr_SetDomainInfo s;
    5819             :                 uint16_t len_old, len;
    5820             :                 uint32_t pwd_prop_old;
    5821             :                 int64_t min_pwd_age_old;
    5822             : 
    5823           8 :                 len = 5;
    5824             : 
    5825           8 :                 r.in.domain_handle = domain_handle;
    5826           8 :                 r.in.level = 1;
    5827           8 :                 r.out.info = &info;
    5828             : 
    5829           8 :                 torture_comment(tctx, "Testing samr_QueryDomainInfo level 1\n");
    5830           8 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &r),
    5831             :                         "QueryDomainInfo failed");
    5832           8 :                 if (!NT_STATUS_IS_OK(r.out.result)) {
    5833           0 :                         return false;
    5834             :                 }
    5835             : 
    5836           8 :                 s.in.domain_handle = domain_handle;
    5837           8 :                 s.in.level = 1;
    5838           8 :                 s.in.info = info;
    5839             : 
    5840             :                 /* remember the old min length, so we can reset it */
    5841           8 :                 len_old = s.in.info->info1.min_password_length;
    5842           8 :                 s.in.info->info1.min_password_length = len;
    5843           8 :                 pwd_prop_old = s.in.info->info1.password_properties;
    5844             :                 /* turn off password complexity checks for this test */
    5845           8 :                 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
    5846             : 
    5847           8 :                 min_pwd_age_old = s.in.info->info1.min_password_age;
    5848           8 :                 s.in.info->info1.min_password_age = 0;
    5849             : 
    5850           8 :                 torture_comment(tctx, "Testing samr_SetDomainInfo level 1\n");
    5851           8 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
    5852             :                         "SetDomainInfo failed");
    5853           8 :                 if (!NT_STATUS_IS_OK(s.out.result)) {
    5854           0 :                         return false;
    5855             :                 }
    5856             : 
    5857           8 :                 torture_comment(tctx, "calling test_ChangePasswordUser3 with too short password\n");
    5858             : 
    5859           8 :                 if (!test_ChangePasswordUser3(p, tctx, acct_name, len - 1, password, NULL, 0, true)) {
    5860           0 :                         ret = false;
    5861             :                 }
    5862             : 
    5863           8 :                 s.in.info->info1.min_password_length = len_old;
    5864           8 :                 s.in.info->info1.password_properties = pwd_prop_old;
    5865           8 :                 s.in.info->info1.min_password_age = min_pwd_age_old;
    5866             : 
    5867           8 :                 torture_comment(tctx, "Testing samr_SetDomainInfo level 1\n");
    5868           8 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
    5869             :                         "SetDomainInfo failed");
    5870           8 :                 if (!NT_STATUS_IS_OK(s.out.result)) {
    5871           0 :                         return false;
    5872             :                 }
    5873             : 
    5874             :         }
    5875             : 
    5876             :         {
    5877             :                 struct samr_OpenUser r;
    5878             :                 struct samr_QueryUserInfo q;
    5879             :                 union samr_UserInfo *info;
    5880             :                 struct samr_LookupNames n;
    5881             :                 struct policy_handle user_handle;
    5882             :                 struct samr_Ids rids, types;
    5883             : 
    5884           8 :                 n.in.domain_handle = domain_handle;
    5885           8 :                 n.in.num_names = 1;
    5886           8 :                 n.in.names = talloc_array(tctx, struct lsa_String, 1);
    5887           8 :                 n.in.names[0].string = acct_name;
    5888           8 :                 n.out.rids = &rids;
    5889           8 :                 n.out.types = &types;
    5890             : 
    5891           8 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupNames_r(b, tctx, &n),
    5892             :                         "LookupNames failed");
    5893           8 :                 if (!NT_STATUS_IS_OK(n.out.result)) {
    5894           0 :                         torture_result(tctx, TORTURE_FAIL, "LookupNames failed - %s\n", nt_errstr(n.out.result));
    5895           0 :                         return false;
    5896             :                 }
    5897             : 
    5898           8 :                 r.in.domain_handle = domain_handle;
    5899           8 :                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    5900           8 :                 r.in.rid = n.out.rids->ids[0];
    5901           8 :                 r.out.user_handle = &user_handle;
    5902             : 
    5903           8 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
    5904             :                         "OpenUser failed");
    5905           8 :                 if (!NT_STATUS_IS_OK(r.out.result)) {
    5906           0 :                         torture_result(tctx, TORTURE_FAIL, "OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(r.out.result));
    5907           0 :                         return false;
    5908             :                 }
    5909             : 
    5910           8 :                 q.in.user_handle = &user_handle;
    5911           8 :                 q.in.level = 5;
    5912           8 :                 q.out.info = &info;
    5913             : 
    5914           8 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
    5915             :                         "QueryUserInfo failed");
    5916           8 :                 if (!NT_STATUS_IS_OK(q.out.result)) {
    5917           0 :                         torture_result(tctx, TORTURE_FAIL, "QueryUserInfo failed - %s\n", nt_errstr(q.out.result));
    5918           0 :                         return false;
    5919             :                 }
    5920             : 
    5921           8 :                 torture_comment(tctx, "calling test_ChangePasswordUser3 with too early password change\n");
    5922             : 
    5923           8 :                 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL,
    5924           8 :                                               info->info5.last_password_change, true)) {
    5925           0 :                         ret = false;
    5926             :                 }
    5927             :         }
    5928             : 
    5929             :         /* we change passwords twice - this has the effect of verifying
    5930             :            they were changed correctly for the final call */
    5931           8 :         if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
    5932           0 :                 ret = false;
    5933             :         }
    5934             : 
    5935           8 :         if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
    5936           0 :                 ret = false;
    5937             :         }
    5938             : 
    5939           8 :         return ret;
    5940             : }
    5941             : 
    5942        2174 : static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
    5943             :                             struct policy_handle *domain_handle,
    5944             :                             const char *user_name,
    5945             :                             struct policy_handle *user_handle_out,
    5946             :                             struct dom_sid *domain_sid,
    5947             :                             enum torture_samr_choice which_ops,
    5948             :                             struct cli_credentials *machine_credentials,
    5949             :                             bool test_user)
    5950             : {
    5951             : 
    5952             :         TALLOC_CTX *user_ctx;
    5953             : 
    5954             :         struct samr_CreateUser r;
    5955             :         struct samr_QueryUserInfo q;
    5956             :         union samr_UserInfo *info;
    5957             :         struct samr_DeleteUser d;
    5958             :         uint32_t rid;
    5959             : 
    5960             :         /* This call creates a 'normal' account - check that it really does */
    5961        2174 :         const uint32_t acct_flags = ACB_NORMAL;
    5962             :         struct lsa_String name;
    5963        2174 :         bool ret = true;
    5964        2174 :         struct dcerpc_binding_handle *b = p->binding_handle;
    5965             : 
    5966             :         struct policy_handle user_handle;
    5967        2174 :         user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
    5968        2174 :         init_lsa_String(&name, user_name);
    5969             : 
    5970        2174 :         r.in.domain_handle = domain_handle;
    5971        2174 :         r.in.account_name = &name;
    5972        2174 :         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    5973        2174 :         r.out.user_handle = &user_handle;
    5974        2174 :         r.out.rid = &rid;
    5975             : 
    5976        2174 :         torture_comment(tctx, "Testing CreateUser(%s)\n", r.in.account_name->string);
    5977             : 
    5978        2174 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser_r(b, user_ctx, &r),
    5979             :                 "CreateUser failed");
    5980             : 
    5981        2174 :         if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
    5982        1087 :                 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
    5983        1087 :                         torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.account_name->string);
    5984        1087 :                         return true;
    5985             :                 } else {
    5986           0 :                         torture_result(tctx, TORTURE_FAIL, "Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
    5987             :                                nt_errstr(r.out.result));
    5988           0 :                         return false;
    5989             :                 }
    5990             :         }
    5991             : 
    5992        1087 :         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_USER_EXISTS)) {
    5993           0 :                 if (!test_DeleteUser_byname(b, tctx, domain_handle, r.in.account_name->string)) {
    5994           0 :                         talloc_free(user_ctx);
    5995           0 :                         return false;
    5996             :                 }
    5997           0 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser_r(b, user_ctx, &r),
    5998             :                         "CreateUser failed");
    5999             :         }
    6000             : 
    6001        1087 :         if (!NT_STATUS_IS_OK(r.out.result)) {
    6002           0 :                 talloc_free(user_ctx);
    6003           0 :                 torture_result(tctx, TORTURE_FAIL, "CreateUser failed - %s\n", nt_errstr(r.out.result));
    6004           0 :                 return false;
    6005             :         }
    6006             : 
    6007        1087 :         if (!test_user) {
    6008        1050 :                 if (user_handle_out) {
    6009        1050 :                         *user_handle_out = user_handle;
    6010             :                 }
    6011        1050 :                 return ret;
    6012             :         }
    6013             : 
    6014             :         {
    6015          37 :                 q.in.user_handle = &user_handle;
    6016          37 :                 q.in.level = 16;
    6017          37 :                 q.out.info = &info;
    6018             : 
    6019          37 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, user_ctx, &q),
    6020             :                         "QueryUserInfo failed");
    6021          37 :                 if (!NT_STATUS_IS_OK(q.out.result)) {
    6022           0 :                         torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level %u failed - %s\n",
    6023           0 :                                q.in.level, nt_errstr(q.out.result));
    6024           0 :                         ret = false;
    6025             :                 } else {
    6026          37 :                         if ((info->info16.acct_flags & acct_flags) != acct_flags) {
    6027           0 :                                 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
    6028           0 :                                        info->info16.acct_flags,
    6029             :                                        acct_flags);
    6030           0 :                                 ret = false;
    6031             :                         }
    6032             :                 }
    6033             : 
    6034          37 :                 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
    6035             :                                    domain_sid, acct_flags, name.string, which_ops,
    6036             :                                    machine_credentials)) {
    6037           8 :                         ret = false;
    6038             :                 }
    6039             : 
    6040          37 :                 if (user_handle_out) {
    6041          37 :                         *user_handle_out = user_handle;
    6042             :                 } else {
    6043           0 :                         torture_comment(tctx, "Testing DeleteUser (createuser test)\n");
    6044             : 
    6045           0 :                         d.in.user_handle = &user_handle;
    6046           0 :                         d.out.user_handle = &user_handle;
    6047             : 
    6048           0 :                         torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, user_ctx, &d),
    6049             :                                 "DeleteUser failed");
    6050           0 :                         if (!NT_STATUS_IS_OK(d.out.result)) {
    6051           0 :                                 torture_result(tctx, TORTURE_FAIL, "DeleteUser failed - %s\n", nt_errstr(d.out.result));
    6052           0 :                                 ret = false;
    6053             :                         }
    6054             :                 }
    6055             : 
    6056             :         }
    6057             : 
    6058          37 :         talloc_free(user_ctx);
    6059             : 
    6060          37 :         return ret;
    6061             : }
    6062             : 
    6063             : 
    6064          16 : static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
    6065             :                              struct policy_handle *domain_handle,
    6066             :                              struct dom_sid *domain_sid,
    6067             :                              enum torture_samr_choice which_ops,
    6068             :                              struct cli_credentials *machine_credentials)
    6069             : {
    6070             :         struct samr_CreateUser2 r;
    6071             :         struct samr_QueryUserInfo q;
    6072             :         union samr_UserInfo *info;
    6073             :         struct samr_DeleteUser d;
    6074             :         struct policy_handle user_handle;
    6075             :         uint32_t rid;
    6076             :         struct lsa_String name;
    6077          16 :         bool ret = true;
    6078             :         int i;
    6079          16 :         struct dcerpc_binding_handle *b = p->binding_handle;
    6080             : 
    6081             :         struct {
    6082             :                 uint32_t acct_flags;
    6083             :                 const char *account_name;
    6084             :                 NTSTATUS nt_status;
    6085          16 :         } account_types[] = {
    6086             :                 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
    6087             :                 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
    6088             :                 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
    6089             :                 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
    6090             :                 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
    6091             :                 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
    6092             :                 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
    6093             :                 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
    6094             :                 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
    6095             :                 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_ACCESS_DENIED },
    6096             :                 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
    6097             :                 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
    6098             :                 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
    6099             :                 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
    6100             :                 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
    6101             :         };
    6102             : 
    6103         240 :         for (i = 0; account_types[i].account_name; i++) {
    6104             :                 TALLOC_CTX *user_ctx;
    6105         224 :                 uint32_t acct_flags = account_types[i].acct_flags;
    6106             :                 uint32_t access_granted;
    6107         224 :                 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
    6108         224 :                 init_lsa_String(&name, account_types[i].account_name);
    6109             : 
    6110         224 :                 r.in.domain_handle = domain_handle;
    6111         224 :                 r.in.account_name = &name;
    6112         224 :                 r.in.acct_flags = acct_flags;
    6113         224 :                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    6114         224 :                 r.out.user_handle = &user_handle;
    6115         224 :                 r.out.access_granted = &access_granted;
    6116         224 :                 r.out.rid = &rid;
    6117             : 
    6118         224 :                 torture_comment(tctx, "Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
    6119             : 
    6120         224 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser2_r(b, user_ctx, &r),
    6121             :                         "CreateUser2 failed");
    6122             : 
    6123         224 :                 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
    6124         112 :                         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
    6125         112 :                                 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.account_name->string);
    6126         210 :                                 continue;
    6127             :                         } else {
    6128           0 :                                 torture_result(tctx, TORTURE_FAIL, "Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
    6129             :                                        nt_errstr(r.out.result));
    6130           0 :                                 ret = false;
    6131           0 :                                 continue;
    6132             :                         }
    6133             :                 }
    6134             : 
    6135         112 :                 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_USER_EXISTS)) {
    6136           0 :                         if (!test_DeleteUser_byname(b, tctx, domain_handle, r.in.account_name->string)) {
    6137           0 :                                 talloc_free(user_ctx);
    6138           0 :                                 ret = false;
    6139           0 :                                 continue;
    6140             :                         }
    6141           0 :                         torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser2_r(b, user_ctx, &r),
    6142             :                                 "CreateUser2 failed");
    6143             : 
    6144             :                 }
    6145         112 :                 if (!NT_STATUS_EQUAL(r.out.result, account_types[i].nt_status)) {
    6146           0 :                         torture_result(tctx, TORTURE_FAIL, "CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
    6147             :                                nt_errstr(r.out.result), nt_errstr(account_types[i].nt_status));
    6148           0 :                         ret = false;
    6149             :                 }
    6150             : 
    6151         112 :                 if (NT_STATUS_IS_OK(r.out.result)) {
    6152          24 :                         q.in.user_handle = &user_handle;
    6153          24 :                         q.in.level = 5;
    6154          24 :                         q.out.info = &info;
    6155             : 
    6156          24 :                         torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, user_ctx, &q),
    6157             :                                 "QueryUserInfo failed");
    6158          24 :                         if (!NT_STATUS_IS_OK(q.out.result)) {
    6159           0 :                                 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level %u failed - %s\n",
    6160           0 :                                        q.in.level, nt_errstr(q.out.result));
    6161           0 :                                 ret = false;
    6162             :                         } else {
    6163          24 :                                 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
    6164          24 :                                 if (acct_flags == ACB_NORMAL) {
    6165           8 :                                         expected_flags |= ACB_PW_EXPIRED;
    6166             :                                 }
    6167          24 :                                 if ((info->info5.acct_flags) != expected_flags) {
    6168           0 :                                         torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
    6169           0 :                                                info->info5.acct_flags,
    6170             :                                                expected_flags);
    6171           0 :                                         ret = false;
    6172             :                                 }
    6173          24 :                                 switch (acct_flags) {
    6174           8 :                                 case ACB_SVRTRUST:
    6175           8 :                                         if (info->info5.primary_gid != DOMAIN_RID_DCS) {
    6176           0 :                                                 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 5: DC should have had Primary Group %d, got %d\n",
    6177           0 :                                                        DOMAIN_RID_DCS, info->info5.primary_gid);
    6178           0 :                                                 ret = false;
    6179             :                                         }
    6180           8 :                                         break;
    6181           8 :                                 case ACB_WSTRUST:
    6182           8 :                                         if (info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
    6183           0 :                                                 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
    6184           0 :                                                        DOMAIN_RID_DOMAIN_MEMBERS, info->info5.primary_gid);
    6185           0 :                                                 ret = false;
    6186             :                                         }
    6187           8 :                                         break;
    6188           8 :                                 case ACB_NORMAL:
    6189           8 :                                         if (info->info5.primary_gid != DOMAIN_RID_USERS) {
    6190           0 :                                                 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 5: Users should have had Primary Group %d, got %d\n",
    6191           0 :                                                        DOMAIN_RID_USERS, info->info5.primary_gid);
    6192           0 :                                                 ret = false;
    6193             :                                         }
    6194           8 :                                         break;
    6195             :                                 }
    6196             :                         }
    6197             : 
    6198          24 :                         if (!test_user_ops(p, tctx, &user_handle, domain_handle,
    6199             :                                            domain_sid, acct_flags, name.string, which_ops,
    6200             :                                            machine_credentials)) {
    6201           0 :                                 ret = false;
    6202             :                         }
    6203             : 
    6204          24 :                         if (!ndr_policy_handle_empty(&user_handle)) {
    6205          21 :                                 torture_comment(tctx, "Testing DeleteUser (createuser2 test)\n");
    6206             : 
    6207          21 :                                 d.in.user_handle = &user_handle;
    6208          21 :                                 d.out.user_handle = &user_handle;
    6209             : 
    6210          21 :                                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, user_ctx, &d),
    6211             :                                         "DeleteUser failed");
    6212          21 :                                 if (!NT_STATUS_IS_OK(d.out.result)) {
    6213           0 :                                         torture_result(tctx, TORTURE_FAIL, "DeleteUser failed - %s\n", nt_errstr(d.out.result));
    6214           0 :                                         ret = false;
    6215             :                                 }
    6216             :                         }
    6217             :                 }
    6218         112 :                 talloc_free(user_ctx);
    6219             :         }
    6220             : 
    6221          16 :         return ret;
    6222             : }
    6223             : 
    6224         148 : static bool test_QueryAliasInfo(struct dcerpc_binding_handle *b,
    6225             :                                 struct torture_context *tctx,
    6226             :                                 struct policy_handle *handle)
    6227             : {
    6228             :         struct samr_QueryAliasInfo r;
    6229             :         union samr_AliasInfo *info;
    6230         148 :         uint16_t levels[] = {1, 2, 3};
    6231             :         int i;
    6232         148 :         bool ret = true;
    6233             : 
    6234         592 :         for (i=0;i<ARRAY_SIZE(levels);i++) {
    6235         444 :                 torture_comment(tctx, "Testing QueryAliasInfo level %u\n", levels[i]);
    6236             : 
    6237         444 :                 r.in.alias_handle = handle;
    6238         444 :                 r.in.level = levels[i];
    6239         444 :                 r.out.info = &info;
    6240             : 
    6241         444 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryAliasInfo_r(b, tctx, &r),
    6242             :                         "QueryAliasInfo failed");
    6243         444 :                 if (!NT_STATUS_IS_OK(r.out.result)) {
    6244           0 :                         torture_result(tctx, TORTURE_FAIL, "QueryAliasInfo level %u failed - %s\n",
    6245           0 :                                levels[i], nt_errstr(r.out.result));
    6246           0 :                         ret = false;
    6247             :                 }
    6248             :         }
    6249             : 
    6250         148 :         return ret;
    6251             : }
    6252             : 
    6253          69 : static bool test_QueryGroupInfo(struct dcerpc_binding_handle *b,
    6254             :                                 struct torture_context *tctx,
    6255             :                                 struct policy_handle *handle)
    6256             : {
    6257             :         struct samr_QueryGroupInfo r;
    6258             :         union samr_GroupInfo *info;
    6259          69 :         uint16_t levels[] = {1, 2, 3, 4, 5};
    6260             :         int i;
    6261          69 :         bool ret = true;
    6262             : 
    6263         414 :         for (i=0;i<ARRAY_SIZE(levels);i++) {
    6264         345 :                 torture_comment(tctx, "Testing QueryGroupInfo level %u\n", levels[i]);
    6265             : 
    6266         345 :                 r.in.group_handle = handle;
    6267         345 :                 r.in.level = levels[i];
    6268         345 :                 r.out.info = &info;
    6269             : 
    6270         345 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupInfo_r(b, tctx, &r),
    6271             :                         "QueryGroupInfo failed");
    6272         345 :                 if (!NT_STATUS_IS_OK(r.out.result)) {
    6273           0 :                         torture_result(tctx, TORTURE_FAIL, "QueryGroupInfo level %u failed - %s\n",
    6274           0 :                                levels[i], nt_errstr(r.out.result));
    6275           0 :                         ret = false;
    6276             :                 }
    6277             :         }
    6278             : 
    6279          69 :         return ret;
    6280             : }
    6281             : 
    6282          69 : static bool test_QueryGroupMember(struct dcerpc_binding_handle *b,
    6283             :                                   struct torture_context *tctx,
    6284             :                                   struct policy_handle *handle)
    6285             : {
    6286             :         struct samr_QueryGroupMember r;
    6287          69 :         struct samr_RidAttrArray *rids = NULL;
    6288          69 :         bool ret = true;
    6289             : 
    6290          69 :         torture_comment(tctx, "Testing QueryGroupMember\n");
    6291             : 
    6292          69 :         r.in.group_handle = handle;
    6293          69 :         r.out.rids = &rids;
    6294             : 
    6295          69 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupMember_r(b, tctx, &r),
    6296             :                 "QueryGroupMember failed");
    6297          69 :         if (!NT_STATUS_IS_OK(r.out.result)) {
    6298           0 :                 torture_result(tctx, TORTURE_FAIL, "QueryGroupMember failed - %s\n", nt_errstr(r.out.result));
    6299           0 :                 ret = false;
    6300             :         }
    6301             : 
    6302          69 :         return ret;
    6303             : }
    6304             : 
    6305             : 
    6306           7 : static bool test_SetGroupInfo(struct dcerpc_binding_handle *b,
    6307             :                               struct torture_context *tctx,
    6308             :                               struct policy_handle *handle)
    6309             : {
    6310             :         struct samr_QueryGroupInfo r;
    6311             :         union samr_GroupInfo *info;
    6312             :         struct samr_SetGroupInfo s;
    6313           7 :         uint16_t levels[] = {1, 2, 3, 4};
    6314           7 :         uint16_t set_ok[] = {0, 1, 1, 1};
    6315             :         int i;
    6316           7 :         bool ret = true;
    6317             : 
    6318          35 :         for (i=0;i<ARRAY_SIZE(levels);i++) {
    6319          28 :                 torture_comment(tctx, "Testing QueryGroupInfo level %u\n", levels[i]);
    6320             : 
    6321          28 :                 r.in.group_handle = handle;
    6322          28 :                 r.in.level = levels[i];
    6323          28 :                 r.out.info = &info;
    6324             : 
    6325          28 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupInfo_r(b, tctx, &r),
    6326             :                         "QueryGroupInfo failed");
    6327          28 :                 if (!NT_STATUS_IS_OK(r.out.result)) {
    6328           0 :                         torture_result(tctx, TORTURE_FAIL, "QueryGroupInfo level %u failed - %s\n",
    6329           0 :                                levels[i], nt_errstr(r.out.result));
    6330           0 :                         ret = false;
    6331             :                 }
    6332             : 
    6333          28 :                 torture_comment(tctx, "Testing SetGroupInfo level %u\n", levels[i]);
    6334             : 
    6335          28 :                 s.in.group_handle = handle;
    6336          28 :                 s.in.level = levels[i];
    6337          28 :                 s.in.info = *r.out.info;
    6338             : 
    6339             : #if 0
    6340             :                 /* disabled this, as it changes the name only from the point of view of samr,
    6341             :                    but leaves the name from the point of view of w2k3 internals (and ldap). This means
    6342             :                    the name is still reserved, so creating the old name fails, but deleting by the old name
    6343             :                    also fails */
    6344             :                 if (s.in.level == 2) {
    6345             :                         init_lsa_String(&s.in.info->string, "NewName");
    6346             :                 }
    6347             : #endif
    6348             : 
    6349          28 :                 if (s.in.level == 4) {
    6350           7 :                         init_lsa_String(&s.in.info->description, "test description");
    6351             :                 }
    6352             : 
    6353          28 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetGroupInfo_r(b, tctx, &s),
    6354             :                         "SetGroupInfo failed");
    6355          28 :                 if (set_ok[i]) {
    6356          21 :                         if (!NT_STATUS_IS_OK(s.out.result)) {
    6357           0 :                                 torture_result(tctx, TORTURE_FAIL, "SetGroupInfo level %u failed - %s\n",
    6358           0 :                                        r.in.level, nt_errstr(s.out.result));
    6359           0 :                                 ret = false;
    6360           0 :                                 continue;
    6361             :                         }
    6362             :                 } else {
    6363           7 :                         if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, s.out.result)) {
    6364           0 :                                 torture_result(tctx, TORTURE_FAIL, "SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
    6365           0 :                                        r.in.level, nt_errstr(s.out.result));
    6366           0 :                                 ret = false;
    6367           0 :                                 continue;
    6368             :                         }
    6369             :                 }
    6370             :         }
    6371             : 
    6372           7 :         return ret;
    6373             : }
    6374             : 
    6375          18 : static bool test_QueryUserInfo(struct dcerpc_binding_handle *b,
    6376             :                                struct torture_context *tctx,
    6377             :                                struct policy_handle *handle)
    6378             : {
    6379             :         struct samr_QueryUserInfo r;
    6380             :         union samr_UserInfo *info;
    6381          18 :         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
    6382             :                            11, 12, 13, 14, 16, 17, 20, 21};
    6383             :         int i;
    6384          18 :         bool ret = true;
    6385             : 
    6386         342 :         for (i=0;i<ARRAY_SIZE(levels);i++) {
    6387         324 :                 torture_comment(tctx, "Testing QueryUserInfo level %u\n", levels[i]);
    6388             : 
    6389         324 :                 r.in.user_handle = handle;
    6390         324 :                 r.in.level = levels[i];
    6391         324 :                 r.out.info = &info;
    6392             : 
    6393         324 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
    6394             :                         "QueryUserInfo failed");
    6395         324 :                 if (!NT_STATUS_IS_OK(r.out.result)) {
    6396           0 :                         torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level %u failed - %s\n",
    6397           0 :                                levels[i], nt_errstr(r.out.result));
    6398           0 :                         ret = false;
    6399             :                 }
    6400             :         }
    6401             : 
    6402          18 :         return ret;
    6403             : }
    6404             : 
    6405          18 : static bool test_QueryUserInfo2(struct dcerpc_binding_handle *b,
    6406             :                                 struct torture_context *tctx,
    6407             :                                 struct policy_handle *handle)
    6408             : {
    6409             :         struct samr_QueryUserInfo2 r;
    6410             :         union samr_UserInfo *info;
    6411          18 :         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
    6412             :                            11, 12, 13, 14, 16, 17, 20, 21};
    6413             :         int i;
    6414          18 :         bool ret = true;
    6415             : 
    6416         342 :         for (i=0;i<ARRAY_SIZE(levels);i++) {
    6417         324 :                 torture_comment(tctx, "Testing QueryUserInfo2 level %u\n", levels[i]);
    6418             : 
    6419         324 :                 r.in.user_handle = handle;
    6420         324 :                 r.in.level = levels[i];
    6421         324 :                 r.out.info = &info;
    6422             : 
    6423         324 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo2_r(b, tctx, &r),
    6424             :                         "QueryUserInfo2 failed");
    6425         324 :                 if (!NT_STATUS_IS_OK(r.out.result)) {
    6426           0 :                         torture_result(tctx, TORTURE_FAIL, "QueryUserInfo2 level %u failed - %s\n",
    6427           0 :                                levels[i], nt_errstr(r.out.result));
    6428           0 :                         ret = false;
    6429             :                 }
    6430             :         }
    6431             : 
    6432          18 :         return ret;
    6433             : }
    6434             : 
    6435           2 : static bool test_OpenUser(struct dcerpc_binding_handle *b,
    6436             :                           struct torture_context *tctx,
    6437             :                           struct policy_handle *handle, uint32_t rid)
    6438             : {
    6439             :         struct samr_OpenUser r;
    6440             :         struct policy_handle user_handle;
    6441           2 :         bool ret = true;
    6442             : 
    6443           2 :         torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
    6444             : 
    6445           2 :         r.in.domain_handle = handle;
    6446           2 :         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    6447           2 :         r.in.rid = rid;
    6448           2 :         r.out.user_handle = &user_handle;
    6449             : 
    6450           2 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
    6451             :                 "OpenUser failed");
    6452           2 :         if (!NT_STATUS_IS_OK(r.out.result)) {
    6453           0 :                 torture_result(tctx, TORTURE_FAIL, "OpenUser(%u) failed - %s\n", rid, nt_errstr(r.out.result));
    6454           0 :                 return false;
    6455             :         }
    6456             : 
    6457           2 :         if (!test_QuerySecurity(b, tctx, &user_handle)) {
    6458           0 :                 ret = false;
    6459             :         }
    6460             : 
    6461           2 :         if (!test_QueryUserInfo(b, tctx, &user_handle)) {
    6462           0 :                 ret = false;
    6463             :         }
    6464             : 
    6465           2 :         if (!test_QueryUserInfo2(b, tctx, &user_handle)) {
    6466           0 :                 ret = false;
    6467             :         }
    6468             : 
    6469           2 :         if (!test_GetUserPwInfo(b, tctx, &user_handle)) {
    6470           0 :                 ret = false;
    6471             :         }
    6472             : 
    6473           2 :         if (!test_GetGroupsForUser(b, tctx, &user_handle)) {
    6474           0 :                 ret = false;
    6475             :         }
    6476             : 
    6477           2 :         if (!test_samr_handle_Close(b, tctx, &user_handle)) {
    6478           0 :                 ret = false;
    6479             :         }
    6480             : 
    6481           2 :         return ret;
    6482             : }
    6483             : 
    6484          69 : static bool test_OpenGroup(struct dcerpc_binding_handle *b,
    6485             :                            struct torture_context *tctx,
    6486             :                            struct policy_handle *handle, uint32_t rid)
    6487             : {
    6488             :         struct samr_OpenGroup r;
    6489             :         struct policy_handle group_handle;
    6490          69 :         bool ret = true;
    6491             : 
    6492          69 :         torture_comment(tctx, "Testing OpenGroup(%u)\n", rid);
    6493             : 
    6494          69 :         r.in.domain_handle = handle;
    6495          69 :         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    6496          69 :         r.in.rid = rid;
    6497          69 :         r.out.group_handle = &group_handle;
    6498             : 
    6499          69 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenGroup_r(b, tctx, &r),
    6500             :                 "OpenGroup failed");
    6501          69 :         if (!NT_STATUS_IS_OK(r.out.result)) {
    6502           0 :                 torture_result(tctx, TORTURE_FAIL, "OpenGroup(%u) failed - %s\n", rid, nt_errstr(r.out.result));
    6503           0 :                 return false;
    6504             :         }
    6505             : 
    6506          69 :         if (!torture_setting_bool(tctx, "samba3", false)) {
    6507          37 :                 if (!test_QuerySecurity(b, tctx, &group_handle)) {
    6508           0 :                         ret = false;
    6509             :                 }
    6510             :         }
    6511             : 
    6512          69 :         if (!test_QueryGroupInfo(b, tctx, &group_handle)) {
    6513           0 :                 ret = false;
    6514             :         }
    6515             : 
    6516          69 :         if (!test_QueryGroupMember(b, tctx, &group_handle)) {
    6517           0 :                 ret = false;
    6518             :         }
    6519             : 
    6520          69 :         if (!test_samr_handle_Close(b, tctx, &group_handle)) {
    6521           0 :                 ret = false;
    6522             :         }
    6523             : 
    6524          69 :         return ret;
    6525             : }
    6526             : 
    6527         141 : static bool test_OpenAlias(struct dcerpc_binding_handle *b,
    6528             :                            struct torture_context *tctx,
    6529             :                            struct policy_handle *handle, uint32_t rid)
    6530             : {
    6531             :         struct samr_OpenAlias r;
    6532             :         struct policy_handle alias_handle;
    6533         141 :         bool ret = true;
    6534             : 
    6535         141 :         torture_comment(tctx, "Testing OpenAlias(%u)\n", rid);
    6536             : 
    6537         141 :         r.in.domain_handle = handle;
    6538         141 :         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    6539         141 :         r.in.rid = rid;
    6540         141 :         r.out.alias_handle = &alias_handle;
    6541             : 
    6542         141 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenAlias_r(b, tctx, &r),
    6543             :                 "OpenAlias failed");
    6544         141 :         if (!NT_STATUS_IS_OK(r.out.result)) {
    6545           0 :                 torture_result(tctx, TORTURE_FAIL, "OpenAlias(%u) failed - %s\n", rid, nt_errstr(r.out.result));
    6546           0 :                 return false;
    6547             :         }
    6548             : 
    6549         141 :         if (!torture_setting_bool(tctx, "samba3", false)) {
    6550          79 :                 if (!test_QuerySecurity(b, tctx, &alias_handle)) {
    6551           0 :                         ret = false;
    6552             :                 }
    6553             :         }
    6554             : 
    6555         141 :         if (!test_QueryAliasInfo(b, tctx, &alias_handle)) {
    6556           0 :                 ret = false;
    6557             :         }
    6558             : 
    6559         141 :         if (!test_GetMembersInAlias(b, tctx, &alias_handle)) {
    6560           0 :                 ret = false;
    6561             :         }
    6562             : 
    6563         141 :         if (!test_samr_handle_Close(b, tctx, &alias_handle)) {
    6564           0 :                 ret = false;
    6565             :         }
    6566             : 
    6567         141 :         return ret;
    6568             : }
    6569             : 
    6570          78 : static bool check_mask(struct dcerpc_binding_handle *b,
    6571             :                        struct torture_context *tctx,
    6572             :                        struct policy_handle *handle, uint32_t rid,
    6573             :                        uint32_t acct_flag_mask)
    6574             : {
    6575             :         struct samr_OpenUser r;
    6576             :         struct samr_QueryUserInfo q;
    6577             :         union samr_UserInfo *info;
    6578             :         struct policy_handle user_handle;
    6579          78 :         bool ret = true;
    6580             : 
    6581          78 :         torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
    6582             : 
    6583          78 :         r.in.domain_handle = handle;
    6584          78 :         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    6585          78 :         r.in.rid = rid;
    6586          78 :         r.out.user_handle = &user_handle;
    6587             : 
    6588          78 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
    6589             :                 "OpenUser failed");
    6590          78 :         if (!NT_STATUS_IS_OK(r.out.result)) {
    6591           0 :                 torture_result(tctx, TORTURE_FAIL, "OpenUser(%u) failed - %s\n", rid, nt_errstr(r.out.result));
    6592           0 :                 return false;
    6593             :         }
    6594             : 
    6595          78 :         q.in.user_handle = &user_handle;
    6596          78 :         q.in.level = 16;
    6597          78 :         q.out.info = &info;
    6598             : 
    6599          78 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
    6600             :                 "QueryUserInfo failed");
    6601          78 :         if (!NT_STATUS_IS_OK(q.out.result)) {
    6602           0 :                 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 16 failed - %s\n",
    6603             :                        nt_errstr(q.out.result));
    6604           0 :                 ret = false;
    6605             :         } else {
    6606          78 :                 if ((acct_flag_mask & info->info16.acct_flags) == 0) {
    6607           0 :                         torture_result(tctx, TORTURE_FAIL, "Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
    6608           0 :                                acct_flag_mask, info->info16.acct_flags, rid);
    6609           0 :                         ret = false;
    6610             :                 }
    6611             :         }
    6612             : 
    6613          78 :         if (!test_samr_handle_Close(b, tctx, &user_handle)) {
    6614           0 :                 ret = false;
    6615             :         }
    6616             : 
    6617          78 :         return ret;
    6618             : }
    6619             : 
    6620          14 : static bool test_EnumDomainUsers_all(struct dcerpc_binding_handle *b,
    6621             :                                      struct torture_context *tctx,
    6622             :                                      struct policy_handle *handle)
    6623             : {
    6624             :         struct samr_EnumDomainUsers r;
    6625          14 :         uint32_t mask, resume_handle=0;
    6626             :         int i, mask_idx;
    6627          14 :         bool ret = true;
    6628             :         struct samr_LookupNames n;
    6629             :         struct samr_LookupRids  lr ;
    6630             :         struct lsa_Strings names;
    6631             :         struct samr_Ids rids, types;
    6632          14 :         struct samr_SamArray *sam = NULL;
    6633          14 :         uint32_t num_entries = 0;
    6634             : 
    6635          14 :         uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
    6636             :                             ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
    6637             :                             ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
    6638             :                             ACB_PWNOEXP, 0};
    6639             : 
    6640          14 :         torture_comment(tctx, "Testing EnumDomainUsers\n");
    6641             : 
    6642          51 :         for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
    6643          47 :                 r.in.domain_handle = handle;
    6644          47 :                 r.in.resume_handle = &resume_handle;
    6645          47 :                 r.in.acct_flags = mask = masks[mask_idx];
    6646          47 :                 r.in.max_size = (uint32_t)-1;
    6647          47 :                 r.out.resume_handle = &resume_handle;
    6648          47 :                 r.out.num_entries = &num_entries;
    6649          47 :                 r.out.sam = &sam;
    6650             : 
    6651          47 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainUsers_r(b, tctx, &r),
    6652             :                         "EnumDomainUsers failed");
    6653          88 :                 if (!NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) &&
    6654          47 :                     !NT_STATUS_IS_OK(r.out.result)) {
    6655           0 :                         torture_result(tctx, TORTURE_FAIL, "EnumDomainUsers failed - %s\n", nt_errstr(r.out.result));
    6656           0 :                         return false;
    6657             :                 }
    6658             : 
    6659          47 :                 torture_assert(tctx, sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
    6660             : 
    6661          37 :                 if (sam->count == 0) {
    6662          28 :                         continue;
    6663             :                 }
    6664             : 
    6665          89 :                 for (i=0;i<sam->count;i++) {
    6666          80 :                         if (mask) {
    6667          78 :                                 if (!check_mask(b, tctx, handle, sam->entries[i].idx, mask)) {
    6668           0 :                                         ret = false;
    6669             :                                 }
    6670           2 :                         } else if (!test_OpenUser(b, tctx, handle, sam->entries[i].idx)) {
    6671           0 :                                 ret = false;
    6672             :                         }
    6673             :                 }
    6674             :         }
    6675             : 
    6676           4 :         torture_comment(tctx, "Testing LookupNames\n");
    6677           4 :         n.in.domain_handle = handle;
    6678           4 :         n.in.num_names = sam->count;
    6679           4 :         n.in.names = talloc_array(tctx, struct lsa_String, sam->count);
    6680           4 :         n.out.rids = &rids;
    6681           4 :         n.out.types = &types;
    6682           6 :         for (i=0;i<sam->count;i++) {
    6683           2 :                 n.in.names[i].string = sam->entries[i].name.string;
    6684             :         }
    6685           4 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupNames_r(b, tctx, &n),
    6686             :                 "LookupNames failed");
    6687           4 :         if (!NT_STATUS_IS_OK(n.out.result)) {
    6688           0 :                 torture_result(tctx, TORTURE_FAIL, "LookupNames failed - %s\n", nt_errstr(n.out.result));
    6689           0 :                 ret = false;
    6690             :         }
    6691             : 
    6692             : 
    6693           4 :         torture_comment(tctx, "Testing LookupRids\n");
    6694           4 :         lr.in.domain_handle = handle;
    6695           4 :         lr.in.num_rids = sam->count;
    6696           4 :         lr.in.rids = talloc_array(tctx, uint32_t, sam->count);
    6697           4 :         lr.out.names = &names;
    6698           4 :         lr.out.types = &types;
    6699           6 :         for (i=0;i<sam->count;i++) {
    6700           2 :                 lr.in.rids[i] = sam->entries[i].idx;
    6701             :         }
    6702           4 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupRids_r(b, tctx, &lr),
    6703             :                 "LookupRids failed");
    6704           4 :         torture_assert_ntstatus_ok(tctx, lr.out.result, "LookupRids");
    6705             : 
    6706           4 :         return ret;
    6707             : }
    6708             : 
    6709             : /*
    6710             :   try blasting the server with a bunch of sync requests
    6711             : */
    6712          14 : static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx,
    6713             :                                        struct policy_handle *handle)
    6714             : {
    6715             :         struct samr_EnumDomainUsers r;
    6716          14 :         uint32_t resume_handle=0;
    6717             :         int i;
    6718             : #define ASYNC_COUNT 100
    6719             :         struct tevent_req *req[ASYNC_COUNT];
    6720             : 
    6721          14 :         if (!torture_setting_bool(tctx, "dangerous", false)) {
    6722          14 :                 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
    6723             :         }
    6724             : 
    6725           0 :         torture_comment(tctx, "Testing EnumDomainUsers_async\n");
    6726             : 
    6727           0 :         r.in.domain_handle = handle;
    6728           0 :         r.in.resume_handle = &resume_handle;
    6729           0 :         r.in.acct_flags = 0;
    6730           0 :         r.in.max_size = (uint32_t)-1;
    6731           0 :         r.out.resume_handle = &resume_handle;
    6732             : 
    6733           0 :         for (i=0;i<ASYNC_COUNT;i++) {
    6734           0 :                 req[i] = dcerpc_samr_EnumDomainUsers_r_send(tctx, tctx->ev, p->binding_handle, &r);
    6735             :         }
    6736             : 
    6737           0 :         for (i=0;i<ASYNC_COUNT;i++) {
    6738           0 :                 tevent_req_poll(req[i], tctx->ev);
    6739           0 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainUsers_r_recv(req[i], tctx),
    6740             :                         talloc_asprintf(tctx, "EnumDomainUsers[%d] failed - %s\n",
    6741             :                                i, nt_errstr(r.out.result)));
    6742             :         }
    6743             : 
    6744           0 :         torture_comment(tctx, "%d async requests OK\n", i);
    6745             : 
    6746           0 :         return true;
    6747             : }
    6748             : 
    6749          14 : static bool test_EnumDomainGroups_all(struct dcerpc_binding_handle *b,
    6750             :                                       struct torture_context *tctx,
    6751             :                                       struct policy_handle *handle)
    6752             : {
    6753             :         struct samr_EnumDomainGroups r;
    6754          14 :         uint32_t resume_handle=0;
    6755          14 :         struct samr_SamArray *sam = NULL;
    6756          14 :         uint32_t num_entries = 0;
    6757             :         int i;
    6758          14 :         bool ret = true;
    6759          14 :         bool universal_group_found = false;
    6760             : 
    6761          14 :         torture_comment(tctx, "Testing EnumDomainGroups\n");
    6762             : 
    6763          14 :         r.in.domain_handle = handle;
    6764          14 :         r.in.resume_handle = &resume_handle;
    6765          14 :         r.in.max_size = (uint32_t)-1;
    6766          14 :         r.out.resume_handle = &resume_handle;
    6767          14 :         r.out.num_entries = &num_entries;
    6768          14 :         r.out.sam = &sam;
    6769             : 
    6770          14 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainGroups_r(b, tctx, &r),
    6771             :                 "EnumDomainGroups failed");
    6772          14 :         if (!NT_STATUS_IS_OK(r.out.result)) {
    6773           0 :                 torture_result(tctx, TORTURE_FAIL, "EnumDomainGroups failed - %s\n", nt_errstr(r.out.result));
    6774           0 :                 return false;
    6775             :         }
    6776             : 
    6777          14 :         if (!sam) {
    6778           0 :                 return false;
    6779             :         }
    6780             : 
    6781          83 :         for (i=0;i<sam->count;i++) {
    6782          69 :                 if (!test_OpenGroup(b, tctx, handle, sam->entries[i].idx)) {
    6783           0 :                         ret = false;
    6784             :                 }
    6785          69 :                 if ((ret == true) && (strcasecmp(sam->entries[i].name.string,
    6786             :                                                  "Enterprise Admins") == 0)) {
    6787           5 :                         universal_group_found = true;
    6788             :                 }
    6789             :         }
    6790             : 
    6791             :         /* when we are running this on s4 we should get back at least the
    6792             :          * "Enterprise Admins" universal group. If we don't get a group entry
    6793             :          * at all we probably are performing the test on the builtin domain.
    6794             :          * So ignore this case. */
    6795          14 :         if (torture_setting_bool(tctx, "samba4", false)) {
    6796           6 :                 if ((sam->count > 0) && (!universal_group_found)) {
    6797           0 :                         ret = false;
    6798             :                 }
    6799             :         }
    6800             : 
    6801          14 :         return ret;
    6802             : }
    6803             : 
    6804          14 : static bool test_EnumDomainAliases_all(struct dcerpc_binding_handle *b,
    6805             :                                        struct torture_context *tctx,
    6806             :                                        struct policy_handle *handle)
    6807             : {
    6808             :         struct samr_EnumDomainAliases r;
    6809          14 :         uint32_t resume_handle=0;
    6810          14 :         struct samr_SamArray *sam = NULL;
    6811          14 :         uint32_t num_entries = 0;
    6812             :         int i;
    6813          14 :         bool ret = true;
    6814             : 
    6815          14 :         torture_comment(tctx, "Testing EnumDomainAliases\n");
    6816             : 
    6817          14 :         r.in.domain_handle = handle;
    6818          14 :         r.in.resume_handle = &resume_handle;
    6819          14 :         r.in.max_size = (uint32_t)-1;
    6820          14 :         r.out.sam = &sam;
    6821          14 :         r.out.num_entries = &num_entries;
    6822          14 :         r.out.resume_handle = &resume_handle;
    6823             : 
    6824          14 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainAliases_r(b, tctx, &r),
    6825             :                 "EnumDomainAliases failed");
    6826          14 :         if (!NT_STATUS_IS_OK(r.out.result)) {
    6827           0 :                 torture_result(tctx, TORTURE_FAIL, "EnumDomainAliases failed - %s\n", nt_errstr(r.out.result));
    6828           0 :                 return false;
    6829             :         }
    6830             : 
    6831          14 :         if (!sam) {
    6832           0 :                 return false;
    6833             :         }
    6834             : 
    6835         155 :         for (i=0;i<sam->count;i++) {
    6836         141 :                 if (!test_OpenAlias(b, tctx, handle, sam->entries[i].idx)) {
    6837           0 :                         ret = false;
    6838             :                 }
    6839             :         }
    6840             : 
    6841          14 :         return ret;
    6842             : }
    6843             : 
    6844           8 : static bool test_GetDisplayEnumerationIndex(struct dcerpc_binding_handle *b,
    6845             :                                             struct torture_context *tctx,
    6846             :                                             struct policy_handle *handle)
    6847             : {
    6848             :         struct samr_GetDisplayEnumerationIndex r;
    6849           8 :         bool ret = true;
    6850           8 :         uint16_t levels[] = {1, 2, 3, 4, 5};
    6851           8 :         uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
    6852             :         struct lsa_String name;
    6853           8 :         uint32_t idx = 0;
    6854             :         int i;
    6855             : 
    6856          28 :         for (i=0;i<ARRAY_SIZE(levels);i++) {
    6857          24 :                 torture_comment(tctx, "Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
    6858             : 
    6859          24 :                 init_lsa_String(&name, TEST_ACCOUNT_NAME);
    6860             : 
    6861          24 :                 r.in.domain_handle = handle;
    6862          24 :                 r.in.level = levels[i];
    6863          24 :                 r.in.name = &name;
    6864          24 :                 r.out.idx = &idx;
    6865             : 
    6866          24 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex_r(b, tctx, &r),
    6867             :                         "GetDisplayEnumerationIndex failed");
    6868             : 
    6869          32 :                 if (ok_lvl[i] &&
    6870          22 :                     !NT_STATUS_IS_OK(r.out.result) &&
    6871          10 :                     !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
    6872           0 :                         torture_result(tctx, TORTURE_FAIL, "GetDisplayEnumerationIndex level %u failed - %s\n",
    6873           0 :                                levels[i], nt_errstr(r.out.result));
    6874           0 :                         ret = false;
    6875             :                 }
    6876             : 
    6877          20 :                 init_lsa_String(&name, "zzzzzzzz");
    6878             : 
    6879          20 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex_r(b, tctx, &r),
    6880             :                         "GetDisplayEnumerationIndex failed");
    6881             : 
    6882          20 :                 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
    6883           0 :                         torture_result(tctx, TORTURE_FAIL, "GetDisplayEnumerationIndex level %u failed - %s\n",
    6884           0 :                                levels[i], nt_errstr(r.out.result));
    6885           0 :                         ret = false;
    6886             :                 }
    6887             :         }
    6888             : 
    6889           4 :         return ret;
    6890             : }
    6891             : 
    6892           8 : static bool test_GetDisplayEnumerationIndex2(struct dcerpc_binding_handle *b,
    6893             :                                              struct torture_context *tctx,
    6894             :                                              struct policy_handle *handle)
    6895             : {
    6896             :         struct samr_GetDisplayEnumerationIndex2 r;
    6897           8 :         bool ret = true;
    6898           8 :         uint16_t levels[] = {1, 2, 3, 4, 5};
    6899           8 :         uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
    6900             :         struct lsa_String name;
    6901           8 :         uint32_t idx = 0;
    6902             :         int i;
    6903             : 
    6904          28 :         for (i=0;i<ARRAY_SIZE(levels);i++) {
    6905          24 :                 torture_comment(tctx, "Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
    6906             : 
    6907          24 :                 init_lsa_String(&name, TEST_ACCOUNT_NAME);
    6908             : 
    6909          24 :                 r.in.domain_handle = handle;
    6910          24 :                 r.in.level = levels[i];
    6911          24 :                 r.in.name = &name;
    6912          24 :                 r.out.idx = &idx;
    6913             : 
    6914          24 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex2_r(b, tctx, &r),
    6915             :                         "GetDisplayEnumerationIndex2 failed");
    6916          32 :                 if (ok_lvl[i] &&
    6917          22 :                     !NT_STATUS_IS_OK(r.out.result) &&
    6918          10 :                     !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
    6919           0 :                         torture_result(tctx, TORTURE_FAIL, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
    6920           0 :                                levels[i], nt_errstr(r.out.result));
    6921           0 :                         ret = false;
    6922             :                 }
    6923             : 
    6924          20 :                 init_lsa_String(&name, "zzzzzzzz");
    6925             : 
    6926          20 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex2_r(b, tctx, &r),
    6927             :                         "GetDisplayEnumerationIndex2 failed");
    6928          20 :                 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
    6929           0 :                         torture_result(tctx, TORTURE_FAIL, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
    6930           0 :                                levels[i], nt_errstr(r.out.result));
    6931           0 :                         ret = false;
    6932             :                 }
    6933             :         }
    6934             : 
    6935           4 :         return ret;
    6936             : }
    6937             : 
    6938             : #define STRING_EQUAL_QUERY(s1, s2, user)                                        \
    6939             :         if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
    6940             :                 /* odd, but valid */                                            \
    6941             :         } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
    6942             :                         torture_result(tctx, TORTURE_FAIL, "%s mismatch for %s: %s != %s (%s)\n", \
    6943             :                                #s1, user.string,  s1.string, s2.string, __location__);   \
    6944             :                         ret = false; \
    6945             :         }
    6946             : #define INT_EQUAL_QUERY(s1, s2, user)           \
    6947             :                 if (s1 != s2) { \
    6948             :                         torture_result(tctx, TORTURE_FAIL, "%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
    6949             :                                #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
    6950             :                         ret = false; \
    6951             :                 }
    6952             : 
    6953          86 : static bool test_each_DisplayInfo_user(struct dcerpc_binding_handle *b,
    6954             :                                        struct torture_context *tctx,
    6955             :                                        struct samr_QueryDisplayInfo *querydisplayinfo,
    6956             :                                        bool *seen_testuser)
    6957             : {
    6958             :         struct samr_OpenUser r;
    6959             :         struct samr_QueryUserInfo q;
    6960             :         union samr_UserInfo *info;
    6961             :         struct policy_handle user_handle;
    6962          86 :         int i, ret = true;
    6963          86 :         r.in.domain_handle = querydisplayinfo->in.domain_handle;
    6964          86 :         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    6965         171 :         for (i = 0; ; i++) {
    6966         230 :                 switch (querydisplayinfo->in.level) {
    6967         150 :                 case 1:
    6968         150 :                         if (i >= querydisplayinfo->out.info->info1.count) {
    6969          42 :                                 return ret;
    6970             :                         }
    6971         108 :                         r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid;
    6972         108 :                         break;
    6973          21 :                 case 2:
    6974          21 :                         if (i >= querydisplayinfo->out.info->info2.count) {
    6975           9 :                                 return ret;
    6976             :                         }
    6977          12 :                         r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid;
    6978          12 :                         break;
    6979           0 :                 case 3:
    6980             :                         /* Groups */
    6981             :                 case 4:
    6982             :                 case 5:
    6983             :                         /* Not interested in validating just the account name */
    6984           0 :                         return true;
    6985             :                 }
    6986             : 
    6987         120 :                 r.out.user_handle = &user_handle;
    6988             : 
    6989         120 :                 switch (querydisplayinfo->in.level) {
    6990         120 :                 case 1:
    6991             :                 case 2:
    6992         120 :                         torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
    6993             :                                 "OpenUser failed");
    6994         120 :                         if (!NT_STATUS_IS_OK(r.out.result)) {
    6995          35 :                                 torture_result(tctx, TORTURE_FAIL, "OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(r.out.result));
    6996          35 :                                 return false;
    6997             :                         }
    6998             :                 }
    6999             : 
    7000          85 :                 q.in.user_handle = &user_handle;
    7001          85 :                 q.in.level = 21;
    7002          85 :                 q.out.info = &info;
    7003          85 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
    7004             :                         "QueryUserInfo failed");
    7005          85 :                 if (!NT_STATUS_IS_OK(r.out.result)) {
    7006           0 :                         torture_result(tctx, TORTURE_FAIL, "QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(r.out.result));
    7007           0 :                         return false;
    7008             :                 }
    7009             : 
    7010          85 :                 switch (querydisplayinfo->in.level) {
    7011          78 :                 case 1:
    7012          78 :                         if (seen_testuser && strcmp(info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
    7013           7 :                                 *seen_testuser = true;
    7014             :                         }
    7015          78 :                         STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name,
    7016             :                                            info->info21.full_name, info->info21.account_name);
    7017          78 :                         STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name,
    7018             :                                            info->info21.account_name, info->info21.account_name);
    7019          78 :                         STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description,
    7020             :                                            info->info21.description, info->info21.account_name);
    7021          78 :                         INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid,
    7022             :                                         info->info21.rid, info->info21.account_name);
    7023          78 :                         INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags,
    7024             :                                         info->info21.acct_flags, info->info21.account_name);
    7025             : 
    7026          78 :                         break;
    7027           7 :                 case 2:
    7028           7 :                         STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name,
    7029             :                                            info->info21.account_name, info->info21.account_name);
    7030           7 :                         STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description,
    7031             :                                            info->info21.description, info->info21.account_name);
    7032           7 :                         INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid,
    7033             :                                         info->info21.rid, info->info21.account_name);
    7034           7 :                         INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL),
    7035             :                                         info->info21.acct_flags, info->info21.account_name);
    7036             : 
    7037           7 :                         if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) {
    7038           2 :                                 torture_result(tctx, TORTURE_FAIL, "Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
    7039           2 :                                        info->info21.account_name.string);
    7040             :                         }
    7041             : 
    7042           7 :                         if (!(info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
    7043           0 :                                 torture_result(tctx, TORTURE_FAIL, "Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
    7044           0 :                                        info->info21.account_name.string,
    7045           0 :                                        querydisplayinfo->out.info->info2.entries[i].acct_flags,
    7046           0 :                                        info->info21.acct_flags);
    7047           0 :                                 return false;
    7048             :                         }
    7049             : 
    7050           7 :                         break;
    7051             :                 }
    7052             : 
    7053          85 :                 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
    7054           0 :                         return false;
    7055             :                 }
    7056             :         }
    7057             :         return ret;
    7058             : }
    7059             : 
    7060          14 : static bool test_QueryDisplayInfo(struct dcerpc_binding_handle *b,
    7061             :                                   struct torture_context *tctx,
    7062             :                                   struct policy_handle *handle)
    7063             : {
    7064             :         struct samr_QueryDisplayInfo r;
    7065             :         struct samr_QueryDomainInfo dom_info;
    7066          14 :         union samr_DomainInfo *info = NULL;
    7067          14 :         bool ret = true;
    7068          14 :         uint16_t levels[] = {1, 2, 3, 4, 5};
    7069             :         int i;
    7070          14 :         bool seen_testuser = false;
    7071             :         uint32_t total_size;
    7072             :         uint32_t returned_size;
    7073             :         union samr_DispInfo disp_info;
    7074             : 
    7075             : 
    7076          84 :         for (i=0;i<ARRAY_SIZE(levels);i++) {
    7077          70 :                 torture_comment(tctx, "Testing QueryDisplayInfo level %u\n", levels[i]);
    7078             : 
    7079          70 :                 r.in.start_idx = 0;
    7080          70 :                 r.out.result = STATUS_MORE_ENTRIES;
    7081         410 :                 while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES)) {
    7082         290 :                         r.in.domain_handle = handle;
    7083         290 :                         r.in.level = levels[i];
    7084         290 :                         r.in.max_entries = 2;
    7085         290 :                         r.in.buf_size = (uint32_t)-1;
    7086         290 :                         r.out.total_size = &total_size;
    7087         290 :                         r.out.returned_size = &returned_size;
    7088         290 :                         r.out.info = &disp_info;
    7089             : 
    7090         290 :                         torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &r),
    7091             :                                 "QueryDisplayInfo failed");
    7092         290 :                         if (!NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(r.out.result)) {
    7093           0 :                                 torture_result(tctx, TORTURE_FAIL, "QueryDisplayInfo level %u failed - %s\n",
    7094           0 :                                        levels[i], nt_errstr(r.out.result));
    7095           0 :                                 ret = false;
    7096             :                         }
    7097         290 :                         switch (r.in.level) {
    7098          72 :                         case 1:
    7099          72 :                                 if (!test_each_DisplayInfo_user(b, tctx, &r, &seen_testuser)) {
    7100          60 :                                         ret = false;
    7101             :                                 }
    7102          72 :                                 r.in.start_idx += r.out.info->info1.count;
    7103          72 :                                 break;
    7104          14 :                         case 2:
    7105          14 :                                 if (!test_each_DisplayInfo_user(b, tctx, &r, NULL)) {
    7106          10 :                                         ret = false;
    7107             :                                 }
    7108          14 :                                 r.in.start_idx += r.out.info->info2.count;
    7109          14 :                                 break;
    7110          66 :                         case 3:
    7111          66 :                                 r.in.start_idx += r.out.info->info3.count;
    7112          66 :                                 break;
    7113          72 :                         case 4:
    7114          72 :                                 r.in.start_idx += r.out.info->info4.count;
    7115          72 :                                 break;
    7116          66 :                         case 5:
    7117          66 :                                 r.in.start_idx += r.out.info->info5.count;
    7118          66 :                                 break;
    7119             :                         }
    7120             :                 }
    7121          70 :                 dom_info.in.domain_handle = handle;
    7122          70 :                 dom_info.in.level = 2;
    7123          70 :                 dom_info.out.info = &info;
    7124             : 
    7125             :                 /* Check number of users returned is correct */
    7126          70 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &dom_info),
    7127             :                         "QueryDomainInfo failed");
    7128          70 :                 if (!NT_STATUS_IS_OK(dom_info.out.result)) {
    7129           0 :                         torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u failed - %s\n",
    7130           0 :                                r.in.level, nt_errstr(dom_info.out.result));
    7131           0 :                         ret = false;
    7132           0 :                         break;
    7133             :                 }
    7134          70 :                 switch (r.in.level) {
    7135          28 :                 case 1:
    7136             :                 case 4:
    7137          28 :                         if (info->general.num_users < r.in.start_idx) {
    7138             :                                 /* On AD deployments this numbers don't match
    7139             :                                  * since QueryDisplayInfo returns universal and
    7140             :                                  * global groups, QueryDomainInfo only global
    7141             :                                  * ones. */
    7142          10 :                                 if (torture_setting_bool(tctx, "samba3", false)) {
    7143           6 :                                         torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
    7144           4 :                                                r.in.start_idx, info->general.num_groups,
    7145           4 :                                                info->general.domain_name.string);
    7146           4 :                                         ret = false;
    7147             :                                 }
    7148             :                         }
    7149          28 :                         if (!seen_testuser) {
    7150             :                                 struct policy_handle user_handle;
    7151          14 :                                 if (NT_STATUS_IS_OK(test_OpenUser_byname(b, tctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
    7152           0 :                                         torture_result(tctx, TORTURE_FAIL, "Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
    7153           0 :                                                info->general.domain_name.string);
    7154           0 :                                         ret = false;
    7155           0 :                                         test_samr_handle_Close(b, tctx, &user_handle);
    7156             :                                 }
    7157             :                         }
    7158          28 :                         break;
    7159          28 :                 case 3:
    7160             :                 case 5:
    7161          28 :                         if (info->general.num_groups != r.in.start_idx) {
    7162             :                                 /* On AD deployments this numbers don't match
    7163             :                                  * since QueryDisplayInfo returns universal and
    7164             :                                  * global groups, QueryDomainInfo only global
    7165             :                                  * ones. */
    7166          10 :                                 if (torture_setting_bool(tctx, "samba3", false)) {
    7167           6 :                                         torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
    7168           4 :                                                r.in.start_idx, info->general.num_groups,
    7169           4 :                                                info->general.domain_name.string);
    7170           4 :                                         ret = false;
    7171             :                                 }
    7172             :                         }
    7173             : 
    7174          28 :                         break;
    7175             :                 }
    7176             : 
    7177             :         }
    7178             : 
    7179          14 :         return ret;
    7180             : }
    7181             : 
    7182          14 : static bool test_QueryDisplayInfo2(struct dcerpc_binding_handle *b,
    7183             :                                    struct torture_context *tctx,
    7184             :                                    struct policy_handle *handle)
    7185             : {
    7186             :         struct samr_QueryDisplayInfo2 r;
    7187          14 :         bool ret = true;
    7188          14 :         uint16_t levels[] = {1, 2, 3, 4, 5};
    7189             :         int i;
    7190             :         uint32_t total_size;
    7191             :         uint32_t returned_size;
    7192             :         union samr_DispInfo info;
    7193             : 
    7194          84 :         for (i=0;i<ARRAY_SIZE(levels);i++) {
    7195          70 :                 torture_comment(tctx, "Testing QueryDisplayInfo2 level %u\n", levels[i]);
    7196             : 
    7197          70 :                 r.in.domain_handle = handle;
    7198          70 :                 r.in.level = levels[i];
    7199          70 :                 r.in.start_idx = 0;
    7200          70 :                 r.in.max_entries = 1000;
    7201          70 :                 r.in.buf_size = (uint32_t)-1;
    7202          70 :                 r.out.total_size = &total_size;
    7203          70 :                 r.out.returned_size = &returned_size;
    7204          70 :                 r.out.info = &info;
    7205             : 
    7206          70 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo2_r(b, tctx, &r),
    7207             :                         "QueryDisplayInfo2 failed");
    7208          70 :                 if (!NT_STATUS_IS_OK(r.out.result)) {
    7209           0 :                         torture_result(tctx, TORTURE_FAIL, "QueryDisplayInfo2 level %u failed - %s\n",
    7210           0 :                                levels[i], nt_errstr(r.out.result));
    7211           0 :                         ret = false;
    7212             :                 }
    7213             :         }
    7214             : 
    7215          14 :         return ret;
    7216             : }
    7217             : 
    7218          14 : static bool test_QueryDisplayInfo3(struct dcerpc_binding_handle *b,
    7219             :                                    struct torture_context *tctx,
    7220             :                                    struct policy_handle *handle)
    7221             : {
    7222             :         struct samr_QueryDisplayInfo3 r;
    7223          14 :         bool ret = true;
    7224          14 :         uint16_t levels[] = {1, 2, 3, 4, 5};
    7225             :         int i;
    7226             :         uint32_t total_size;
    7227             :         uint32_t returned_size;
    7228             :         union samr_DispInfo info;
    7229             : 
    7230          84 :         for (i=0;i<ARRAY_SIZE(levels);i++) {
    7231          70 :                 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
    7232             : 
    7233          70 :                 r.in.domain_handle = handle;
    7234          70 :                 r.in.level = levels[i];
    7235          70 :                 r.in.start_idx = 0;
    7236          70 :                 r.in.max_entries = 1000;
    7237          70 :                 r.in.buf_size = (uint32_t)-1;
    7238          70 :                 r.out.total_size = &total_size;
    7239          70 :                 r.out.returned_size = &returned_size;
    7240          70 :                 r.out.info = &info;
    7241             : 
    7242          70 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo3_r(b, tctx, &r),
    7243             :                         "QueryDisplayInfo3 failed");
    7244          70 :                 if (!NT_STATUS_IS_OK(r.out.result)) {
    7245           0 :                         torture_result(tctx, TORTURE_FAIL, "QueryDisplayInfo3 level %u failed - %s\n",
    7246           0 :                                levels[i], nt_errstr(r.out.result));
    7247           0 :                         ret = false;
    7248             :                 }
    7249             :         }
    7250             : 
    7251          14 :         return ret;
    7252             : }
    7253             : 
    7254             : 
    7255          14 : static bool test_QueryDisplayInfo_continue(struct dcerpc_binding_handle *b,
    7256             :                                            struct torture_context *tctx,
    7257             :                                            struct policy_handle *handle)
    7258             : {
    7259             :         struct samr_QueryDisplayInfo r;
    7260          14 :         bool ret = true;
    7261             :         uint32_t total_size;
    7262             :         uint32_t returned_size;
    7263             :         union samr_DispInfo info;
    7264             : 
    7265          14 :         torture_comment(tctx, "Testing QueryDisplayInfo continuation\n");
    7266             : 
    7267          14 :         r.in.domain_handle = handle;
    7268          14 :         r.in.level = 1;
    7269          14 :         r.in.start_idx = 0;
    7270          14 :         r.in.max_entries = 1;
    7271          14 :         r.in.buf_size = (uint32_t)-1;
    7272          14 :         r.out.total_size = &total_size;
    7273          14 :         r.out.returned_size = &returned_size;
    7274          14 :         r.out.info = &info;
    7275             : 
    7276             :         do {
    7277         147 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &r),
    7278             :                         "QueryDisplayInfo failed");
    7279         147 :                 if (NT_STATUS_IS_OK(r.out.result) && *r.out.returned_size != 0) {
    7280          10 :                         if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) {
    7281           0 :                                 torture_result(tctx, TORTURE_FAIL, "expected idx %d but got %d\n",
    7282           0 :                                        r.in.start_idx + 1,
    7283           0 :                                        r.out.info->info1.entries[0].idx);
    7284           0 :                                 break;
    7285             :                         }
    7286             :                 }
    7287         163 :                 if (!NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) &&
    7288          24 :                     !NT_STATUS_IS_OK(r.out.result)) {
    7289           0 :                         torture_result(tctx, TORTURE_FAIL, "QueryDisplayInfo level %u failed - %s\n",
    7290           0 :                                r.in.level, nt_errstr(r.out.result));
    7291           0 :                         ret = false;
    7292           0 :                         break;
    7293             :                 }
    7294         147 :                 r.in.start_idx++;
    7295         171 :         } while ((NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) ||
    7296         163 :                   NT_STATUS_IS_OK(r.out.result)) &&
    7297         244 :                  *r.out.returned_size != 0);
    7298             : 
    7299          14 :         return ret;
    7300             : }
    7301             : 
    7302          14 : static bool test_QueryDomainInfo(struct dcerpc_pipe *p,
    7303             :                                  struct torture_context *tctx,
    7304             :                                  struct policy_handle *handle)
    7305             : {
    7306             :         struct samr_QueryDomainInfo r;
    7307          14 :         union samr_DomainInfo *info = NULL;
    7308             :         struct samr_SetDomainInfo s;
    7309          14 :         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
    7310          14 :         uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1,  0,  1,  0};
    7311             :         int i;
    7312          14 :         bool ret = true;
    7313          14 :         struct dcerpc_binding_handle *b = p->binding_handle;
    7314          14 :         const char *domain_comment = talloc_asprintf(tctx,
    7315             :                                   "Tortured by Samba4 RPC-SAMR: %s",
    7316             :                                   timestring(tctx, time(NULL)));
    7317             : 
    7318          14 :         s.in.domain_handle = handle;
    7319          14 :         s.in.level = 4;
    7320          14 :         s.in.info = talloc(tctx, union samr_DomainInfo);
    7321             : 
    7322          14 :         s.in.info->oem.oem_information.string = domain_comment;
    7323          14 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
    7324             :                 "SetDomainInfo failed");
    7325          14 :         if (!NT_STATUS_IS_OK(s.out.result)) {
    7326           0 :                 torture_result(tctx, TORTURE_FAIL, "SetDomainInfo level %u (set comment) failed - %s\n",
    7327           0 :                        s.in.level, nt_errstr(s.out.result));
    7328           0 :                 return false;
    7329             :         }
    7330             : 
    7331         182 :         for (i=0;i<ARRAY_SIZE(levels);i++) {
    7332         168 :                 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
    7333             : 
    7334         168 :                 r.in.domain_handle = handle;
    7335         168 :                 r.in.level = levels[i];
    7336         168 :                 r.out.info = &info;
    7337             : 
    7338         168 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &r),
    7339             :                         "QueryDomainInfo failed");
    7340         168 :                 if (!NT_STATUS_IS_OK(r.out.result)) {
    7341           0 :                         torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u failed - %s\n",
    7342           0 :                                r.in.level, nt_errstr(r.out.result));
    7343           0 :                         ret = false;
    7344           0 :                         continue;
    7345             :                 }
    7346             : 
    7347         168 :                 switch (levels[i]) {
    7348          14 :                 case 2:
    7349          14 :                         if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
    7350           8 :                                 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
    7351           8 :                                        levels[i], info->general.oem_information.string, domain_comment);
    7352           4 :                                 if (!torture_setting_bool(tctx, "samba3", false)) {
    7353           0 :                                         ret = false;
    7354             :                                 }
    7355             :                         }
    7356          14 :                         if (!info->general.primary.string) {
    7357           0 :                                 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u returned no PDC name\n",
    7358           0 :                                        levels[i]);
    7359           0 :                                 ret = false;
    7360          14 :                         } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
    7361          10 :                                 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
    7362          10 :                                         if (torture_setting_bool(tctx, "samba3", false)) {
    7363          20 :                                                 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
    7364          14 :                                                        levels[i], info->general.primary.string, dcerpc_server_name(p));
    7365             :                                         }
    7366             :                                 }
    7367             :                         }
    7368          14 :                         break;
    7369          14 :                 case 4:
    7370          14 :                         if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
    7371           8 :                                 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
    7372           8 :                                        levels[i], info->oem.oem_information.string, domain_comment);
    7373           4 :                                 if (!torture_setting_bool(tctx, "samba3", false)) {
    7374           0 :                                         ret = false;
    7375             :                                 }
    7376             :                         }
    7377          14 :                         break;
    7378          14 :                 case 6:
    7379          14 :                         if (!info->info6.primary.string) {
    7380           0 :                                 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u returned no PDC name\n",
    7381           0 :                                        levels[i]);
    7382           0 :                                 ret = false;
    7383             :                         }
    7384          14 :                         break;
    7385          14 :                 case 11:
    7386          14 :                         if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
    7387           8 :                                 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
    7388           8 :                                        levels[i], info->general2.general.oem_information.string, domain_comment);
    7389           4 :                                 if (!torture_setting_bool(tctx, "samba3", false)) {
    7390           0 :                                         ret = false;
    7391             :                                 }
    7392             :                         }
    7393          14 :                         break;
    7394             :                 }
    7395             : 
    7396         168 :                 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
    7397             : 
    7398         168 :                 s.in.domain_handle = handle;
    7399         168 :                 s.in.level = levels[i];
    7400         168 :                 s.in.info = info;
    7401             : 
    7402         168 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
    7403             :                         "SetDomainInfo failed");
    7404         168 :                 if (set_ok[i]) {
    7405          98 :                         if (!NT_STATUS_IS_OK(s.out.result)) {
    7406           0 :                                 torture_result(tctx, TORTURE_FAIL, "SetDomainInfo level %u failed - %s\n",
    7407           0 :                                        r.in.level, nt_errstr(s.out.result));
    7408           0 :                                 ret = false;
    7409           0 :                                 continue;
    7410             :                         }
    7411             :                 } else {
    7412          70 :                         if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, s.out.result)) {
    7413           0 :                                 torture_result(tctx, TORTURE_FAIL, "SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
    7414           0 :                                        r.in.level, nt_errstr(s.out.result));
    7415           0 :                                 ret = false;
    7416           0 :                                 continue;
    7417             :                         }
    7418             :                 }
    7419             : 
    7420         168 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &r),
    7421             :                         "QueryDomainInfo failed");
    7422         168 :                 if (!NT_STATUS_IS_OK(r.out.result)) {
    7423           0 :                         torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u failed - %s\n",
    7424           0 :                                r.in.level, nt_errstr(r.out.result));
    7425           0 :                         ret = false;
    7426           0 :                         continue;
    7427             :                 }
    7428             :         }
    7429             : 
    7430          14 :         return ret;
    7431             : }
    7432             : 
    7433             : 
    7434          14 : static bool test_QueryDomainInfo2(struct dcerpc_binding_handle *b,
    7435             :                                   struct torture_context *tctx,
    7436             :                                   struct policy_handle *handle)
    7437             : {
    7438             :         struct samr_QueryDomainInfo2 r;
    7439          14 :         union samr_DomainInfo *info = NULL;
    7440          14 :         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
    7441             :         int i;
    7442          14 :         bool ret = true;
    7443             : 
    7444         182 :         for (i=0;i<ARRAY_SIZE(levels);i++) {
    7445         168 :                 torture_comment(tctx, "Testing QueryDomainInfo2 level %u\n", levels[i]);
    7446             : 
    7447         168 :                 r.in.domain_handle = handle;
    7448         168 :                 r.in.level = levels[i];
    7449         168 :                 r.out.info = &info;
    7450             : 
    7451         168 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo2_r(b, tctx, &r),
    7452             :                         "QueryDomainInfo2 failed");
    7453         168 :                 if (!NT_STATUS_IS_OK(r.out.result)) {
    7454           0 :                         torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo2 level %u failed - %s\n",
    7455           0 :                                r.in.level, nt_errstr(r.out.result));
    7456           0 :                         ret = false;
    7457           0 :                         continue;
    7458             :                 }
    7459             :         }
    7460             : 
    7461          14 :         return ret;
    7462             : }
    7463             : 
    7464             : /* Test whether querydispinfo level 5 and enumdomgroups return the same
    7465             :    set of group names. */
    7466          14 : static bool test_GroupList(struct dcerpc_binding_handle *b,
    7467             :                            struct torture_context *tctx,
    7468             :                            struct dom_sid *domain_sid,
    7469             :                            struct policy_handle *handle)
    7470             : {
    7471             :         struct samr_EnumDomainGroups q1;
    7472             :         struct samr_QueryDisplayInfo q2;
    7473             :         NTSTATUS status;
    7474          14 :         uint32_t resume_handle=0;
    7475          14 :         struct samr_SamArray *sam = NULL;
    7476          14 :         uint32_t num_entries = 0;
    7477             :         int i;
    7478          14 :         bool ret = true;
    7479             :         uint32_t total_size;
    7480             :         uint32_t returned_size;
    7481             :         union samr_DispInfo info;
    7482             : 
    7483          14 :         size_t num_names = 0;
    7484          14 :         const char **names = NULL;
    7485             : 
    7486          14 :         bool builtin_domain = dom_sid_compare(domain_sid,
    7487             :                                               &global_sid_Builtin) == 0;
    7488             : 
    7489          14 :         torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
    7490             : 
    7491          14 :         q1.in.domain_handle = handle;
    7492          14 :         q1.in.resume_handle = &resume_handle;
    7493          14 :         q1.in.max_size = 5;
    7494          14 :         q1.out.resume_handle = &resume_handle;
    7495          14 :         q1.out.num_entries = &num_entries;
    7496          14 :         q1.out.sam = &sam;
    7497             : 
    7498          14 :         status = STATUS_MORE_ENTRIES;
    7499          96 :         while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
    7500          72 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainGroups_r(b, tctx, &q1),
    7501             :                         "EnumDomainGroups failed");
    7502          72 :                 status = q1.out.result;
    7503             : 
    7504         107 :                 if (!NT_STATUS_IS_OK(status) &&
    7505          58 :                     !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
    7506           0 :                         break;
    7507             : 
    7508         141 :                 for (i=0; i<*q1.out.num_entries; i++) {
    7509          69 :                         add_string_to_array(tctx,
    7510          69 :                                             sam->entries[i].name.string,
    7511             :                                             &names, &num_names);
    7512             :                 }
    7513             :         }
    7514             : 
    7515          14 :         torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
    7516             : 
    7517          14 :         torture_assert(tctx, sam, "EnumDomainGroups failed to return sam");
    7518             : 
    7519          14 :         if (builtin_domain) {
    7520           7 :                 torture_assert(tctx, num_names == 0,
    7521             :                                "EnumDomainGroups shouldn't return any group in the builtin domain!");
    7522             :         }
    7523             : 
    7524          14 :         q2.in.domain_handle = handle;
    7525          14 :         q2.in.level = 5;
    7526          14 :         q2.in.start_idx = 0;
    7527          14 :         q2.in.max_entries = 5;
    7528          14 :         q2.in.buf_size = (uint32_t)-1;
    7529          14 :         q2.out.total_size = &total_size;
    7530          14 :         q2.out.returned_size = &returned_size;
    7531          14 :         q2.out.info = &info;
    7532             : 
    7533          14 :         status = STATUS_MORE_ENTRIES;
    7534          58 :         while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
    7535          34 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &q2),
    7536             :                         "QueryDisplayInfo failed");
    7537          34 :                 status = q2.out.result;
    7538          46 :                 if (!NT_STATUS_IS_OK(status) &&
    7539          20 :                     !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
    7540           0 :                         break;
    7541             : 
    7542         161 :                 for (i=0; i<q2.out.info->info5.count; i++) {
    7543             :                         int j;
    7544         127 :                         const char *name = q2.out.info->info5.entries[i].account_name.string;
    7545         127 :                         bool found = false;
    7546         499 :                         for (j=0; j<num_names; j++) {
    7547         441 :                                 if (names[j] == NULL)
    7548         142 :                                         continue;
    7549         299 :                                 if (strequal(names[j], name)) {
    7550          69 :                                         names[j] = NULL;
    7551          69 :                                         found = true;
    7552          69 :                                         break;
    7553             :                                 }
    7554             :                         }
    7555             : 
    7556         127 :                         if ((!found) && (!builtin_domain)) {
    7557           0 :                                 torture_result(tctx, TORTURE_FAIL, "QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
    7558             :                                        name);
    7559           0 :                                 ret = false;
    7560             :                         }
    7561             :                 }
    7562          34 :                 q2.in.start_idx += q2.out.info->info5.count;
    7563             :         }
    7564             : 
    7565          14 :         if (!NT_STATUS_IS_OK(status)) {
    7566           0 :                 torture_result(tctx, TORTURE_FAIL, "QueryDisplayInfo level 5 failed - %s\n",
    7567             :                        nt_errstr(status));
    7568           0 :                 ret = false;
    7569             :         }
    7570             : 
    7571          14 :         if (builtin_domain) {
    7572           7 :                 torture_assert(tctx, q2.in.start_idx != 0,
    7573             :                                "QueryDisplayInfo should return all domain groups also on the builtin domain handle!");
    7574             :         }
    7575             : 
    7576          81 :         for (i=0; i<num_names; i++) {
    7577          69 :                 if (names[i] != NULL) {
    7578           0 :                         torture_result(tctx, TORTURE_FAIL, "EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
    7579           0 :                                names[i]);
    7580           0 :                         ret = false;
    7581             :                 }
    7582             :         }
    7583             : 
    7584          12 :         return ret;
    7585             : }
    7586             : 
    7587         457 : static bool test_DeleteDomainGroup(struct dcerpc_binding_handle *b,
    7588             :                                    struct torture_context *tctx,
    7589             :                                    struct policy_handle *group_handle)
    7590             : {
    7591             :         struct samr_DeleteDomainGroup d;
    7592             : 
    7593         457 :         torture_comment(tctx, "Testing DeleteDomainGroup\n");
    7594             : 
    7595         457 :         d.in.group_handle = group_handle;
    7596         457 :         d.out.group_handle = group_handle;
    7597             : 
    7598         457 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomainGroup_r(b, tctx, &d),
    7599             :                 "DeleteDomainGroup failed");
    7600         457 :         torture_assert_ntstatus_ok(tctx, d.out.result, "DeleteDomainGroup");
    7601             : 
    7602         457 :         return true;
    7603             : }
    7604             : 
    7605          14 : static bool test_TestPrivateFunctionsDomain(struct dcerpc_binding_handle *b,
    7606             :                                             struct torture_context *tctx,
    7607             :                                             struct policy_handle *domain_handle)
    7608             : {
    7609             :         struct samr_TestPrivateFunctionsDomain r;
    7610          14 :         bool ret = true;
    7611             : 
    7612          14 :         torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
    7613             : 
    7614          14 :         r.in.domain_handle = domain_handle;
    7615             : 
    7616          14 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_TestPrivateFunctionsDomain_r(b, tctx, &r),
    7617             :                 "TestPrivateFunctionsDomain failed");
    7618          10 :         torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsDomain");
    7619             : 
    7620          10 :         return ret;
    7621             : }
    7622             : 
    7623          14 : static bool test_RidToSid(struct dcerpc_binding_handle *b,
    7624             :                           struct torture_context *tctx,
    7625             :                           struct dom_sid *domain_sid,
    7626             :                           struct policy_handle *domain_handle)
    7627             : {
    7628             :         struct samr_RidToSid r;
    7629          14 :         bool ret = true;
    7630             :         struct dom_sid *calc_sid, *out_sid;
    7631          14 :         int rids[] = { 0, 42, 512, 10200 };
    7632             :         int i;
    7633             : 
    7634          70 :         for (i=0;i<ARRAY_SIZE(rids);i++) {
    7635          56 :                 torture_comment(tctx, "Testing RidToSid\n");
    7636             : 
    7637          56 :                 calc_sid = dom_sid_dup(tctx, domain_sid);
    7638          56 :                 r.in.domain_handle = domain_handle;
    7639          56 :                 r.in.rid = rids[i];
    7640          56 :                 r.out.sid = &out_sid;
    7641             : 
    7642          56 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RidToSid_r(b, tctx, &r),
    7643             :                         "RidToSid failed");
    7644          56 :                 if (!NT_STATUS_IS_OK(r.out.result)) {
    7645           0 :                         torture_result(tctx, TORTURE_FAIL, "RidToSid for %d failed - %s\n", rids[i], nt_errstr(r.out.result));
    7646           0 :                         ret = false;
    7647             :                 } else {
    7648          56 :                         calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
    7649             : 
    7650          56 :                         if (!dom_sid_equal(calc_sid, out_sid)) {
    7651           0 :                                 torture_result(tctx, TORTURE_FAIL, "RidToSid for %d failed - got %s, expected %s\n", rids[i],
    7652             :                                        dom_sid_string(tctx, out_sid),
    7653             :                                        dom_sid_string(tctx, calc_sid));
    7654           0 :                                 ret = false;
    7655             :                         }
    7656             :                 }
    7657             :         }
    7658             : 
    7659          14 :         return ret;
    7660             : }
    7661             : 
    7662          14 : static bool test_GetBootKeyInformation(struct dcerpc_binding_handle *b,
    7663             :                                        struct torture_context *tctx,
    7664             :                                        struct policy_handle *domain_handle)
    7665             : {
    7666             :         struct samr_GetBootKeyInformation r;
    7667          14 :         bool ret = true;
    7668          14 :         uint32_t unknown = 0;
    7669             :         NTSTATUS status;
    7670             : 
    7671          14 :         torture_comment(tctx, "Testing GetBootKeyInformation\n");
    7672             : 
    7673          14 :         r.in.domain_handle = domain_handle;
    7674          14 :         r.out.unknown = &unknown;
    7675             : 
    7676          14 :         status = dcerpc_samr_GetBootKeyInformation_r(b, tctx, &r);
    7677          14 :         if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(r.out.result)) {
    7678          10 :                 status = r.out.result;
    7679             :         }
    7680          14 :         if (!NT_STATUS_IS_OK(status)) {
    7681             :                 /* w2k3 seems to fail this sometimes and pass it sometimes */
    7682          14 :                 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
    7683             :         }
    7684             : 
    7685          14 :         return ret;
    7686             : }
    7687             : 
    7688           7 : static bool test_AddGroupMember(struct dcerpc_binding_handle *b,
    7689             :                                 struct torture_context *tctx,
    7690             :                                 struct policy_handle *domain_handle,
    7691             :                                 struct policy_handle *group_handle)
    7692             : {
    7693             :         NTSTATUS status;
    7694             :         struct samr_AddGroupMember r;
    7695             :         struct samr_DeleteGroupMember d;
    7696             :         struct samr_QueryGroupMember q;
    7697           7 :         struct samr_RidAttrArray *rids = NULL;
    7698             :         struct samr_SetMemberAttributesOfGroup s;
    7699             :         uint32_t rid;
    7700           7 :         bool found_member = false;
    7701             :         int i;
    7702             : 
    7703           7 :         status = test_LookupName(b, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
    7704           7 :         torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
    7705             : 
    7706           7 :         r.in.group_handle = group_handle;
    7707           7 :         r.in.rid = rid;
    7708           7 :         r.in.flags = 0; /* ??? */
    7709             : 
    7710           7 :         torture_comment(tctx, "Testing AddGroupMember, QueryGroupMember and DeleteGroupMember\n");
    7711             : 
    7712           7 :         d.in.group_handle = group_handle;
    7713           7 :         d.in.rid = rid;
    7714             : 
    7715           7 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteGroupMember_r(b, tctx, &d),
    7716             :                 "DeleteGroupMember failed");
    7717           7 :         torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, d.out.result, "DeleteGroupMember");
    7718             : 
    7719           2 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddGroupMember_r(b, tctx, &r),
    7720             :                 "AddGroupMember failed");
    7721           2 :         torture_assert_ntstatus_ok(tctx, r.out.result, "AddGroupMember");
    7722             : 
    7723           2 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddGroupMember_r(b, tctx, &r),
    7724             :                 "AddGroupMember failed");
    7725           2 :         torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, r.out.result, "AddGroupMember");
    7726             : 
    7727           4 :         if (torture_setting_bool(tctx, "samba4", false) ||
    7728           2 :             torture_setting_bool(tctx, "samba3", false)) {
    7729           2 :                 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba\n");
    7730             :         } else {
    7731             :                 /* this one is quite strange. I am using random inputs in the
    7732             :                    hope of triggering an error that might give us a clue */
    7733             : 
    7734           0 :                 s.in.group_handle = group_handle;
    7735           0 :                 s.in.unknown1 = random();
    7736           0 :                 s.in.unknown2 = random();
    7737             : 
    7738           0 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetMemberAttributesOfGroup_r(b, tctx, &s),
    7739             :                         "SetMemberAttributesOfGroup failed");
    7740           0 :                 torture_assert_ntstatus_ok(tctx, s.out.result, "SetMemberAttributesOfGroup");
    7741             :         }
    7742             : 
    7743           2 :         q.in.group_handle = group_handle;
    7744           2 :         q.out.rids = &rids;
    7745             : 
    7746           2 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupMember_r(b, tctx, &q),
    7747             :                 "QueryGroupMember failed");
    7748           2 :         torture_assert_ntstatus_ok(tctx, q.out.result, "QueryGroupMember");
    7749           2 :         torture_assert(tctx, rids, "QueryGroupMember did not fill in rids structure");
    7750             : 
    7751           4 :         for (i=0; i < rids->count; i++) {
    7752           2 :                 if (rids->rids[i] == rid) {
    7753           2 :                         found_member = true;
    7754             :                 }
    7755             :         }
    7756             : 
    7757           2 :         torture_assert(tctx, found_member, "QueryGroupMember did not list newly added member");
    7758             : 
    7759           2 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteGroupMember_r(b, tctx, &d),
    7760             :                 "DeleteGroupMember failed");
    7761           2 :         torture_assert_ntstatus_ok(tctx, d.out.result, "DeleteGroupMember");
    7762             : 
    7763           2 :         rids = NULL;
    7764           2 :         found_member = false;
    7765             : 
    7766           2 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupMember_r(b, tctx, &q),
    7767             :                 "QueryGroupMember failed");
    7768           2 :         torture_assert_ntstatus_ok(tctx, q.out.result, "QueryGroupMember");
    7769           2 :         torture_assert(tctx, rids, "QueryGroupMember did not fill in rids structure");
    7770             : 
    7771           2 :         for (i=0; i < rids->count; i++) {
    7772           0 :                 if (rids->rids[i] == rid) {
    7773           0 :                         found_member = true;
    7774             :                 }
    7775             :         }
    7776             : 
    7777           2 :         torture_assert(tctx, !found_member, "QueryGroupMember does still list removed member");
    7778             : 
    7779           2 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddGroupMember_r(b, tctx, &r),
    7780             :                 "AddGroupMember failed");
    7781           2 :         torture_assert_ntstatus_ok(tctx, r.out.result, "AddGroupMember");
    7782             : 
    7783           2 :         return true;
    7784             : }
    7785             : 
    7786             : 
    7787        2114 : static bool test_CreateDomainGroup(struct dcerpc_binding_handle *b,
    7788             :                                    struct torture_context *tctx,
    7789             :                                    struct policy_handle *domain_handle,
    7790             :                                    const char *group_name,
    7791             :                                    struct policy_handle *group_handle,
    7792             :                                    struct dom_sid *domain_sid,
    7793             :                                    bool test_group)
    7794             : {
    7795             :         struct samr_CreateDomainGroup r;
    7796             :         uint32_t rid;
    7797             :         struct lsa_String name;
    7798        2114 :         bool ret = true;
    7799             : 
    7800        2114 :         init_lsa_String(&name, group_name);
    7801             : 
    7802        2114 :         r.in.domain_handle = domain_handle;
    7803        2114 :         r.in.name = &name;
    7804        2114 :         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    7805        2114 :         r.out.group_handle = group_handle;
    7806        2114 :         r.out.rid = &rid;
    7807             : 
    7808        2114 :         torture_comment(tctx, "Testing CreateDomainGroup(%s)\n", r.in.name->string);
    7809             : 
    7810        2114 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomainGroup_r(b, tctx, &r),
    7811             :                 "CreateDomainGroup failed");
    7812             : 
    7813        2114 :         if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
    7814        1057 :                 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED)) {
    7815        1057 :                         torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
    7816        1057 :                         return true;
    7817             :                 } else {
    7818           0 :                         torture_result(tctx, TORTURE_FAIL, "Server should have refused create of '%s', got %s instead\n", r.in.name->string,
    7819             :                                nt_errstr(r.out.result));
    7820           0 :                         return false;
    7821             :                 }
    7822             :         }
    7823             : 
    7824        1057 :         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_GROUP_EXISTS)) {
    7825           0 :                 if (!test_DeleteGroup_byname(b, tctx, domain_handle, r.in.name->string)) {
    7826           0 :                         torture_result(tctx, TORTURE_FAIL, "CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
    7827             :                                nt_errstr(r.out.result));
    7828           0 :                         return false;
    7829             :                 }
    7830           0 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomainGroup_r(b, tctx, &r),
    7831             :                         "CreateDomainGroup failed");
    7832             :         }
    7833        1057 :         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_USER_EXISTS)) {
    7834           0 :                 if (!test_DeleteUser_byname(b, tctx, domain_handle, r.in.name->string)) {
    7835             : 
    7836           0 :                         torture_result(tctx, TORTURE_FAIL, "CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
    7837             :                                nt_errstr(r.out.result));
    7838           0 :                         return false;
    7839             :                 }
    7840           0 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomainGroup_r(b, tctx, &r),
    7841             :                         "CreateDomainGroup failed");
    7842             :         }
    7843        1057 :         torture_assert_ntstatus_ok(tctx, r.out.result, "CreateDomainGroup");
    7844             : 
    7845        1057 :         if (!test_group) {
    7846        1050 :                 return ret;
    7847             :         }
    7848             : 
    7849           7 :         if (!test_AddGroupMember(b, tctx, domain_handle, group_handle)) {
    7850           5 :                 torture_result(tctx, TORTURE_FAIL, "CreateDomainGroup failed - %s\n", nt_errstr(r.out.result));
    7851           5 :                 ret = false;
    7852             :         }
    7853             : 
    7854           7 :         if (!test_SetGroupInfo(b, tctx, group_handle)) {
    7855           0 :                 ret = false;
    7856             :         }
    7857             : 
    7858           7 :         return ret;
    7859             : }
    7860             : 
    7861             : 
    7862             : /*
    7863             :   its not totally clear what this does. It seems to accept any sid you like.
    7864             : */
    7865          14 : static bool test_RemoveMemberFromForeignDomain(struct dcerpc_binding_handle *b,
    7866             :                                                struct torture_context *tctx,
    7867             :                                                struct policy_handle *domain_handle)
    7868             : {
    7869             :         struct samr_RemoveMemberFromForeignDomain r;
    7870             : 
    7871          14 :         r.in.domain_handle = domain_handle;
    7872          14 :         r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
    7873             : 
    7874          14 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMemberFromForeignDomain_r(b, tctx, &r),
    7875             :                 "RemoveMemberFromForeignDomain failed");
    7876          14 :         torture_assert_ntstatus_ok(tctx, r.out.result, "RemoveMemberFromForeignDomain");
    7877             : 
    7878          14 :         return true;
    7879             : }
    7880             : 
    7881          14 : static bool test_EnumDomainUsers(struct dcerpc_binding_handle *b,
    7882             :                                  struct torture_context *tctx,
    7883             :                                  struct policy_handle *domain_handle,
    7884             :                                  uint32_t *total_num_entries_p)
    7885             : {
    7886             :         NTSTATUS status;
    7887             :         struct samr_EnumDomainUsers r;
    7888          14 :         uint32_t resume_handle = 0;
    7889          14 :         uint32_t num_entries = 0;
    7890          14 :         uint32_t total_num_entries = 0;
    7891             :         struct samr_SamArray *sam;
    7892             : 
    7893          14 :         r.in.domain_handle = domain_handle;
    7894          14 :         r.in.acct_flags = 0;
    7895          14 :         r.in.max_size = (uint32_t)-1;
    7896          14 :         r.in.resume_handle = &resume_handle;
    7897             : 
    7898          14 :         r.out.sam = &sam;
    7899          14 :         r.out.num_entries = &num_entries;
    7900          14 :         r.out.resume_handle = &resume_handle;
    7901             : 
    7902          14 :         torture_comment(tctx, "Testing EnumDomainUsers\n");
    7903             : 
    7904             :         do {
    7905          14 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainUsers_r(b, tctx, &r),
    7906             :                         "EnumDomainUsers failed");
    7907          14 :                 if (NT_STATUS_IS_ERR(r.out.result)) {
    7908           0 :                         torture_assert_ntstatus_ok(tctx, r.out.result,
    7909             :                                 "failed to enumerate users");
    7910             :                 }
    7911          14 :                 status = r.out.result;
    7912             : 
    7913          14 :                 total_num_entries += num_entries;
    7914          14 :         } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
    7915             : 
    7916          14 :         if (total_num_entries_p) {
    7917          14 :                 *total_num_entries_p = total_num_entries;
    7918             :         }
    7919             : 
    7920          14 :         return true;
    7921             : }
    7922             : 
    7923          14 : static bool test_EnumDomainGroups(struct dcerpc_binding_handle *b,
    7924             :                                   struct torture_context *tctx,
    7925             :                                   struct policy_handle *domain_handle,
    7926             :                                   uint32_t *total_num_entries_p)
    7927             : {
    7928             :         NTSTATUS status;
    7929             :         struct samr_EnumDomainGroups r;
    7930          14 :         uint32_t resume_handle = 0;
    7931          14 :         uint32_t num_entries = 0;
    7932          14 :         uint32_t total_num_entries = 0;
    7933             :         struct samr_SamArray *sam;
    7934             : 
    7935          14 :         r.in.domain_handle = domain_handle;
    7936          14 :         r.in.max_size = (uint32_t)-1;
    7937          14 :         r.in.resume_handle = &resume_handle;
    7938             : 
    7939          14 :         r.out.sam = &sam;
    7940          14 :         r.out.num_entries = &num_entries;
    7941          14 :         r.out.resume_handle = &resume_handle;
    7942             : 
    7943          14 :         torture_comment(tctx, "Testing EnumDomainGroups\n");
    7944             : 
    7945             :         do {
    7946          14 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainGroups_r(b, tctx, &r),
    7947             :                         "EnumDomainGroups failed");
    7948          14 :                 if (NT_STATUS_IS_ERR(r.out.result)) {
    7949           0 :                         torture_assert_ntstatus_ok(tctx, r.out.result,
    7950             :                                 "failed to enumerate groups");
    7951             :                 }
    7952          14 :                 status = r.out.result;
    7953             : 
    7954          14 :                 total_num_entries += num_entries;
    7955          14 :         } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
    7956             : 
    7957          14 :         if (total_num_entries_p) {
    7958          14 :                 *total_num_entries_p = total_num_entries;
    7959             :         }
    7960             : 
    7961          14 :         return true;
    7962             : }
    7963             : 
    7964          14 : static bool test_EnumDomainAliases(struct dcerpc_binding_handle *b,
    7965             :                                    struct torture_context *tctx,
    7966             :                                    struct policy_handle *domain_handle,
    7967             :                                    uint32_t *total_num_entries_p)
    7968             : {
    7969             :         NTSTATUS status;
    7970             :         struct samr_EnumDomainAliases r;
    7971          14 :         uint32_t resume_handle = 0;
    7972          14 :         uint32_t num_entries = 0;
    7973          14 :         uint32_t total_num_entries = 0;
    7974             :         struct samr_SamArray *sam;
    7975             : 
    7976          14 :         r.in.domain_handle = domain_handle;
    7977          14 :         r.in.max_size = (uint32_t)-1;
    7978          14 :         r.in.resume_handle = &resume_handle;
    7979             : 
    7980          14 :         r.out.sam = &sam;
    7981          14 :         r.out.num_entries = &num_entries;
    7982          14 :         r.out.resume_handle = &resume_handle;
    7983             : 
    7984          14 :         torture_comment(tctx, "Testing EnumDomainAliases\n");
    7985             : 
    7986             :         do {
    7987          14 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainAliases_r(b, tctx, &r),
    7988             :                         "EnumDomainAliases failed");
    7989          14 :                 if (NT_STATUS_IS_ERR(r.out.result)) {
    7990           0 :                         torture_assert_ntstatus_ok(tctx, r.out.result,
    7991             :                                 "failed to enumerate aliases");
    7992             :                 }
    7993          14 :                 status = r.out.result;
    7994             : 
    7995          14 :                 total_num_entries += num_entries;
    7996          14 :         } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
    7997             : 
    7998          14 :         if (total_num_entries_p) {
    7999          14 :                 *total_num_entries_p = total_num_entries;
    8000             :         }
    8001             : 
    8002          14 :         return true;
    8003             : }
    8004             : 
    8005          28 : static bool test_QueryDisplayInfo_level(struct dcerpc_binding_handle *b,
    8006             :                                         struct torture_context *tctx,
    8007             :                                         struct policy_handle *handle,
    8008             :                                         uint16_t level,
    8009             :                                         uint32_t *total_num_entries_p)
    8010             : {
    8011             :         NTSTATUS status;
    8012             :         struct samr_QueryDisplayInfo r;
    8013          28 :         uint32_t total_num_entries = 0;
    8014             : 
    8015          28 :         r.in.domain_handle = handle;
    8016          28 :         r.in.level = level;
    8017          28 :         r.in.start_idx = 0;
    8018          28 :         r.in.max_entries = (uint32_t)-1;
    8019          28 :         r.in.buf_size = (uint32_t)-1;
    8020             : 
    8021          28 :         torture_comment(tctx, "Testing QueryDisplayInfo\n");
    8022             : 
    8023             :         do {
    8024             :                 uint32_t total_size;
    8025             :                 uint32_t returned_size;
    8026             :                 union samr_DispInfo info;
    8027             : 
    8028          28 :                 r.out.total_size = &total_size;
    8029          28 :                 r.out.returned_size = &returned_size;
    8030          28 :                 r.out.info = &info;
    8031             : 
    8032          28 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &r),
    8033             :                         "failed to query displayinfo");
    8034          28 :                 if (NT_STATUS_IS_ERR(r.out.result)) {
    8035           0 :                         torture_assert_ntstatus_ok(tctx, r.out.result,
    8036             :                                 "failed to query displayinfo");
    8037             :                 }
    8038          28 :                 status = r.out.result;
    8039             : 
    8040          28 :                 if (*r.out.returned_size == 0) {
    8041           4 :                         break;
    8042             :                 }
    8043             : 
    8044          24 :                 switch (r.in.level) {
    8045          12 :                 case 1:
    8046          12 :                         total_num_entries += info.info1.count;
    8047          12 :                         r.in.start_idx += info.info1.entries[info.info1.count - 1].idx + 1;
    8048          12 :                         break;
    8049           0 :                 case 2:
    8050           0 :                         total_num_entries += info.info2.count;
    8051           0 :                         r.in.start_idx += info.info2.entries[info.info2.count - 1].idx + 1;
    8052           0 :                         break;
    8053          12 :                 case 3:
    8054          12 :                         total_num_entries += info.info3.count;
    8055          12 :                         r.in.start_idx += info.info3.entries[info.info3.count - 1].idx + 1;
    8056          12 :                         break;
    8057           0 :                 case 4:
    8058           0 :                         total_num_entries += info.info4.count;
    8059           0 :                         r.in.start_idx += info.info4.entries[info.info4.count - 1].idx + 1;
    8060           0 :                         break;
    8061           0 :                 case 5:
    8062           0 :                         total_num_entries += info.info5.count;
    8063           0 :                         r.in.start_idx += info.info5.entries[info.info5.count - 1].idx + 1;
    8064           0 :                         break;
    8065           0 :                 default:
    8066           0 :                         return false;
    8067             :                 }
    8068             : 
    8069          24 :         } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
    8070             : 
    8071          28 :         if (total_num_entries_p) {
    8072          28 :                 *total_num_entries_p = total_num_entries;
    8073             :         }
    8074             : 
    8075          28 :         return true;
    8076             : }
    8077             : 
    8078          42 : static bool test_ManyObjects(struct dcerpc_pipe *p,
    8079             :                              struct torture_context *tctx,
    8080             :                              struct policy_handle *domain_handle,
    8081             :                              struct dom_sid *domain_sid,
    8082             :                              struct torture_samr_context *ctx)
    8083             : {
    8084          42 :         uint32_t num_total = ctx->num_objects_large_dc;
    8085          42 :         uint32_t num_enum = 0;
    8086          42 :         uint32_t num_disp = 0;
    8087          42 :         uint32_t num_created = 0;
    8088          42 :         uint32_t num_anounced = 0;
    8089             :         uint32_t i;
    8090          42 :         struct dcerpc_binding_handle *b = p->binding_handle;
    8091             : 
    8092          42 :         struct policy_handle *handles = talloc_zero_array(tctx, struct policy_handle, num_total);
    8093             : 
    8094             :         /* query */
    8095             : 
    8096             :         {
    8097             :                 struct samr_QueryDomainInfo2 r;
    8098             :                 union samr_DomainInfo *info;
    8099          42 :                 r.in.domain_handle = domain_handle;
    8100          42 :                 r.in.level = 2;
    8101          42 :                 r.out.info = &info;
    8102             : 
    8103          42 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo2_r(b, tctx, &r),
    8104             :                         "QueryDomainInfo2 failed");
    8105          42 :                 torture_assert_ntstatus_ok(tctx, r.out.result,
    8106             :                         "failed to query domain info");
    8107             : 
    8108          42 :                 switch (ctx->choice) {
    8109          14 :                 case TORTURE_SAMR_MANY_ACCOUNTS:
    8110          14 :                         num_anounced = info->general.num_users;
    8111          14 :                         break;
    8112          14 :                 case TORTURE_SAMR_MANY_GROUPS:
    8113          14 :                         num_anounced = info->general.num_groups;
    8114          14 :                         break;
    8115          14 :                 case TORTURE_SAMR_MANY_ALIASES:
    8116          14 :                         num_anounced = info->general.num_aliases;
    8117          14 :                         break;
    8118           0 :                 default:
    8119           0 :                         return false;
    8120             :                 }
    8121             :         }
    8122             : 
    8123             :         /* create */
    8124             : 
    8125        6342 :         for (i=0; i < num_total; i++) {
    8126             : 
    8127        6300 :                 const char *name = NULL;
    8128             : 
    8129        6300 :                 switch (ctx->choice) {
    8130        2100 :                 case TORTURE_SAMR_MANY_ACCOUNTS:
    8131        2100 :                         name = talloc_asprintf(tctx, "%s%04d", TEST_ACCOUNT_NAME, i);
    8132        2100 :                         torture_assert(tctx,
    8133             :                                 test_CreateUser(p, tctx, domain_handle, name, &handles[i], domain_sid, 0, NULL, false),
    8134             :                                 "failed to create user");
    8135        2100 :                         break;
    8136        2100 :                 case TORTURE_SAMR_MANY_GROUPS:
    8137        2100 :                         name = talloc_asprintf(tctx, "%s%04d", TEST_GROUPNAME, i);
    8138        2100 :                         torture_assert(tctx,
    8139             :                                 test_CreateDomainGroup(b, tctx, domain_handle, name, &handles[i], domain_sid, false),
    8140             :                                 "failed to create group");
    8141        2100 :                         break;
    8142        2100 :                 case TORTURE_SAMR_MANY_ALIASES:
    8143        2100 :                         name = talloc_asprintf(tctx, "%s%04d", TEST_ALIASNAME, i);
    8144        2100 :                         torture_assert(tctx,
    8145             :                                 test_CreateAlias(b, tctx, domain_handle, name, &handles[i], domain_sid, false),
    8146             :                                 "failed to create alias");
    8147        2100 :                         break;
    8148           0 :                 default:
    8149           0 :                         return false;
    8150             :                 }
    8151        6300 :                 if (!ndr_policy_handle_empty(&handles[i])) {
    8152        3150 :                         num_created++;
    8153             :                 }
    8154             :         }
    8155             : 
    8156             :         /* enum */
    8157             : 
    8158          42 :         switch (ctx->choice) {
    8159          14 :         case TORTURE_SAMR_MANY_ACCOUNTS:
    8160          14 :                 torture_assert(tctx,
    8161             :                         test_EnumDomainUsers(b, tctx, domain_handle, &num_enum),
    8162             :                         "failed to enum users");
    8163          14 :                 break;
    8164          14 :         case TORTURE_SAMR_MANY_GROUPS:
    8165          14 :                 torture_assert(tctx,
    8166             :                         test_EnumDomainGroups(b, tctx, domain_handle, &num_enum),
    8167             :                         "failed to enum groups");
    8168          14 :                 break;
    8169          14 :         case TORTURE_SAMR_MANY_ALIASES:
    8170          14 :                 torture_assert(tctx,
    8171             :                         test_EnumDomainAliases(b, tctx, domain_handle, &num_enum),
    8172             :                         "failed to enum aliases");
    8173          14 :                 break;
    8174           0 :         default:
    8175           0 :                 return false;
    8176             :         }
    8177             : 
    8178             :         /* dispinfo */
    8179             : 
    8180          42 :         switch (ctx->choice) {
    8181          14 :         case TORTURE_SAMR_MANY_ACCOUNTS:
    8182          14 :                 torture_assert(tctx,
    8183             :                         test_QueryDisplayInfo_level(b, tctx, domain_handle, 1, &num_disp),
    8184             :                         "failed to query display info");
    8185          14 :                 break;
    8186          14 :         case TORTURE_SAMR_MANY_GROUPS:
    8187          14 :                 torture_assert(tctx,
    8188             :                         test_QueryDisplayInfo_level(b, tctx, domain_handle, 3, &num_disp),
    8189             :                         "failed to query display info");
    8190          14 :                 break;
    8191          14 :         case TORTURE_SAMR_MANY_ALIASES:
    8192             :                 /* no aliases in dispinfo */
    8193          14 :                 break;
    8194           0 :         default:
    8195           0 :                 return false;
    8196             :         }
    8197             : 
    8198             :         /* close or delete */
    8199             : 
    8200        6342 :         for (i=0; i < num_total; i++) {
    8201             : 
    8202        6300 :                 if (ndr_policy_handle_empty(&handles[i])) {
    8203        3150 :                         continue;
    8204             :                 }
    8205             : 
    8206        3150 :                 if (torture_setting_bool(tctx, "samba3", false)) {
    8207        1800 :                         torture_assert(tctx,
    8208             :                                 test_samr_handle_Close(b, tctx, &handles[i]),
    8209             :                                 "failed to close handle");
    8210             :                 } else {
    8211        1350 :                         switch (ctx->choice) {
    8212         450 :                         case TORTURE_SAMR_MANY_ACCOUNTS:
    8213         450 :                                 torture_assert(tctx,
    8214             :                                         test_DeleteUser(b, tctx, &handles[i]),
    8215             :                                         "failed to delete user");
    8216         450 :                                 break;
    8217         450 :                         case TORTURE_SAMR_MANY_GROUPS:
    8218         450 :                                 torture_assert(tctx,
    8219             :                                         test_DeleteDomainGroup(b, tctx, &handles[i]),
    8220             :                                         "failed to delete group");
    8221         450 :                                 break;
    8222         450 :                         case TORTURE_SAMR_MANY_ALIASES:
    8223         450 :                                 torture_assert(tctx,
    8224             :                                         test_DeleteAlias(b, tctx, &handles[i]),
    8225             :                                         "failed to delete alias");
    8226         450 :                                 break;
    8227           0 :                         default:
    8228           0 :                                 return false;
    8229             :                         }
    8230             :                 }
    8231             :         }
    8232             : 
    8233          42 :         talloc_free(handles);
    8234             : 
    8235          42 :         if (ctx->choice == TORTURE_SAMR_MANY_ACCOUNTS && num_enum != num_anounced + num_created) {
    8236           2 :                 torture_comment(tctx,
    8237             :                                 "unexpected number of results (%u) returned in enum call, expected %u\n",
    8238             :                                 num_enum, num_anounced + num_created);
    8239             : 
    8240           2 :                 torture_comment(tctx,
    8241             :                                 "unexpected number of results (%u) returned in dispinfo, call, expected %u\n",
    8242             :                                 num_disp, num_anounced + num_created);
    8243             :         }
    8244             : 
    8245          42 :         return true;
    8246             : }
    8247             : 
    8248             : static bool test_Connect(struct dcerpc_binding_handle *b,
    8249             :                          struct torture_context *tctx,
    8250             :                          struct policy_handle *handle);
    8251             : 
    8252         116 : static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
    8253             :                             struct torture_samr_context *ctx, struct dom_sid *sid)
    8254             : {
    8255             :         struct samr_OpenDomain r;
    8256             :         struct policy_handle domain_handle;
    8257             :         struct policy_handle alias_handle;
    8258             :         struct policy_handle user_handle;
    8259             :         struct policy_handle group_handle;
    8260         116 :         bool ret = true;
    8261         116 :         struct dcerpc_binding_handle *b = p->binding_handle;
    8262             : 
    8263         116 :         ZERO_STRUCT(alias_handle);
    8264         116 :         ZERO_STRUCT(user_handle);
    8265         116 :         ZERO_STRUCT(group_handle);
    8266         116 :         ZERO_STRUCT(domain_handle);
    8267             : 
    8268         116 :         torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
    8269             : 
    8270         116 :         r.in.connect_handle = &ctx->handle;
    8271         116 :         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    8272         116 :         r.in.sid = sid;
    8273         116 :         r.out.domain_handle = &domain_handle;
    8274             : 
    8275         116 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenDomain_r(b, tctx, &r),
    8276             :                 "OpenDomain failed");
    8277         116 :         torture_assert_ntstatus_ok(tctx, r.out.result, "OpenDomain failed");
    8278             : 
    8279             :         /* run the domain tests with the main handle closed - this tests
    8280             :            the servers reference counting */
    8281         116 :         torture_assert(tctx, test_samr_handle_Close(b, tctx, &ctx->handle), "Failed to close SAMR handle");
    8282             : 
    8283         116 :         switch (ctx->choice) {
    8284          20 :         case TORTURE_SAMR_PASSWORDS:
    8285             :         case TORTURE_SAMR_USER_PRIVILEGES:
    8286          20 :                 if (!torture_setting_bool(tctx, "samba3", false)) {
    8287           4 :                         ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, NULL);
    8288             :                 }
    8289          20 :                 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
    8290          20 :                 if (!ret) {
    8291           0 :                         torture_result(tctx, TORTURE_FAIL, "Testing PASSWORDS or PRIVILEGES on domain %s failed!\n", dom_sid_string(tctx, sid));
    8292             :                 }
    8293          20 :                 break;
    8294          14 :         case TORTURE_SAMR_USER_ATTRIBUTES:
    8295          14 :                 if (!torture_setting_bool(tctx, "samba3", false)) {
    8296           6 :                         ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, NULL);
    8297             :                 }
    8298          14 :                 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
    8299             :                 /* This test needs 'complex' users to validate */
    8300          14 :                 ret &= test_QueryDisplayInfo(b, tctx, &domain_handle);
    8301          14 :                 if (!ret) {
    8302          12 :                         torture_result(tctx, TORTURE_FAIL, "Testing ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
    8303             :                 }
    8304          14 :                 break;
    8305          26 :         case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
    8306             :         case TORTURE_SAMR_PASSWORDS_BADPWDCOUNT:
    8307             :         case TORTURE_SAMR_PASSWORDS_LOCKOUT:
    8308          26 :                 if (!torture_setting_bool(tctx, "samba3", false)) {
    8309           6 :                         ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, ctx->machine_credentials);
    8310             :                 }
    8311          26 :                 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, ctx->machine_credentials, true);
    8312          26 :                 if (!ret) {
    8313           4 :                         torture_result(tctx, TORTURE_FAIL, "Testing PASSWORDS PWDLASTSET or BADPWDCOUNT on domain %s failed!\n", dom_sid_string(tctx, sid));
    8314             :                 }
    8315          26 :                 break;
    8316          42 :         case TORTURE_SAMR_MANY_ACCOUNTS:
    8317             :         case TORTURE_SAMR_MANY_GROUPS:
    8318             :         case TORTURE_SAMR_MANY_ALIASES:
    8319          42 :                 ret &= test_ManyObjects(p, tctx, &domain_handle, sid, ctx);
    8320          42 :                 if (!ret) {
    8321           0 :                         torture_result(tctx, TORTURE_FAIL, "Testing MANY-{ACCOUNTS,GROUPS,ALIASES} on domain %s failed!\n", dom_sid_string(tctx, sid));
    8322             :                 }
    8323          42 :                 break;
    8324          14 :         case TORTURE_SAMR_OTHER:
    8325          14 :                 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
    8326          14 :                 if (!ret) {
    8327           0 :                         torture_result(tctx, TORTURE_FAIL, "Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
    8328             :                 }
    8329          14 :                 if (!torture_setting_bool(tctx, "samba3", false)) {
    8330           6 :                         ret &= test_QuerySecurity(b, tctx, &domain_handle);
    8331             :                 }
    8332          14 :                 ret &= test_RemoveMemberFromForeignDomain(b, tctx, &domain_handle);
    8333          14 :                 ret &= test_CreateAlias(b, tctx, &domain_handle, TEST_ALIASNAME, &alias_handle, sid, true);
    8334          14 :                 ret &= test_CreateDomainGroup(b, tctx, &domain_handle, TEST_GROUPNAME, &group_handle, sid, true);
    8335          14 :                 ret &= test_GetAliasMembership(b, tctx, &domain_handle);
    8336          14 :                 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
    8337          14 :                 ret &= test_QueryDomainInfo2(b, tctx, &domain_handle);
    8338          14 :                 ret &= test_EnumDomainUsers_all(b, tctx, &domain_handle);
    8339          14 :                 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
    8340          14 :                 ret &= test_EnumDomainGroups_all(b, tctx, &domain_handle);
    8341          14 :                 ret &= test_EnumDomainAliases_all(b, tctx, &domain_handle);
    8342          14 :                 ret &= test_QueryDisplayInfo2(b, tctx, &domain_handle);
    8343          14 :                 ret &= test_QueryDisplayInfo3(b, tctx, &domain_handle);
    8344          14 :                 ret &= test_QueryDisplayInfo_continue(b, tctx, &domain_handle);
    8345             : 
    8346          14 :                 if (torture_setting_bool(tctx, "samba4", false)) {
    8347           6 :                         torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
    8348             :                 } else {
    8349           8 :                         ret &= test_GetDisplayEnumerationIndex(b, tctx, &domain_handle);
    8350           8 :                         ret &= test_GetDisplayEnumerationIndex2(b, tctx, &domain_handle);
    8351             :                 }
    8352          14 :                 ret &= test_GroupList(b, tctx, sid, &domain_handle);
    8353          14 :                 ret &= test_TestPrivateFunctionsDomain(b, tctx, &domain_handle);
    8354          14 :                 ret &= test_RidToSid(b, tctx, sid, &domain_handle);
    8355          14 :                 ret &= test_GetBootKeyInformation(b, tctx, &domain_handle);
    8356          14 :                 if (!ret) {
    8357          14 :                         torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
    8358             :                 }
    8359          14 :                 break;
    8360             :         }
    8361             : 
    8362         141 :         if (!ndr_policy_handle_empty(&user_handle) &&
    8363          32 :             !test_DeleteUser(b, tctx, &user_handle)) {
    8364           0 :                 ret = false;
    8365             :         }
    8366             : 
    8367         121 :         if (!ndr_policy_handle_empty(&alias_handle) &&
    8368           7 :             !test_DeleteAlias(b, tctx, &alias_handle)) {
    8369           0 :                 ret = false;
    8370             :         }
    8371             : 
    8372         121 :         if (!ndr_policy_handle_empty(&group_handle) &&
    8373           7 :             !test_DeleteDomainGroup(b, tctx, &group_handle)) {
    8374           0 :                 ret = false;
    8375             :         }
    8376             : 
    8377         116 :         torture_assert(tctx, test_samr_handle_Close(b, tctx, &domain_handle), "Failed to close SAMR domain handle");
    8378             : 
    8379         116 :         torture_assert(tctx, test_Connect(b, tctx, &ctx->handle), "Faile to re-connect SAMR handle");
    8380             :         /* reconnect the main handle */
    8381             : 
    8382         116 :         if (!ret) {
    8383          30 :                 torture_result(tctx, TORTURE_FAIL, "Testing domain %s failed!\n", dom_sid_string(tctx, sid));
    8384             :         }
    8385             : 
    8386         116 :         return ret;
    8387             : }
    8388             : 
    8389         116 : static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
    8390             :                               struct torture_samr_context *ctx, const char *domain)
    8391             : {
    8392             :         struct samr_LookupDomain r;
    8393         116 :         struct dom_sid2 *sid = NULL;
    8394             :         struct lsa_String n1;
    8395             :         struct lsa_String n2;
    8396         116 :         bool ret = true;
    8397         116 :         struct dcerpc_binding_handle *b = p->binding_handle;
    8398             : 
    8399         116 :         torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
    8400             : 
    8401             :         /* check for correct error codes */
    8402         116 :         r.in.connect_handle = &ctx->handle;
    8403         116 :         r.in.domain_name = &n2;
    8404         116 :         r.out.sid = &sid;
    8405         116 :         n2.string = NULL;
    8406             : 
    8407         116 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupDomain_r(b, tctx, &r),
    8408             :                 "LookupDomain failed");
    8409         116 :         torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, r.out.result, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
    8410             : 
    8411         116 :         init_lsa_String(&n2, "xxNODOMAINxx");
    8412             : 
    8413         116 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupDomain_r(b, tctx, &r),
    8414             :                 "LookupDomain failed");
    8415         116 :         torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, r.out.result, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
    8416             : 
    8417         116 :         r.in.connect_handle = &ctx->handle;
    8418             : 
    8419         116 :         init_lsa_String(&n1, domain);
    8420         116 :         r.in.domain_name = &n1;
    8421             : 
    8422         116 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupDomain_r(b, tctx, &r),
    8423             :                 "LookupDomain failed");
    8424         116 :         torture_assert_ntstatus_ok(tctx, r.out.result, "LookupDomain");
    8425             : 
    8426         116 :         if (!test_GetDomPwInfo(p, tctx, &n1)) {
    8427           0 :                 ret = false;
    8428             :         }
    8429             : 
    8430         116 :         if (!test_OpenDomain(p, tctx, ctx, *r.out.sid)) {
    8431          30 :                 ret = false;
    8432             :         }
    8433             : 
    8434         116 :         return ret;
    8435             : }
    8436             : 
    8437             : 
    8438          58 : static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
    8439             :                              struct torture_samr_context *ctx)
    8440             : {
    8441             :         struct samr_EnumDomains r;
    8442          58 :         uint32_t resume_handle = 0;
    8443          58 :         uint32_t num_entries = 0;
    8444          58 :         struct samr_SamArray *sam = NULL;
    8445             :         int i;
    8446          58 :         bool ret = true;
    8447          58 :         struct dcerpc_binding_handle *b = p->binding_handle;
    8448             : 
    8449          58 :         r.in.connect_handle = &ctx->handle;
    8450          58 :         r.in.resume_handle = &resume_handle;
    8451          58 :         r.in.buf_size = (uint32_t)-1;
    8452          58 :         r.out.resume_handle = &resume_handle;
    8453          58 :         r.out.num_entries = &num_entries;
    8454          58 :         r.out.sam = &sam;
    8455             : 
    8456          58 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomains_r(b, tctx, &r),
    8457             :                 "EnumDomains failed");
    8458          58 :         torture_assert_ntstatus_ok(tctx, r.out.result, "EnumDomains failed");
    8459             : 
    8460          58 :         if (!*r.out.sam) {
    8461           0 :                 return false;
    8462             :         }
    8463             : 
    8464         174 :         for (i=0;i<sam->count;i++) {
    8465         116 :                 if (!test_LookupDomain(p, tctx, ctx,
    8466         116 :                                        sam->entries[i].name.string)) {
    8467          30 :                         ret = false;
    8468             :                 }
    8469             :         }
    8470             : 
    8471          58 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomains_r(b, tctx, &r),
    8472             :                 "EnumDomains failed");
    8473          58 :         torture_assert_ntstatus_ok(tctx, r.out.result, "EnumDomains failed");
    8474             : 
    8475          58 :         return ret;
    8476             : }
    8477             : 
    8478             : 
    8479         174 : static bool test_Connect(struct dcerpc_binding_handle *b,
    8480             :                          struct torture_context *tctx,
    8481             :                          struct policy_handle *handle)
    8482             : {
    8483             :         struct samr_Connect r;
    8484             :         struct samr_Connect2 r2;
    8485             :         struct samr_Connect3 r3;
    8486             :         struct samr_Connect4 r4;
    8487             :         struct samr_Connect5 r5;
    8488             :         union samr_ConnectInfo info;
    8489             :         struct policy_handle h;
    8490         174 :         uint32_t level_out = 0;
    8491         174 :         bool ret = true, got_handle = false;
    8492             : 
    8493         174 :         torture_comment(tctx, "Testing samr_Connect\n");
    8494             : 
    8495         174 :         r.in.system_name = NULL;
    8496         174 :         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    8497         174 :         r.out.connect_handle = &h;
    8498             : 
    8499         174 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect_r(b, tctx, &r),
    8500             :                 "Connect failed");
    8501         174 :         if (!NT_STATUS_IS_OK(r.out.result)) {
    8502           0 :                 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(r.out.result));
    8503           0 :                 ret = false;
    8504             :         } else {
    8505         174 :                 got_handle = true;
    8506         174 :                 *handle = h;
    8507             :         }
    8508             : 
    8509         174 :         torture_comment(tctx, "Testing samr_Connect2\n");
    8510             : 
    8511         174 :         r2.in.system_name = NULL;
    8512         174 :         r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    8513         174 :         r2.out.connect_handle = &h;
    8514             : 
    8515         174 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect2_r(b, tctx, &r2),
    8516             :                 "Connect2 failed");
    8517         174 :         if (!NT_STATUS_IS_OK(r2.out.result)) {
    8518           0 :                 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(r2.out.result));
    8519           0 :                 ret = false;
    8520             :         } else {
    8521         174 :                 if (got_handle) {
    8522         174 :                         test_samr_handle_Close(b, tctx, handle);
    8523             :                 }
    8524         174 :                 got_handle = true;
    8525         174 :                 *handle = h;
    8526             :         }
    8527             : 
    8528         174 :         torture_comment(tctx, "Testing samr_Connect3\n");
    8529             : 
    8530         174 :         r3.in.system_name = NULL;
    8531         174 :         r3.in.unknown = 0;
    8532         174 :         r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    8533         174 :         r3.out.connect_handle = &h;
    8534             : 
    8535         174 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect3_r(b, tctx, &r3),
    8536             :                 "Connect3 failed");
    8537         174 :         if (!NT_STATUS_IS_OK(r3.out.result)) {
    8538           0 :                 torture_result(tctx, TORTURE_FAIL, "Connect3 failed - %s\n", nt_errstr(r3.out.result));
    8539           0 :                 ret = false;
    8540             :         } else {
    8541         174 :                 if (got_handle) {
    8542         174 :                         test_samr_handle_Close(b, tctx, handle);
    8543             :                 }
    8544         174 :                 got_handle = true;
    8545         174 :                 *handle = h;
    8546             :         }
    8547             : 
    8548         174 :         torture_comment(tctx, "Testing samr_Connect4\n");
    8549             : 
    8550         174 :         r4.in.system_name = "";
    8551         174 :         r4.in.client_version = 0;
    8552         174 :         r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    8553         174 :         r4.out.connect_handle = &h;
    8554             : 
    8555         174 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect4_r(b, tctx, &r4),
    8556             :                 "Connect4 failed");
    8557         174 :         if (!NT_STATUS_IS_OK(r4.out.result)) {
    8558           0 :                 torture_result(tctx, TORTURE_FAIL, "Connect4 failed - %s\n", nt_errstr(r4.out.result));
    8559           0 :                 ret = false;
    8560             :         } else {
    8561         174 :                 if (got_handle) {
    8562         174 :                         test_samr_handle_Close(b, tctx, handle);
    8563             :                 }
    8564         174 :                 got_handle = true;
    8565         174 :                 *handle = h;
    8566             :         }
    8567             : 
    8568         174 :         torture_comment(tctx, "Testing samr_Connect5\n");
    8569             : 
    8570         174 :         info.info1.client_version = 0;
    8571         174 :         info.info1.unknown2 = 0;
    8572             : 
    8573         174 :         r5.in.system_name = "";
    8574         174 :         r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    8575         174 :         r5.in.level_in = 1;
    8576         174 :         r5.out.level_out = &level_out;
    8577         174 :         r5.in.info_in = &info;
    8578         174 :         r5.out.info_out = &info;
    8579         174 :         r5.out.connect_handle = &h;
    8580             : 
    8581         174 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect5_r(b, tctx, &r5),
    8582             :                 "Connect5 failed");
    8583         174 :         if (!NT_STATUS_IS_OK(r5.out.result)) {
    8584           0 :                 torture_result(tctx, TORTURE_FAIL, "Connect5 failed - %s\n", nt_errstr(r5.out.result));
    8585           0 :                 ret = false;
    8586             :         } else {
    8587         174 :                 if (got_handle) {
    8588         174 :                         test_samr_handle_Close(b, tctx, handle);
    8589             :                 }
    8590         174 :                 got_handle = true;
    8591         174 :                 *handle = h;
    8592             :         }
    8593             : 
    8594         174 :         return ret;
    8595             : }
    8596             : 
    8597             : 
    8598           7 : static bool test_samr_ValidatePassword(struct torture_context *tctx,
    8599             :                                        struct dcerpc_pipe *p)
    8600             : {
    8601             :         struct samr_ValidatePassword r;
    8602             :         union samr_ValidatePasswordReq req;
    8603           7 :         union samr_ValidatePasswordRep *repp = NULL;
    8604             :         NTSTATUS status;
    8605           7 :         const char *passwords[] = { "penguin", "p@ssw0rd", "p@ssw0rd123$", NULL };
    8606             :         int i;
    8607           7 :         struct dcerpc_binding_handle *b = p->binding_handle;
    8608             : 
    8609           7 :         torture_comment(tctx, "Testing samr_ValidatePassword\n");
    8610             : 
    8611           7 :         if (p->conn->transport.transport != NCACN_IP_TCP) {
    8612           0 :                 torture_comment(tctx, "samr_ValidatePassword only should succeed over NCACN_IP_TCP!\n");
    8613             :         }
    8614             : 
    8615           7 :         ZERO_STRUCT(r);
    8616           7 :         r.in.level = NetValidatePasswordReset;
    8617           7 :         r.in.req = &req;
    8618           7 :         r.out.rep = &repp;
    8619             : 
    8620           7 :         ZERO_STRUCT(req);
    8621           7 :         req.req3.account.string = "non-existent-account-aklsdji";
    8622             : 
    8623          22 :         for (i=0; passwords[i]; i++) {
    8624          17 :                 req.req3.password.string = passwords[i];
    8625             : 
    8626          17 :                 status = dcerpc_samr_ValidatePassword_r(b, tctx, &r);
    8627          17 :                 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) {
    8628           0 :                         torture_skip(tctx, "ValidatePassword not supported by server\n");
    8629             :                 }
    8630          17 :                 torture_assert_ntstatus_ok(tctx, status,
    8631             :                                            "samr_ValidatePassword failed");
    8632          15 :                 torture_assert_ntstatus_ok(tctx, r.out.result,
    8633             :                                            "samr_ValidatePassword failed");
    8634          27 :                 torture_comment(tctx, "Server %s password '%s' with code %i\n",
    8635          15 :                                 repp->ctr3.status==SAMR_VALIDATION_STATUS_SUCCESS?"allowed":"refused",
    8636          15 :                                 req.req3.password.string, repp->ctr3.status);
    8637             :         }
    8638             : 
    8639           5 :         return true;
    8640             : }
    8641             : 
    8642           7 : bool torture_rpc_samr(struct torture_context *torture)
    8643             : {
    8644             :         NTSTATUS status;
    8645             :         struct dcerpc_pipe *p;
    8646           7 :         bool ret = true;
    8647             :         struct torture_samr_context *ctx;
    8648             :         struct dcerpc_binding_handle *b;
    8649             : 
    8650           7 :         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
    8651           7 :         if (!NT_STATUS_IS_OK(status)) {
    8652           0 :                 return false;
    8653             :         }
    8654           7 :         b = p->binding_handle;
    8655             : 
    8656           7 :         ctx = talloc_zero(torture, struct torture_samr_context);
    8657             : 
    8658           7 :         ctx->choice = TORTURE_SAMR_OTHER;
    8659             : 
    8660           7 :         ret &= test_Connect(b, torture, &ctx->handle);
    8661             : 
    8662           7 :         if (!torture_setting_bool(torture, "samba3", false)) {
    8663           3 :                 ret &= test_QuerySecurity(b, torture, &ctx->handle);
    8664             :         }
    8665             : 
    8666           7 :         ret &= test_EnumDomains(p, torture, ctx);
    8667             : 
    8668           7 :         ret &= test_SetDsrmPassword(b, torture, &ctx->handle);
    8669             : 
    8670           7 :         ret &= test_Shutdown(b, torture, &ctx->handle);
    8671             : 
    8672           7 :         ret &= test_samr_handle_Close(b, torture, &ctx->handle);
    8673             : 
    8674           7 :         return ret;
    8675             : }
    8676             : 
    8677             : 
    8678           7 : bool torture_rpc_samr_users(struct torture_context *torture)
    8679             : {
    8680             :         NTSTATUS status;
    8681             :         struct dcerpc_pipe *p;
    8682           7 :         bool ret = true;
    8683             :         struct torture_samr_context *ctx;
    8684             :         struct dcerpc_binding_handle *b;
    8685             : 
    8686           7 :         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
    8687           7 :         if (!NT_STATUS_IS_OK(status)) {
    8688           0 :                 return false;
    8689             :         }
    8690           7 :         b = p->binding_handle;
    8691             : 
    8692           7 :         ctx = talloc_zero(torture, struct torture_samr_context);
    8693             : 
    8694           7 :         ctx->choice = TORTURE_SAMR_USER_ATTRIBUTES;
    8695             : 
    8696           7 :         ret &= test_Connect(b, torture, &ctx->handle);
    8697             : 
    8698           7 :         if (!torture_setting_bool(torture, "samba3", false)) {
    8699           3 :                 ret &= test_QuerySecurity(b, torture, &ctx->handle);
    8700             :         }
    8701             : 
    8702           7 :         ret &= test_EnumDomains(p, torture, ctx);
    8703             : 
    8704           7 :         ret &= test_SetDsrmPassword(b, torture, &ctx->handle);
    8705             : 
    8706           7 :         ret &= test_Shutdown(b, torture, &ctx->handle);
    8707             : 
    8708           7 :         ret &= test_samr_handle_Close(b, torture, &ctx->handle);
    8709             : 
    8710           7 :         return ret;
    8711             : }
    8712             : 
    8713             : 
    8714           5 : bool torture_rpc_samr_passwords(struct torture_context *torture)
    8715             : {
    8716             :         NTSTATUS status;
    8717             :         struct dcerpc_pipe *p;
    8718           5 :         bool ret = true;
    8719             :         struct torture_samr_context *ctx;
    8720             :         struct dcerpc_binding_handle *b;
    8721             : 
    8722           5 :         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
    8723           5 :         if (!NT_STATUS_IS_OK(status)) {
    8724           0 :                 return false;
    8725             :         }
    8726           5 :         b = p->binding_handle;
    8727             : 
    8728           5 :         ctx = talloc_zero(torture, struct torture_samr_context);
    8729             : 
    8730           5 :         ctx->choice = TORTURE_SAMR_PASSWORDS;
    8731             : 
    8732           5 :         ret &= test_Connect(b, torture, &ctx->handle);
    8733             : 
    8734           5 :         ret &= test_EnumDomains(p, torture, ctx);
    8735             : 
    8736           5 :         ret &= test_samr_handle_Close(b, torture, &ctx->handle);
    8737             : 
    8738           5 :         return ret;
    8739             : }
    8740             : 
    8741           5 : static bool torture_rpc_samr_pwdlastset(struct torture_context *torture,
    8742             :                                         struct dcerpc_pipe *p2,
    8743             :                                         struct cli_credentials *machine_credentials)
    8744             : {
    8745             :         NTSTATUS status;
    8746             :         struct dcerpc_pipe *p;
    8747           5 :         bool ret = true;
    8748             :         struct torture_samr_context *ctx;
    8749             :         struct dcerpc_binding_handle *b;
    8750             : 
    8751           5 :         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
    8752           5 :         if (!NT_STATUS_IS_OK(status)) {
    8753           0 :                 return false;
    8754             :         }
    8755           5 :         b = p->binding_handle;
    8756             : 
    8757           5 :         ctx = talloc_zero(torture, struct torture_samr_context);
    8758             : 
    8759           5 :         ctx->choice = TORTURE_SAMR_PASSWORDS_PWDLASTSET;
    8760           5 :         ctx->machine_credentials = machine_credentials;
    8761             : 
    8762           5 :         ret &= test_Connect(b, torture, &ctx->handle);
    8763             : 
    8764           5 :         ret &= test_EnumDomains(p, torture, ctx);
    8765             : 
    8766           5 :         ret &= test_samr_handle_Close(b, torture, &ctx->handle);
    8767             : 
    8768           5 :         return ret;
    8769             : }
    8770             : 
    8771        2355 : struct torture_suite *torture_rpc_samr_passwords_pwdlastset(TALLOC_CTX *mem_ctx)
    8772             : {
    8773        2355 :         struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.passwords.pwdlastset");
    8774             :         struct torture_rpc_tcase *tcase;
    8775             : 
    8776        2355 :         tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
    8777             :                                                           &ndr_table_samr,
    8778             :                                                           TEST_ACCOUNT_NAME_PWD);
    8779             : 
    8780        2355 :         torture_rpc_tcase_add_test_creds(tcase, "pwdLastSet",
    8781             :                                          torture_rpc_samr_pwdlastset);
    8782             : 
    8783        2355 :         return suite;
    8784             : }
    8785             : 
    8786           5 : static bool torture_rpc_samr_users_privileges_delete_user(struct torture_context *torture,
    8787             :                                                           struct dcerpc_pipe *p2,
    8788             :                                                           struct cli_credentials *machine_credentials)
    8789             : {
    8790             :         NTSTATUS status;
    8791             :         struct dcerpc_pipe *p;
    8792           5 :         bool ret = true;
    8793             :         struct torture_samr_context *ctx;
    8794             :         struct dcerpc_binding_handle *b;
    8795             : 
    8796           5 :         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
    8797           5 :         if (!NT_STATUS_IS_OK(status)) {
    8798           0 :                 return false;
    8799             :         }
    8800           5 :         b = p->binding_handle;
    8801             : 
    8802           5 :         ctx = talloc_zero(torture, struct torture_samr_context);
    8803             : 
    8804           5 :         ctx->choice = TORTURE_SAMR_USER_PRIVILEGES;
    8805           5 :         ctx->machine_credentials = machine_credentials;
    8806             : 
    8807           5 :         ret &= test_Connect(b, torture, &ctx->handle);
    8808             : 
    8809           5 :         ret &= test_EnumDomains(p, torture, ctx);
    8810             : 
    8811           5 :         ret &= test_samr_handle_Close(b, torture, &ctx->handle);
    8812             : 
    8813           5 :         return ret;
    8814             : }
    8815             : 
    8816        2355 : struct torture_suite *torture_rpc_samr_user_privileges(TALLOC_CTX *mem_ctx)
    8817             : {
    8818        2355 :         struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.users.privileges");
    8819             :         struct torture_rpc_tcase *tcase;
    8820             : 
    8821        2355 :         tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
    8822             :                                                           &ndr_table_samr,
    8823             :                                                           TEST_ACCOUNT_NAME_PWD);
    8824             : 
    8825        2355 :         torture_rpc_tcase_add_test_creds(tcase, "delete_privileged_user",
    8826             :                                          torture_rpc_samr_users_privileges_delete_user);
    8827             : 
    8828        2355 :         return suite;
    8829             : }
    8830             : 
    8831           7 : static bool torture_rpc_samr_many_accounts(struct torture_context *torture,
    8832             :                                            struct dcerpc_pipe *p2,
    8833             :                                            void *data)
    8834             : {
    8835             :         NTSTATUS status;
    8836             :         struct dcerpc_pipe *p;
    8837           7 :         bool ret = true;
    8838           6 :         struct torture_samr_context *ctx =
    8839           1 :                 talloc_get_type_abort(data, struct torture_samr_context);
    8840             :         struct dcerpc_binding_handle *b;
    8841             : 
    8842           7 :         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
    8843           7 :         if (!NT_STATUS_IS_OK(status)) {
    8844           0 :                 return false;
    8845             :         }
    8846           7 :         b = p->binding_handle;
    8847             : 
    8848           7 :         ctx->choice = TORTURE_SAMR_MANY_ACCOUNTS;
    8849           8 :         ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
    8850           7 :                                                         ctx->num_objects_large_dc);
    8851             : 
    8852           7 :         ret &= test_Connect(b, torture, &ctx->handle);
    8853             : 
    8854           7 :         ret &= test_EnumDomains(p, torture, ctx);
    8855             : 
    8856           7 :         ret &= test_samr_handle_Close(b, torture, &ctx->handle);
    8857             : 
    8858           7 :         return ret;
    8859             : }
    8860             : 
    8861           7 : static bool torture_rpc_samr_many_groups(struct torture_context *torture,
    8862             :                                          struct dcerpc_pipe *p2,
    8863             :                                          void *data)
    8864             : {
    8865             :         NTSTATUS status;
    8866             :         struct dcerpc_pipe *p;
    8867           7 :         bool ret = true;
    8868           6 :         struct torture_samr_context *ctx =
    8869           1 :                 talloc_get_type_abort(data, struct torture_samr_context);
    8870             :         struct dcerpc_binding_handle *b;
    8871             : 
    8872           7 :         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
    8873           7 :         if (!NT_STATUS_IS_OK(status)) {
    8874           0 :                 return false;
    8875             :         }
    8876           7 :         b = p->binding_handle;
    8877             : 
    8878           7 :         ctx->choice = TORTURE_SAMR_MANY_GROUPS;
    8879           8 :         ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
    8880           7 :                                                         ctx->num_objects_large_dc);
    8881             : 
    8882           7 :         ret &= test_Connect(b, torture, &ctx->handle);
    8883             : 
    8884           7 :         ret &= test_EnumDomains(p, torture, ctx);
    8885             : 
    8886           7 :         ret &= test_samr_handle_Close(b, torture, &ctx->handle);
    8887             : 
    8888           7 :         return ret;
    8889             : }
    8890             : 
    8891           7 : static bool torture_rpc_samr_many_aliases(struct torture_context *torture,
    8892             :                                           struct dcerpc_pipe *p2,
    8893             :                                           void *data)
    8894             : {
    8895             :         NTSTATUS status;
    8896             :         struct dcerpc_pipe *p;
    8897           7 :         bool ret = true;
    8898           6 :         struct torture_samr_context *ctx =
    8899           1 :                 talloc_get_type_abort(data, struct torture_samr_context);
    8900             :         struct dcerpc_binding_handle *b;
    8901             : 
    8902           7 :         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
    8903           7 :         if (!NT_STATUS_IS_OK(status)) {
    8904           0 :                 return false;
    8905             :         }
    8906           7 :         b = p->binding_handle;
    8907             : 
    8908           7 :         ctx->choice = TORTURE_SAMR_MANY_ALIASES;
    8909           8 :         ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
    8910           7 :                                                         ctx->num_objects_large_dc);
    8911             : 
    8912           7 :         ret &= test_Connect(b, torture, &ctx->handle);
    8913             : 
    8914           7 :         ret &= test_EnumDomains(p, torture, ctx);
    8915             : 
    8916           7 :         ret &= test_samr_handle_Close(b, torture, &ctx->handle);
    8917             : 
    8918           7 :         return ret;
    8919             : }
    8920             : 
    8921        2355 : struct torture_suite *torture_rpc_samr_large_dc(TALLOC_CTX *mem_ctx)
    8922             : {
    8923        2355 :         struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.large-dc");
    8924             :         struct torture_rpc_tcase *tcase;
    8925             :         struct torture_samr_context *ctx;
    8926             : 
    8927        2355 :         tcase = torture_suite_add_rpc_iface_tcase(suite, "samr", &ndr_table_samr);
    8928             : 
    8929        2355 :         ctx = talloc_zero(suite, struct torture_samr_context);
    8930        2355 :         ctx->num_objects_large_dc = 150;
    8931             : 
    8932        2355 :         torture_rpc_tcase_add_test_ex(tcase, "many_aliases",
    8933             :                                       torture_rpc_samr_many_aliases, ctx);
    8934        2355 :         torture_rpc_tcase_add_test_ex(tcase, "many_groups",
    8935             :                                       torture_rpc_samr_many_groups, ctx);
    8936        2355 :         torture_rpc_tcase_add_test_ex(tcase, "many_accounts",
    8937             :                                       torture_rpc_samr_many_accounts, ctx);
    8938             : 
    8939        2355 :         return suite;
    8940             : }
    8941             : 
    8942           5 : static bool torture_rpc_samr_badpwdcount(struct torture_context *torture,
    8943             :                                          struct dcerpc_pipe *p2,
    8944             :                                          struct cli_credentials *machine_credentials)
    8945             : {
    8946             :         NTSTATUS status;
    8947             :         struct dcerpc_pipe *p;
    8948           5 :         bool ret = true;
    8949             :         struct torture_samr_context *ctx;
    8950             :         struct dcerpc_binding_handle *b;
    8951             : 
    8952           5 :         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
    8953           5 :         if (!NT_STATUS_IS_OK(status)) {
    8954           0 :                 return false;
    8955             :         }
    8956           5 :         b = p->binding_handle;
    8957             : 
    8958           5 :         ctx = talloc_zero(torture, struct torture_samr_context);
    8959             : 
    8960           5 :         ctx->choice = TORTURE_SAMR_PASSWORDS_BADPWDCOUNT;
    8961           5 :         ctx->machine_credentials = machine_credentials;
    8962             : 
    8963           5 :         ret &= test_Connect(b, torture, &ctx->handle);
    8964             : 
    8965           5 :         ret &= test_EnumDomains(p, torture, ctx);
    8966             : 
    8967           5 :         ret &= test_samr_handle_Close(b, torture, &ctx->handle);
    8968             : 
    8969           5 :         return ret;
    8970             : }
    8971             : 
    8972        2355 : struct torture_suite *torture_rpc_samr_passwords_badpwdcount(TALLOC_CTX *mem_ctx)
    8973             : {
    8974        2355 :         struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.passwords.badpwdcount");
    8975             :         struct torture_rpc_tcase *tcase;
    8976             : 
    8977        2355 :         tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
    8978             :                                                           &ndr_table_samr,
    8979             :                                                           TEST_ACCOUNT_NAME_PWD);
    8980             : 
    8981        2355 :         torture_rpc_tcase_add_test_creds(tcase, "badPwdCount",
    8982             :                                          torture_rpc_samr_badpwdcount);
    8983             : 
    8984        2355 :         return suite;
    8985             : }
    8986             : 
    8987           3 : static bool torture_rpc_samr_lockout(struct torture_context *torture,
    8988             :                                      struct dcerpc_pipe *p2,
    8989             :                                      struct cli_credentials *machine_credentials)
    8990             : {
    8991             :         NTSTATUS status;
    8992             :         struct dcerpc_pipe *p;
    8993           3 :         bool ret = true;
    8994             :         struct torture_samr_context *ctx;
    8995             :         struct dcerpc_binding_handle *b;
    8996             : 
    8997           3 :         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
    8998           3 :         if (!NT_STATUS_IS_OK(status)) {
    8999           0 :                 return false;
    9000             :         }
    9001           3 :         b = p->binding_handle;
    9002             : 
    9003           3 :         ctx = talloc_zero(torture, struct torture_samr_context);
    9004             : 
    9005           3 :         ctx->choice = TORTURE_SAMR_PASSWORDS_LOCKOUT;
    9006           3 :         ctx->machine_credentials = machine_credentials;
    9007             : 
    9008           3 :         ret &= test_Connect(b, torture, &ctx->handle);
    9009             : 
    9010           3 :         ret &= test_EnumDomains(p, torture, ctx);
    9011             : 
    9012           3 :         ret &= test_samr_handle_Close(b, torture, &ctx->handle);
    9013             : 
    9014           3 :         return ret;
    9015             : }
    9016             : 
    9017        2355 : struct torture_suite *torture_rpc_samr_passwords_lockout(TALLOC_CTX *mem_ctx)
    9018             : {
    9019        2355 :         struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.passwords.lockout");
    9020             :         struct torture_rpc_tcase *tcase;
    9021             : 
    9022        2355 :         tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
    9023             :                                                           &ndr_table_samr,
    9024             :                                                           TEST_ACCOUNT_NAME_PWD);
    9025             : 
    9026        2355 :         torture_rpc_tcase_add_test_creds(tcase, "lockout",
    9027             :                                          torture_rpc_samr_lockout);
    9028             : 
    9029        2355 :         return suite;
    9030             : }
    9031             : 
    9032        2355 : struct torture_suite *torture_rpc_samr_passwords_validate(TALLOC_CTX *mem_ctx)
    9033             : {
    9034        2355 :         struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.passwords.validate");
    9035             :         struct torture_rpc_tcase *tcase;
    9036             : 
    9037        2355 :         tcase = torture_suite_add_rpc_iface_tcase(suite, "samr",
    9038             :                                                   &ndr_table_samr);
    9039        2355 :         torture_rpc_tcase_add_test(tcase, "validate",
    9040             :                                    test_samr_ValidatePassword);
    9041             : 
    9042        2355 :         return suite;
    9043             : }

Generated by: LCOV version 1.13