LCOV - code coverage report
Current view: top level - source4/torture/rpc - samr.c (source / functions) Hit Total Coverage
Test: coverage report for master 2b515b7d Lines: 3364 4828 69.7 %
Date: 2024-02-28 12:06:22 Functions: 121 125 96.8 %

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

Generated by: LCOV version 1.14