LCOV - code coverage report
Current view: top level - source4/torture/rpc - samr.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 3133 4302 72.8 %
Date: 2024-06-13 04:01:37 Functions: 117 125 93.6 %

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

Generated by: LCOV version 1.13