LCOV - code coverage report
Current view: top level - source4/torture/rpc - lsa.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 2098 2937 71.4 %
Date: 2024-04-21 15:09:00 Functions: 71 73 97.3 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    test suite for lsa rpc operations
       4             : 
       5             :    Copyright (C) Andrew Tridgell 2003
       6             :    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2005
       7             : 
       8             :    This program is free software; you can redistribute it and/or modify
       9             :    it under the terms of the GNU General Public License as published by
      10             :    the Free Software Foundation; either version 3 of the License, or
      11             :    (at your option) any later version.
      12             : 
      13             :    This program is distributed in the hope that it will be useful,
      14             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :    GNU General Public License for more details.
      17             : 
      18             :    You should have received a copy of the GNU General Public License
      19             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      20             : */
      21             : 
      22             : #include "includes.h"
      23             : #include "torture/torture.h"
      24             : #include "libcli/cldap/cldap.h"
      25             : #include "../lib/tsocket/tsocket.h"
      26             : #include "librpc/gen_ndr/ndr_lsa_c.h"
      27             : #include "librpc/gen_ndr/netlogon.h"
      28             : #include "librpc/gen_ndr/ndr_drsblobs.h"
      29             : #include "librpc/gen_ndr/ndr_netlogon_c.h"
      30             : #include "lib/events/events.h"
      31             : #include "libcli/security/security.h"
      32             : #include "libcli/auth/libcli_auth.h"
      33             : #include "torture/rpc/torture_rpc.h"
      34             : #include "param/param.h"
      35             : #include "source4/auth/kerberos/kerberos.h"
      36             : #include "source4/auth/kerberos/kerberos_util.h"
      37             : #include "lib/util/util_net.h"
      38             : #include "libcli/resolve/resolve.h"
      39             : #include "source3/rpc_client/init_lsa.h"
      40             : #include "librpc/gen_ndr/ndr_lsa.h"
      41             : #include "librpc/rpc/dcerpc_lsa.h"
      42             : 
      43             : #include <gnutls/gnutls.h>
      44             : #include <gnutls/crypto.h>
      45             : 
      46             : #define TEST_MACHINENAME "lsatestmach"
      47             : #define TRUSTPW "12345678"
      48             : 
      49          27 : static bool test_OpenPolicy(struct dcerpc_binding_handle *b,
      50             :                             struct torture_context *tctx)
      51             : {
      52           0 :         struct lsa_ObjectAttribute attr;
      53           0 :         struct policy_handle handle;
      54           0 :         struct lsa_QosInfo qos;
      55           0 :         struct lsa_OpenPolicy r;
      56          27 :         uint16_t system_name = '\\';
      57             : 
      58          27 :         torture_comment(tctx, "\nTesting OpenPolicy\n");
      59             : 
      60          27 :         qos.len = 0;
      61          27 :         qos.impersonation_level = 2;
      62          27 :         qos.context_mode = 1;
      63          27 :         qos.effective_only = 0;
      64             : 
      65          27 :         attr.len = 0;
      66          27 :         attr.root_dir = NULL;
      67          27 :         attr.object_name = NULL;
      68          27 :         attr.attributes = 0;
      69          27 :         attr.sec_desc = NULL;
      70          27 :         attr.sec_qos = &qos;
      71             : 
      72          27 :         r.in.system_name = &system_name;
      73          27 :         r.in.attr = &attr;
      74          27 :         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
      75          27 :         r.out.handle = &handle;
      76             : 
      77          27 :         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenPolicy_r(b, tctx, &r),
      78             :                                    "OpenPolicy failed");
      79             : 
      80          27 :         torture_assert_ntstatus_ok(tctx,
      81             :                                    r.out.result,
      82             :                                    "OpenPolicy failed");
      83             : 
      84          27 :         return true;
      85             : }
      86             : 
      87           5 : static bool test_OpenPolicy_fail(struct dcerpc_binding_handle *b,
      88             :                                  struct torture_context *tctx)
      89             : {
      90           0 :         struct lsa_ObjectAttribute attr;
      91           0 :         struct policy_handle handle;
      92           0 :         struct lsa_QosInfo qos;
      93           0 :         struct lsa_OpenPolicy r;
      94           5 :         uint16_t system_name = '\\';
      95           0 :         NTSTATUS status;
      96             : 
      97           5 :         torture_comment(tctx, "\nTesting OpenPolicy_fail\n");
      98             : 
      99           5 :         qos.len = 0;
     100           5 :         qos.impersonation_level = 2;
     101           5 :         qos.context_mode = 1;
     102           5 :         qos.effective_only = 0;
     103             : 
     104           5 :         attr.len = 0;
     105           5 :         attr.root_dir = NULL;
     106           5 :         attr.object_name = NULL;
     107           5 :         attr.attributes = 0;
     108           5 :         attr.sec_desc = NULL;
     109           5 :         attr.sec_qos = &qos;
     110             : 
     111           5 :         r.in.system_name = &system_name;
     112           5 :         r.in.attr = &attr;
     113           5 :         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
     114           5 :         r.out.handle = &handle;
     115             : 
     116           5 :         status = dcerpc_lsa_OpenPolicy_r(b, tctx, &r);
     117           5 :         if (!NT_STATUS_IS_OK(status)) {
     118           5 :                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
     119           5 :                         torture_comment(tctx,
     120             :                                         "OpenPolicy correctly returned with "
     121             :                                         "status: %s\n",
     122             :                                         nt_errstr(status));
     123           5 :                         return true;
     124             :                 }
     125             : 
     126           0 :                 torture_assert_ntstatus_equal(tctx,
     127             :                                               status,
     128             :                                               NT_STATUS_ACCESS_DENIED,
     129             :                                               "OpenPolicy return value should "
     130             :                                               "be ACCESS_DENIED");
     131           0 :                 return true;
     132             :         }
     133             : 
     134           0 :         if (!NT_STATUS_IS_OK(r.out.result)) {
     135           0 :                 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) ||
     136           0 :                     NT_STATUS_EQUAL(r.out.result, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
     137           0 :                         torture_comment(tctx,
     138             :                                         "OpenPolicy correctly returned with "
     139             :                                         "result: %s\n",
     140             :                                         nt_errstr(r.out.result));
     141           0 :                         return true;
     142             :                 }
     143             :         }
     144             : 
     145           0 :         torture_assert_ntstatus_equal(tctx,
     146             :                                       r.out.result,
     147             :                                       NT_STATUS_OK,
     148             :                                       "OpenPolicy return value should be "
     149             :                                       "ACCESS_DENIED");
     150             : 
     151           0 :         return false;
     152             : }
     153             : 
     154             : 
     155        2397 : bool test_lsa_OpenPolicy2_ex(struct dcerpc_binding_handle *b,
     156             :                              struct torture_context *tctx,
     157             :                              struct policy_handle **handle,
     158             :                              NTSTATUS expected_status,
     159             :                              NTSTATUS expected_status2)
     160             : {
     161           9 :         struct lsa_ObjectAttribute attr;
     162           9 :         struct lsa_QosInfo qos;
     163           9 :         struct lsa_OpenPolicy2 r;
     164           9 :         NTSTATUS status;
     165             : 
     166        2397 :         torture_comment(tctx, "\nTesting OpenPolicy2\n");
     167             : 
     168        2397 :         *handle = talloc(tctx, struct policy_handle);
     169        2397 :         torture_assert(tctx, *handle != NULL, "talloc(tctx, struct policy_handle)");
     170             : 
     171        2397 :         qos.len = 0;
     172        2397 :         qos.impersonation_level = 2;
     173        2397 :         qos.context_mode = 1;
     174        2397 :         qos.effective_only = 0;
     175             : 
     176        2397 :         attr.len = 0;
     177        2397 :         attr.root_dir = NULL;
     178        2397 :         attr.object_name = NULL;
     179        2397 :         attr.attributes = 0;
     180        2397 :         attr.sec_desc = NULL;
     181        2397 :         attr.sec_qos = &qos;
     182             : 
     183        2397 :         r.in.system_name = "\\";
     184        2397 :         r.in.attr = &attr;
     185        2397 :         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
     186        2397 :         r.out.handle = *handle;
     187             : 
     188        2397 :         status = dcerpc_lsa_OpenPolicy2_r(b, tctx, &r);
     189             : 
     190             :         /* Allow two possible failure status codes */
     191        2397 :         if (!NT_STATUS_EQUAL(status, expected_status2)) {
     192          15 :                 torture_assert_ntstatus_equal(tctx, status,
     193             :                                               expected_status,
     194             :                                               "OpenPolicy2 failed");
     195             :         }
     196        2397 :         if (!NT_STATUS_IS_OK(expected_status) ||
     197        2382 :             !NT_STATUS_IS_OK(expected_status2)) {
     198          12 :                 return true;
     199             :         }
     200             : 
     201        2382 :         torture_assert_ntstatus_ok(tctx,
     202             :                                    r.out.result,
     203             :                                    "OpenPolicy2 failed");
     204             : 
     205        2376 :         return true;
     206             : }
     207             : 
     208             : 
     209        2382 : bool test_lsa_OpenPolicy2(struct dcerpc_binding_handle *b,
     210             :                           struct torture_context *tctx,
     211             :                           struct policy_handle **handle)
     212             : {
     213        4764 :         return test_lsa_OpenPolicy2_ex(b, tctx, handle,
     214        2382 :                                        NT_STATUS_OK, NT_STATUS_OK);
     215             : }
     216             : 
     217           5 : static bool test_OpenPolicy2_fail(struct dcerpc_binding_handle *b,
     218             :                                   struct torture_context *tctx)
     219             : {
     220           0 :         struct lsa_ObjectAttribute attr;
     221           0 :         struct policy_handle handle;
     222           0 :         struct lsa_QosInfo qos;
     223           0 :         struct lsa_OpenPolicy2 r;
     224           0 :         NTSTATUS status;
     225             : 
     226           5 :         torture_comment(tctx, "\nTesting OpenPolicy2_fail\n");
     227             : 
     228           5 :         qos.len = 0;
     229           5 :         qos.impersonation_level = 2;
     230           5 :         qos.context_mode = 1;
     231           5 :         qos.effective_only = 0;
     232             : 
     233           5 :         attr.len = 0;
     234           5 :         attr.root_dir = NULL;
     235           5 :         attr.object_name = NULL;
     236           5 :         attr.attributes = 0;
     237           5 :         attr.sec_desc = NULL;
     238           5 :         attr.sec_qos = &qos;
     239             : 
     240           5 :         r.in.system_name = "\\";
     241           5 :         r.in.attr = &attr;
     242           5 :         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
     243           5 :         r.out.handle = &handle;
     244             : 
     245           5 :         status = dcerpc_lsa_OpenPolicy2_r(b, tctx, &r);
     246           5 :         if (!NT_STATUS_IS_OK(status)) {
     247           5 :                 if (NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_DISCONNECTED) ||
     248           5 :                     NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
     249           5 :                         torture_comment(tctx,
     250             :                                         "OpenPolicy2 correctly returned with "
     251             :                                         "status: %s\n",
     252             :                                         nt_errstr(status));
     253           5 :                         return true;
     254             :                 }
     255             : 
     256           0 :                 torture_assert_ntstatus_equal(tctx,
     257             :                                               status,
     258             :                                               NT_STATUS_ACCESS_DENIED,
     259             :                                               "OpenPolicy2 return value should "
     260             :                                               "be ACCESS_DENIED");
     261           0 :                 return true;
     262             :         }
     263             : 
     264           0 :         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) ||
     265           0 :             NT_STATUS_EQUAL(r.out.result, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
     266           0 :                 torture_comment(tctx,
     267             :                                 "OpenPolicy2 correctly returned with "
     268             :                                 "result: %s\n",
     269             :                                 nt_errstr(r.out.result));
     270           0 :                 return true;
     271             :         }
     272             : 
     273           0 :         torture_fail(tctx,
     274             :                      "OpenPolicy2 return value should be "
     275             :                      "ACCESS_DENIED or RPC_PROTSEQ_NOT_SUPPORTED");
     276             : 
     277             :         return false;
     278             : }
     279             : 
     280          17 : bool test_lsa_OpenPolicy3_ex(struct dcerpc_binding_handle *b,
     281             :                              struct torture_context *tctx,
     282             :                              struct policy_handle **handle,
     283             :                              NTSTATUS expected_status,
     284             :                              NTSTATUS expected_status2)
     285             : {
     286          17 :         struct lsa_QosInfo qos = {
     287             :                 .impersonation_level = 2,
     288             :                 .context_mode = 1,
     289             :         };
     290          17 :         struct lsa_ObjectAttribute attr = {
     291             :                 .len = 0,
     292             :                 .sec_qos = &qos,
     293             :         };
     294          17 :         struct lsa_revision_info1 in_rinfo1 = {
     295             :                 .revision = 1,
     296             :                 .supported_features = LSA_FEATURE_TDO_AUTH_INFO_AES_CIPHER,
     297             :         };
     298          17 :         union lsa_revision_info in_rinfo = {
     299             :                 .info1 = in_rinfo1,
     300             :         };
     301          17 :         struct lsa_revision_info1 out_rinfo1 = {
     302             :                 .revision = 0,
     303             :         };
     304          17 :         union lsa_revision_info out_rinfo = {
     305             :                 .info1 = out_rinfo1,
     306             :         };
     307          17 :         uint32_t out_version = 0;
     308          17 :         struct lsa_OpenPolicy3 r = {
     309             :                 .in.system_name = "\\",
     310             :                 .in.attr = &attr,
     311             :                 .in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED,
     312             :                 .in.in_version = 1,
     313             :                 .in.in_revision_info = &in_rinfo,
     314             :                 .out.out_version = &out_version,
     315             :                 .out.out_revision_info = &out_rinfo,
     316             :         };
     317           0 :         NTSTATUS status;
     318             : 
     319          17 :         torture_comment(tctx, "\nTesting OpenPolicy3\n");
     320             : 
     321          17 :         *handle = talloc(tctx, struct policy_handle);
     322          17 :         torture_assert(tctx,
     323             :                        *handle != NULL,
     324             :                        "talloc(tctx, struct policy_handle)");
     325          17 :         r.out.handle = *handle;
     326             : 
     327          17 :         status = dcerpc_lsa_OpenPolicy3_r(b, tctx, &r);
     328             : 
     329             :         /* Allow two possible failure status codes */
     330          17 :         if (!NT_STATUS_EQUAL(status, expected_status2)) {
     331          17 :                 torture_assert_ntstatus_equal(tctx,
     332             :                                               status,
     333             :                                               expected_status,
     334             :                                               "OpenPolicy3 failed");
     335             :         }
     336          17 :         if (!NT_STATUS_IS_OK(expected_status) ||
     337          17 :             !NT_STATUS_IS_OK(expected_status2)) {
     338          17 :                 return true;
     339             :         }
     340             : 
     341           0 :         torture_assert_ntstatus_ok(tctx, r.out.result, "OpenPolicy3 failed");
     342           0 :         torture_assert_int_equal(tctx, out_version, 1, "Invalid out_version");
     343           0 :         torture_assert_int_equal(tctx,
     344             :                                  out_rinfo1.revision,
     345             :                                  1,
     346             :                                  "Invalid revision");
     347           0 :         torture_assert_int_equal(tctx,
     348             :                                  out_rinfo1.supported_features,
     349             :                                  LSA_FEATURE_TDO_AUTH_INFO_AES_CIPHER,
     350             :                                  "Invalid supported feature set");
     351             : 
     352           0 :         return true;
     353             : }
     354             : 
     355          17 : bool test_lsa_OpenPolicy3(struct dcerpc_binding_handle *b,
     356             :                           struct torture_context *tctx,
     357             :                           struct policy_handle **handle)
     358             : {
     359          34 :         return test_lsa_OpenPolicy3_ex(b,
     360             :                                        tctx,
     361             :                                        handle,
     362          17 :                                        NT_STATUS_OK,
     363          17 :                                        NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE);
     364             : }
     365             : 
     366           5 : static bool test_OpenPolicy3_fail(struct dcerpc_binding_handle *b,
     367             :                                   struct torture_context *tctx)
     368             : {
     369           5 :         struct policy_handle handle = {
     370             :                 .handle_type = 0,
     371             :         };
     372           5 :         struct lsa_QosInfo qos = {
     373             :                 .impersonation_level = 2,
     374             :                 .context_mode = 1,
     375             :         };
     376           5 :         struct lsa_ObjectAttribute attr = {
     377             :                 .len = 0,
     378             :                 .sec_qos = &qos,
     379             :         };
     380           5 :         struct lsa_revision_info1 in_rinfo1 = {
     381             :                 .revision = 0,
     382             :                 .supported_features = 0,
     383             :         };
     384           5 :         union lsa_revision_info in_rinfo = {
     385             :                 .info1 = in_rinfo1,
     386             :         };
     387           5 :         struct lsa_revision_info1 out_rinfo1 = {
     388             :                 .revision = 0,
     389             :         };
     390           5 :         union lsa_revision_info out_rinfo = {
     391             :                 .info1 = out_rinfo1,
     392             :         };
     393           5 :         uint32_t out_version = 0;
     394           5 :         struct lsa_OpenPolicy3 r = {
     395             :                 .in.system_name = "\\",
     396             :                 .in.attr = &attr,
     397             :                 .in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED,
     398             :                 .in.in_version = 1,
     399             :                 .in.in_revision_info = &in_rinfo,
     400             :                 .out.out_version = &out_version,
     401             :                 .out.out_revision_info = &out_rinfo,
     402             :                 .out.handle = &handle,
     403             :         };
     404           0 :         NTSTATUS status;
     405             : 
     406           5 :         torture_comment(tctx, "\nTesting OpenPolicy3_fail\n");
     407             : 
     408           5 :         status = dcerpc_lsa_OpenPolicy3_r(b, tctx, &r);
     409           5 :         if (!NT_STATUS_IS_OK(status)) {
     410           5 :                 if (NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_DISCONNECTED) ||
     411           5 :                     NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) ||
     412           0 :                     NT_STATUS_EQUAL(status,
     413             :                                     NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) {
     414           5 :                         torture_comment(tctx,
     415             :                                         "OpenPolicy3 correctly returned with "
     416             :                                         "status: %s\n",
     417             :                                         nt_errstr(status));
     418           5 :                         return true;
     419             :                 }
     420             : 
     421           0 :                 torture_assert_ntstatus_equal(tctx,
     422             :                                               status,
     423             :                                               NT_STATUS_ACCESS_DENIED,
     424             :                                               "OpenPolicy3 return value should "
     425             :                                               "be ACCESS_DENIED or CONNECTION_DISCONNECTED");
     426           0 :                 return true;
     427             :         }
     428             : 
     429           0 :         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) ||
     430           0 :             NT_STATUS_EQUAL(r.out.result,
     431             :                             NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
     432           0 :                 torture_comment(tctx,
     433             :                                 "OpenPolicy3 correctly returned with "
     434             :                                 "result: %s\n",
     435             :                                 nt_errstr(r.out.result));
     436           0 :                 return true;
     437             :         }
     438             : 
     439           0 :         torture_fail(tctx,
     440             :                      "OpenPolicy3 return value should be "
     441             :                      "ACCESS_DENIED or RPC_PROTSEQ_NOT_SUPPORTED");
     442             : 
     443             :         return false;
     444             : }
     445             : 
     446         155 : static bool test_LookupNames(struct dcerpc_binding_handle *b,
     447             :                              struct torture_context *tctx,
     448             :                              struct policy_handle *handle,
     449             :                              enum lsa_LookupNamesLevel level,
     450             :                              struct lsa_TransNameArray *tnames)
     451             : {
     452           0 :         struct lsa_LookupNames r;
     453           0 :         struct lsa_TransSidArray sids;
     454         155 :         struct lsa_RefDomainList *domains = NULL;
     455           0 :         struct lsa_String *names;
     456         155 :         uint32_t count = 0;
     457           0 :         int i;
     458           0 :         uint32_t *input_idx;
     459             : 
     460         155 :         torture_comment(tctx, "\nTesting LookupNames with %d names\n", tnames->count);
     461             : 
     462         155 :         sids.count = 0;
     463         155 :         sids.sids = NULL;
     464             : 
     465             : 
     466         155 :         r.in.num_names = 0;
     467             : 
     468         155 :         input_idx = talloc_array(tctx, uint32_t, tnames->count);
     469         155 :         names = talloc_array(tctx, struct lsa_String, tnames->count);
     470             : 
     471        2345 :         for (i=0;i<tnames->count;i++) {
     472        2190 :                 if (tnames->names[i].sid_type != SID_NAME_UNKNOWN) {
     473        2190 :                         init_lsa_String(&names[r.in.num_names], tnames->names[i].name.string);
     474        2190 :                         input_idx[r.in.num_names] = i;
     475        2190 :                         r.in.num_names++;
     476             :                 }
     477             :         }
     478             : 
     479         155 :         r.in.handle = handle;
     480         155 :         r.in.names = names;
     481         155 :         r.in.sids = &sids;
     482         155 :         r.in.level = level;
     483         155 :         r.in.count = &count;
     484         155 :         r.out.count = &count;
     485         155 :         r.out.sids = &sids;
     486         155 :         r.out.domains = &domains;
     487             : 
     488         155 :         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupNames_r(b, tctx, &r),
     489             :                                    "LookupNames failed");
     490         155 :         if (NT_STATUS_EQUAL(r.out.result, STATUS_SOME_UNMAPPED) ||
     491         155 :             NT_STATUS_EQUAL(r.out.result, NT_STATUS_NONE_MAPPED)) {
     492           0 :                 for (i=0;i< r.in.num_names;i++) {
     493           0 :                         if (i < count && sids.sids[i].sid_type == SID_NAME_UNKNOWN) {
     494           0 :                                 torture_comment(tctx, "LookupName of %s was unmapped\n",
     495           0 :                                        tnames->names[i].name.string);
     496           0 :                         } else if (i >=count) {
     497           0 :                                 torture_comment(tctx, "LookupName of %s failed to return a result\n",
     498           0 :                                        tnames->names[i].name.string);
     499             :                         }
     500             :                 }
     501           0 :                 torture_assert_ntstatus_ok(tctx, r.out.result,
     502             :                                            "LookupNames failed");
     503         155 :         } else if (!NT_STATUS_IS_OK(r.out.result)) {
     504           0 :                 torture_assert_ntstatus_ok(tctx, r.out.result,
     505             :                                            "LookupNames failed");
     506             :         }
     507             : 
     508        2345 :         for (i=0;i< r.in.num_names;i++) {
     509        2190 :                 torture_assert(tctx, (i < count),
     510             :                                talloc_asprintf(tctx,
     511             :                                "LookupName of %s failed to return a result\n",
     512             :                                tnames->names[input_idx[i]].name.string));
     513             : 
     514        2190 :                 torture_assert_int_equal(tctx,
     515             :                                          sids.sids[i].sid_type,
     516             :                                          tnames->names[input_idx[i]].sid_type,
     517             :                                          talloc_asprintf(tctx,
     518             :                                          "LookupName of %s got unexpected name type: %s\n",
     519             :                                          tnames->names[input_idx[i]].name.string,
     520             :                                          sid_type_lookup(sids.sids[i].sid_type)));
     521        2190 :                 if (sids.sids[i].sid_type != SID_NAME_DOMAIN) {
     522        1988 :                         continue;
     523             :                 }
     524         202 :                 torture_assert_int_equal(tctx,
     525             :                                          sids.sids[i].rid,
     526             :                                          UINT32_MAX,
     527             :                                          talloc_asprintf(tctx,
     528             :                                          "LookupName of %s got unexpected rid: %d\n",
     529             :                                          tnames->names[input_idx[i]].name.string,
     530             :                                          sids.sids[i].rid));
     531             :         }
     532             : 
     533         155 :         return true;
     534             : }
     535             : 
     536           5 : static bool test_LookupNames_bogus(struct dcerpc_binding_handle *b,
     537             :                                    struct torture_context *tctx,
     538             :                                    struct policy_handle *handle,
     539             :                                    enum lsa_LookupNamesLevel level)
     540             : {
     541           0 :         struct lsa_LookupNames r;
     542           0 :         struct lsa_TransSidArray sids;
     543           5 :         struct lsa_RefDomainList *domains = NULL;
     544           0 :         struct lsa_String names[1];
     545           5 :         uint32_t count = 0;
     546             : 
     547           5 :         torture_comment(tctx, "\nTesting LookupNames with bogus name\n");
     548             : 
     549           5 :         sids.count = 0;
     550           5 :         sids.sids = NULL;
     551             : 
     552           5 :         init_lsa_String(&names[0], "NT AUTHORITY\\BOGUS");
     553             : 
     554           5 :         r.in.handle = handle;
     555           5 :         r.in.num_names = 1;
     556           5 :         r.in.names = names;
     557           5 :         r.in.sids = &sids;
     558           5 :         r.in.level = level;
     559           5 :         r.in.count = &count;
     560           5 :         r.out.count = &count;
     561           5 :         r.out.sids = &sids;
     562           5 :         r.out.domains = &domains;
     563             : 
     564           5 :         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupNames_r(b, tctx, &r),
     565             :                                    "LookupNames bogus failed");
     566           5 :         if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_NONE_MAPPED)) {
     567           0 :                 torture_comment(tctx, "LookupNames failed - %s\n",
     568             :                                 nt_errstr(r.out.result));
     569           0 :                 return false;
     570             :         }
     571             : 
     572           5 :         torture_comment(tctx, "\n");
     573             : 
     574           5 :         return true;
     575             : }
     576             : 
     577           5 : static bool test_LookupNames_NULL(struct dcerpc_binding_handle *b,
     578             :                                   struct torture_context *tctx,
     579             :                                   struct policy_handle *handle,
     580             :                                   enum lsa_LookupNamesLevel level)
     581             : {
     582           0 :         struct lsa_LookupNames r;
     583           0 :         struct lsa_TransSidArray sids;
     584           5 :         struct lsa_RefDomainList *domains = NULL;
     585           0 :         struct lsa_String names[1];
     586           5 :         uint32_t count = 0;
     587             : 
     588           5 :         torture_comment(tctx, "\nTesting LookupNames with NULL name\n");
     589             : 
     590           5 :         sids.count = 0;
     591           5 :         sids.sids = NULL;
     592             : 
     593           5 :         names[0].string = NULL;
     594             : 
     595           5 :         r.in.handle = handle;
     596           5 :         r.in.num_names = 1;
     597           5 :         r.in.names = names;
     598           5 :         r.in.sids = &sids;
     599           5 :         r.in.level = level;
     600           5 :         r.in.count = &count;
     601           5 :         r.out.count = &count;
     602           5 :         r.out.sids = &sids;
     603           5 :         r.out.domains = &domains;
     604             : 
     605             :         /* nt4 returns NT_STATUS_NONE_MAPPED with sid_type
     606             :          * SID_NAME_UNKNOWN, rid 0, and sid_index -1;
     607             :          *
     608             :          * w2k3/w2k8 return NT_STATUS_OK with sid_type
     609             :          * SID_NAME_DOMAIN, rid -1 and sid_index 0 and BUILTIN domain
     610             :          */
     611             : 
     612           5 :         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupNames_r(b, tctx, &r),
     613             :                 "LookupNames with NULL name failed");
     614           5 :         torture_assert_ntstatus_ok(tctx, r.out.result,
     615             :                 "LookupNames with NULL name failed");
     616             : 
     617           5 :         torture_comment(tctx, "\n");
     618             : 
     619           5 :         return true;
     620             : }
     621             : 
     622           5 : static bool test_LookupNames_wellknown(struct dcerpc_binding_handle *b,
     623             :                                        struct torture_context *tctx,
     624             :                                        struct policy_handle *handle,
     625             :                                        enum lsa_LookupNamesLevel level)
     626             : {
     627           0 :         struct lsa_TranslatedName name;
     628           0 :         struct lsa_TransNameArray tnames;
     629           5 :         bool ret = true;
     630             : 
     631           5 :         torture_comment(tctx, "Testing LookupNames with well known names\n");
     632             : 
     633           5 :         tnames.names = &name;
     634           5 :         tnames.count = 1;
     635           5 :         name.name.string = "NT AUTHORITY\\SYSTEM";
     636           5 :         name.sid_type = SID_NAME_WKN_GRP;
     637           5 :         ret &= test_LookupNames(b, tctx, handle, level, &tnames);
     638             : 
     639           5 :         name.name.string = "NT AUTHORITY\\ANONYMOUS LOGON";
     640           5 :         name.sid_type = SID_NAME_WKN_GRP;
     641           5 :         ret &= test_LookupNames(b, tctx, handle, level, &tnames);
     642             : 
     643           5 :         name.name.string = "NT AUTHORITY\\Authenticated Users";
     644           5 :         name.sid_type = SID_NAME_WKN_GRP;
     645           5 :         ret &= test_LookupNames(b, tctx, handle, level, &tnames);
     646             : 
     647             : #if 0
     648             :         name.name.string = "NT AUTHORITY";
     649             :         ret &= test_LookupNames(b, tctx, handle, level, &tnames);
     650             : 
     651             :         name.name.string = "NT AUTHORITY\\";
     652             :         ret &= test_LookupNames(b, tctx, handle, level, &tnames);
     653             : #endif
     654             : 
     655           5 :         name.name.string = "BUILTIN\\";
     656           5 :         name.sid_type = SID_NAME_DOMAIN;
     657           5 :         ret &= test_LookupNames(b, tctx, handle, level, &tnames);
     658             : 
     659           5 :         name.name.string = "BUILTIN\\Administrators";
     660           5 :         name.sid_type = SID_NAME_ALIAS;
     661           5 :         ret &= test_LookupNames(b, tctx, handle, level, &tnames);
     662             : 
     663           5 :         name.name.string = "SYSTEM";
     664           5 :         name.sid_type = SID_NAME_WKN_GRP;
     665           5 :         ret &= test_LookupNames(b, tctx, handle, level, &tnames);
     666             : 
     667           5 :         name.name.string = "Everyone";
     668           5 :         name.sid_type = SID_NAME_WKN_GRP;
     669           5 :         ret &= test_LookupNames(b, tctx, handle, level, &tnames);
     670           5 :         return ret;
     671             : }
     672             : 
     673          10 : static bool test_LookupNames2(struct dcerpc_binding_handle *b,
     674             :                               struct torture_context *tctx,
     675             :                               struct policy_handle *handle,
     676             :                               enum lsa_LookupNamesLevel level,
     677             :                               struct lsa_TransNameArray2 *tnames,
     678             :                               bool check_result)
     679             : {
     680           0 :         struct lsa_LookupNames2 r;
     681           0 :         struct lsa_TransSidArray2 sids;
     682          10 :         struct lsa_RefDomainList *domains = NULL;
     683           0 :         struct lsa_String *names;
     684           0 :         uint32_t *input_idx;
     685          10 :         uint32_t count = 0;
     686           0 :         int i;
     687             : 
     688          10 :         torture_comment(tctx, "\nTesting LookupNames2 with %d names\n", tnames->count);
     689             : 
     690          10 :         sids.count = 0;
     691          10 :         sids.sids = NULL;
     692             : 
     693          10 :         r.in.num_names = 0;
     694             : 
     695          10 :         input_idx = talloc_array(tctx, uint32_t, tnames->count);
     696          10 :         names = talloc_array(tctx, struct lsa_String, tnames->count);
     697             : 
     698          45 :         for (i=0;i<tnames->count;i++) {
     699          35 :                 if (tnames->names[i].sid_type != SID_NAME_UNKNOWN) {
     700          35 :                         init_lsa_String(&names[r.in.num_names], tnames->names[i].name.string);
     701          35 :                         input_idx[r.in.num_names] = i;
     702          35 :                         r.in.num_names++;
     703             :                 }
     704             :         }
     705             : 
     706          10 :         r.in.handle = handle;
     707          10 :         r.in.names = names;
     708          10 :         r.in.sids = &sids;
     709          10 :         r.in.level = level;
     710          10 :         r.in.count = &count;
     711          10 :         r.in.lookup_options = 0;
     712          10 :         r.in.client_revision = 0;
     713          10 :         r.out.count = &count;
     714          10 :         r.out.sids = &sids;
     715          10 :         r.out.domains = &domains;
     716             : 
     717          10 :         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupNames2_r(b, tctx, &r),
     718             :                 "LookupNames2 failed");
     719          10 :         torture_assert_ntstatus_ok(tctx, r.out.result, "LookupNames2 failed");
     720             : 
     721          10 :         if (check_result) {
     722           5 :                 torture_assert_int_equal(tctx, count, sids.count,
     723             :                         "unexpected number of results returned");
     724           5 :                 if (sids.count > 0) {
     725           5 :                         torture_assert(tctx, sids.sids, "invalid sid buffer");
     726             :                 }
     727             :         }
     728             : 
     729          10 :         torture_comment(tctx, "\n");
     730             : 
     731          10 :         return true;
     732             : }
     733             : 
     734             : 
     735          10 : static bool test_LookupNames3(struct dcerpc_binding_handle *b,
     736             :                               struct torture_context *tctx,
     737             :                               struct policy_handle *handle,
     738             :                               enum lsa_LookupNamesLevel level,
     739             :                               struct lsa_TransNameArray2 *tnames,
     740             :                               bool check_result)
     741             : {
     742           0 :         struct lsa_LookupNames3 r;
     743           0 :         struct lsa_TransSidArray3 sids;
     744          10 :         struct lsa_RefDomainList *domains = NULL;
     745           0 :         struct lsa_String *names;
     746          10 :         uint32_t count = 0;
     747           0 :         int i;
     748           0 :         uint32_t *input_idx;
     749             : 
     750          10 :         torture_comment(tctx, "\nTesting LookupNames3 with %d names\n", tnames->count);
     751             : 
     752          10 :         sids.count = 0;
     753          10 :         sids.sids = NULL;
     754             : 
     755          10 :         r.in.num_names = 0;
     756             : 
     757          10 :         input_idx = talloc_array(tctx, uint32_t, tnames->count);
     758          10 :         names = talloc_array(tctx, struct lsa_String, tnames->count);
     759          45 :         for (i=0;i<tnames->count;i++) {
     760          35 :                 if (tnames->names[i].sid_type != SID_NAME_UNKNOWN) {
     761          35 :                         init_lsa_String(&names[r.in.num_names], tnames->names[i].name.string);
     762          35 :                         input_idx[r.in.num_names] = i;
     763          35 :                         r.in.num_names++;
     764             :                 }
     765             :         }
     766             : 
     767          10 :         r.in.handle = handle;
     768          10 :         r.in.names = names;
     769          10 :         r.in.sids = &sids;
     770          10 :         r.in.level = level;
     771          10 :         r.in.count = &count;
     772          10 :         r.in.lookup_options = 0;
     773          10 :         r.in.client_revision = 0;
     774          10 :         r.out.count = &count;
     775          10 :         r.out.sids = &sids;
     776          10 :         r.out.domains = &domains;
     777             : 
     778          10 :         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupNames3_r(b, tctx, &r),
     779             :                 "LookupNames3 failed");
     780          10 :         torture_assert_ntstatus_ok(tctx, r.out.result,
     781             :                 "LookupNames3 failed");
     782             : 
     783          10 :         if (check_result) {
     784           5 :                 torture_assert_int_equal(tctx, count, sids.count,
     785             :                         "unexpected number of results returned");
     786           5 :                 if (sids.count > 0) {
     787           5 :                         torture_assert(tctx, sids.sids, "invalid sid buffer");
     788             :                 }
     789             :         }
     790             : 
     791          10 :         torture_comment(tctx, "\n");
     792             : 
     793          10 :         return true;
     794             : }
     795             : 
     796         552 : static bool test_LookupNames4(struct dcerpc_binding_handle *b,
     797             :                               struct torture_context *tctx,
     798             :                               enum lsa_LookupNamesLevel level,
     799             :                               struct lsa_TransNameArray2 *tnames,
     800             :                               bool check_result)
     801             : {
     802          96 :         struct lsa_LookupNames4 r;
     803          96 :         struct lsa_TransSidArray3 sids;
     804         552 :         struct lsa_RefDomainList *domains = NULL;
     805          96 :         struct lsa_String *names;
     806         552 :         uint32_t count = 0;
     807          96 :         int i;
     808          96 :         uint32_t *input_idx;
     809             : 
     810         552 :         torture_comment(tctx, "\nTesting LookupNames4 with %d names\n", tnames->count);
     811             : 
     812         552 :         sids.count = 0;
     813         552 :         sids.sids = NULL;
     814             : 
     815         552 :         r.in.num_names = 0;
     816             : 
     817         552 :         input_idx = talloc_array(tctx, uint32_t, tnames->count);
     818         552 :         names = talloc_array(tctx, struct lsa_String, tnames->count);
     819       28248 :         for (i=0;i<tnames->count;i++) {
     820       27600 :                 if (tnames->names[i].sid_type != SID_NAME_UNKNOWN) {
     821       27600 :                         init_lsa_String(&names[r.in.num_names], tnames->names[i].name.string);
     822       27600 :                         input_idx[r.in.num_names] = i;
     823       27600 :                         r.in.num_names++;
     824             :                 }
     825             :         }
     826             : 
     827         552 :         r.in.num_names = tnames->count;
     828         552 :         r.in.names = names;
     829         552 :         r.in.sids = &sids;
     830         552 :         r.in.level = level;
     831         552 :         r.in.count = &count;
     832         552 :         r.in.lookup_options = 0;
     833         552 :         r.in.client_revision = 0;
     834         552 :         r.out.count = &count;
     835         552 :         r.out.sids = &sids;
     836         552 :         r.out.domains = &domains;
     837             : 
     838         552 :         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupNames4_r(b, tctx, &r),
     839             :                 "LookupNames4 failed");
     840             : 
     841         552 :         if (!NT_STATUS_IS_OK(r.out.result)) {
     842         276 :                 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NONE_MAPPED)) {
     843         276 :                         torture_comment(tctx,
     844             :                                         "LookupNames4 failed: %s - not considered as an error",
     845             :                                         nt_errstr(r.out.result));
     846             : 
     847         276 :                         return true;
     848             :                 }
     849             :         }
     850         276 :         torture_assert_ntstatus_ok(tctx,
     851             :                                    r.out.result,
     852             :                                    "LookupNames4 failed");
     853             : 
     854         276 :         if (check_result) {
     855         276 :                 torture_assert_int_equal(tctx, count, sids.count,
     856             :                         "unexpected number of results returned");
     857         276 :                 if (sids.count > 0) {
     858         276 :                         torture_assert(tctx, sids.sids, "invalid sid buffer");
     859             :                 }
     860             :         }
     861             : 
     862         276 :         torture_comment(tctx, "\n");
     863             : 
     864         276 :         return true;
     865             : }
     866             : 
     867          16 : static bool test_LookupNames4_fail(struct dcerpc_binding_handle *b,
     868             :                                    struct torture_context *tctx,
     869             :                                    enum lsa_LookupNamesLevel level)
     870             : {
     871           0 :         struct lsa_LookupNames4 r;
     872           0 :         struct lsa_TransSidArray3 sids;
     873          16 :         struct lsa_RefDomainList *domains = NULL;
     874          16 :         struct lsa_String *names = NULL;
     875          16 :         uint32_t count = 0;
     876           0 :         NTSTATUS status;
     877             : 
     878          16 :         torture_comment(tctx, "\nTesting LookupNames4_fail");
     879             : 
     880          16 :         sids.count = 0;
     881          16 :         sids.sids = NULL;
     882             : 
     883          16 :         r.in.num_names = 0;
     884             : 
     885          16 :         r.in.num_names = count;
     886          16 :         r.in.names = names;
     887          16 :         r.in.sids = &sids;
     888          16 :         r.in.level = level;
     889          16 :         r.in.count = &count;
     890          16 :         r.in.lookup_options = 0;
     891          16 :         r.in.client_revision = 0;
     892          16 :         r.out.count = &count;
     893          16 :         r.out.sids = &sids;
     894          16 :         r.out.domains = &domains;
     895             : 
     896          16 :         status = dcerpc_lsa_LookupNames4_r(b, tctx, &r);
     897          16 :         if (!NT_STATUS_IS_OK(status)) {
     898          16 :                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) ||
     899           0 :                     NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_DISCONNECTED)) {
     900          16 :                         torture_comment(tctx,
     901             :                                         "LookupNames4 correctly returned with "
     902             :                                         "status: %s\n",
     903             :                                         nt_errstr(status));
     904          16 :                         return true;
     905             :                 }
     906             : 
     907           0 :                 torture_assert_ntstatus_equal(tctx,
     908             :                                               status,
     909             :                                               NT_STATUS_ACCESS_DENIED,
     910             :                                               "LookupNames4 return value should "
     911             :                                               "be ACCESS_DENIED");
     912           0 :                 return true;
     913             :         }
     914             : 
     915           0 :         if (!NT_STATUS_IS_OK(r.out.result)) {
     916           0 :                 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) ||
     917           0 :                     NT_STATUS_EQUAL(r.out.result, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
     918           0 :                         torture_comment(tctx,
     919             :                                         "LookupSids3 correctly returned with "
     920             :                                         "result: %s\n",
     921             :                                         nt_errstr(r.out.result));
     922           0 :                         return true;
     923             :                 }
     924             :         }
     925             : 
     926           0 :         torture_fail(tctx,
     927             :                      "LookupNames4 return value should be "
     928             :                      "ACCESS_DENIED or RPC_PROTSEQ_NOT_SUPPORTED");
     929             : 
     930             :         return false;
     931             : }
     932             : 
     933             : 
     934           5 : static bool test_LookupSids(struct dcerpc_binding_handle *b,
     935             :                             struct torture_context *tctx,
     936             :                             struct policy_handle *handle,
     937             :                             enum lsa_LookupNamesLevel level,
     938             :                             struct lsa_SidArray *sids)
     939             : {
     940           0 :         struct lsa_LookupSids r;
     941           0 :         struct lsa_TransNameArray names;
     942           5 :         struct lsa_RefDomainList *domains = NULL;
     943           5 :         uint32_t count = sids->num_sids;
     944             : 
     945           5 :         torture_comment(tctx, "\nTesting LookupSids\n");
     946             : 
     947           5 :         names.count = 0;
     948           5 :         names.names = NULL;
     949             : 
     950           5 :         r.in.handle = handle;
     951           5 :         r.in.sids = sids;
     952           5 :         r.in.names = &names;
     953           5 :         r.in.level = level;
     954           5 :         r.in.count = &count;
     955           5 :         r.out.count = &count;
     956           5 :         r.out.names = &names;
     957           5 :         r.out.domains = &domains;
     958             : 
     959           5 :         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupSids_r(b, tctx, &r),
     960             :                 "LookupSids failed");
     961           5 :         if (!NT_STATUS_EQUAL(r.out.result, STATUS_SOME_UNMAPPED)) {
     962           5 :                 torture_assert_ntstatus_ok(tctx, r.out.result,
     963             :                         "LookupSids failed");
     964             :         }
     965             : 
     966           5 :         torture_comment(tctx, "\n");
     967             : 
     968           5 :         if (!test_LookupNames(b, tctx, handle, level, &names)) {
     969           0 :                 return false;
     970             :         }
     971             : 
     972           5 :         return true;
     973             : }
     974             : 
     975             : 
     976           5 : static bool test_LookupSids2(struct dcerpc_binding_handle *b,
     977             :                             struct torture_context *tctx,
     978             :                             struct policy_handle *handle,
     979             :                             enum lsa_LookupNamesLevel level,
     980             :                             struct lsa_SidArray *sids)
     981             : {
     982           0 :         struct lsa_LookupSids2 r;
     983           0 :         struct lsa_TransNameArray2 names;
     984           5 :         struct lsa_RefDomainList *domains = NULL;
     985           5 :         uint32_t count = sids->num_sids;
     986             : 
     987           5 :         torture_comment(tctx, "\nTesting LookupSids2\n");
     988             : 
     989           5 :         names.count = 0;
     990           5 :         names.names = NULL;
     991             : 
     992           5 :         r.in.handle = handle;
     993           5 :         r.in.sids = sids;
     994           5 :         r.in.names = &names;
     995           5 :         r.in.level = level;
     996           5 :         r.in.count = &count;
     997           5 :         r.in.lookup_options = 0;
     998           5 :         r.in.client_revision = 0;
     999           5 :         r.out.count = &count;
    1000           5 :         r.out.names = &names;
    1001           5 :         r.out.domains = &domains;
    1002             : 
    1003           5 :         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupSids2_r(b, tctx, &r),
    1004             :                 "LookupSids2 failed");
    1005           5 :         if (!NT_STATUS_IS_OK(r.out.result) &&
    1006           0 :             !NT_STATUS_EQUAL(r.out.result, STATUS_SOME_UNMAPPED)) {
    1007           0 :                 torture_comment(tctx, "LookupSids2 failed - %s\n",
    1008             :                                 nt_errstr(r.out.result));
    1009           0 :                 return false;
    1010             :         }
    1011             : 
    1012           5 :         torture_comment(tctx, "\n");
    1013             : 
    1014           5 :         if (!test_LookupNames2(b, tctx, handle, level, &names, false)) {
    1015           0 :                 return false;
    1016             :         }
    1017             : 
    1018           5 :         if (!test_LookupNames3(b, tctx, handle, level, &names, false)) {
    1019           0 :                 return false;
    1020             :         }
    1021             : 
    1022           5 :         return true;
    1023             : }
    1024             : 
    1025         276 : static bool test_LookupSids3(struct dcerpc_binding_handle *b,
    1026             :                             struct torture_context *tctx,
    1027             :                             enum lsa_LookupNamesLevel level,
    1028             :                             struct lsa_SidArray *sids)
    1029             : {
    1030          48 :         struct lsa_LookupSids3 r;
    1031          48 :         struct lsa_TransNameArray2 names;
    1032         276 :         struct lsa_RefDomainList *domains = NULL;
    1033         276 :         uint32_t count = sids->num_sids;
    1034             : 
    1035         276 :         torture_comment(tctx, "\nTesting LookupSids3\n");
    1036             : 
    1037         276 :         names.count = 0;
    1038         276 :         names.names = NULL;
    1039             : 
    1040         276 :         r.in.sids = sids;
    1041         276 :         r.in.names = &names;
    1042         276 :         r.in.level = level;
    1043         276 :         r.in.count = &count;
    1044         276 :         r.in.lookup_options = 0;
    1045         276 :         r.in.client_revision = 0;
    1046         276 :         r.out.domains = &domains;
    1047         276 :         r.out.count = &count;
    1048         276 :         r.out.names = &names;
    1049             : 
    1050         276 :         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupSids3_r(b, tctx, &r),
    1051             :                 "LookupSids3 failed");
    1052             : 
    1053         276 :         if (!NT_STATUS_IS_OK(r.out.result)) {
    1054           0 :                 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NONE_MAPPED)) {
    1055           0 :                         torture_comment(tctx,
    1056             :                                         "LookupSids3 failed: %s - not considered as an error",
    1057             :                                         nt_errstr(r.out.result));
    1058             : 
    1059           0 :                         return true;
    1060             :                 }
    1061             : 
    1062           0 :                 torture_assert_ntstatus_ok(tctx,
    1063             :                                            r.out.result,
    1064             :                                            "LookupSids3 failed");
    1065             : 
    1066           0 :                 return false;
    1067             :         }
    1068             : 
    1069         276 :         torture_comment(tctx, "\n");
    1070             : 
    1071         276 :         if (!test_LookupNames4(b, tctx, level, &names, true)) {
    1072           0 :                 return false;
    1073             :         }
    1074             : 
    1075         228 :         return true;
    1076             : }
    1077             : 
    1078          16 : static bool test_LookupSids3_fail(struct dcerpc_binding_handle *b,
    1079             :                                   struct torture_context *tctx,
    1080             :                                   enum lsa_LookupNamesLevel level,
    1081             :                                   struct lsa_SidArray *sids)
    1082             : {
    1083           0 :         struct lsa_LookupSids3 r;
    1084           0 :         struct lsa_TransNameArray2 names;
    1085          16 :         struct lsa_RefDomainList *domains = NULL;
    1086          16 :         uint32_t count = sids->num_sids;
    1087           0 :         NTSTATUS status;
    1088             : 
    1089          16 :         torture_comment(tctx, "\nTesting LookupSids3\n");
    1090             : 
    1091          16 :         names.count = 0;
    1092          16 :         names.names = NULL;
    1093             : 
    1094          16 :         r.in.sids = sids;
    1095          16 :         r.in.names = &names;
    1096          16 :         r.in.level = level;
    1097          16 :         r.in.count = &count;
    1098          16 :         r.in.lookup_options = 0;
    1099          16 :         r.in.client_revision = 0;
    1100          16 :         r.out.domains = &domains;
    1101          16 :         r.out.count = &count;
    1102          16 :         r.out.names = &names;
    1103             : 
    1104          16 :         status = dcerpc_lsa_LookupSids3_r(b, tctx, &r);
    1105          16 :         if (!NT_STATUS_IS_OK(status)) {
    1106          16 :                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) ||
    1107           0 :                     NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_DISCONNECTED)) {
    1108          16 :                         torture_comment(tctx,
    1109             :                                         "LookupSids3 correctly returned with "
    1110             :                                         "status: %s\n",
    1111             :                                         nt_errstr(status));
    1112          16 :                         return true;
    1113             :                 }
    1114             : 
    1115           0 :                 torture_assert_ntstatus_equal(tctx,
    1116             :                                               status,
    1117             :                                               NT_STATUS_ACCESS_DENIED,
    1118             :                                               "LookupSids3 return value should "
    1119             :                                               "be ACCESS_DENIED");
    1120           0 :                 return true;
    1121             :         }
    1122             : 
    1123           0 :         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) ||
    1124           0 :             NT_STATUS_EQUAL(r.out.result, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
    1125           0 :                 torture_comment(tctx,
    1126             :                                 "LookupNames4 correctly returned with "
    1127             :                                 "result: %s\n",
    1128             :                                 nt_errstr(r.out.result));
    1129           0 :                 return true;
    1130             :         }
    1131             : 
    1132           0 :         torture_fail(tctx,
    1133             :                      "LookupSids3 return value should be "
    1134             :                      "ACCESS_DENIED or RPC_PROTSEQ_NOT_SUPPORTED");
    1135             : 
    1136             :         return false;
    1137             : }
    1138             : 
    1139         295 : bool test_many_LookupSids(struct dcerpc_pipe *p,
    1140             :                           struct torture_context *tctx,
    1141             :                           struct policy_handle *handle,
    1142             :                           enum lsa_LookupNamesLevel level)
    1143             : {
    1144          48 :         uint32_t count;
    1145          48 :         struct lsa_SidArray sids;
    1146          48 :         int i;
    1147         295 :         struct dcerpc_binding_handle *b = p->binding_handle;
    1148         295 :         enum dcerpc_transport_t transport = dcerpc_binding_get_transport(p->binding);
    1149             : 
    1150         295 :         torture_comment(tctx, "\nTesting LookupSids with lots of SIDs\n");
    1151             : 
    1152         295 :         sids.num_sids = 100;
    1153             : 
    1154         295 :         sids.sids = talloc_array(tctx, struct lsa_SidPtr, sids.num_sids);
    1155             : 
    1156       29795 :         for (i=0; i<sids.num_sids; i++) {
    1157       29500 :                 const char *sidstr = "S-1-5-32-545";
    1158       29500 :                 sids.sids[i].sid = dom_sid_parse_talloc(tctx, sidstr);
    1159             :         }
    1160             : 
    1161         295 :         count = sids.num_sids;
    1162             : 
    1163         295 :         if (handle) {
    1164           0 :                 struct lsa_LookupSids r;
    1165           0 :                 struct lsa_TransNameArray names;
    1166          14 :                 struct lsa_RefDomainList *domains = NULL;
    1167          14 :                 names.count = 0;
    1168          14 :                 names.names = NULL;
    1169             : 
    1170          14 :                 r.in.handle = handle;
    1171          14 :                 r.in.sids = &sids;
    1172          14 :                 r.in.names = &names;
    1173          14 :                 r.in.level = level;
    1174          14 :                 r.in.count = &names.count;
    1175          14 :                 r.out.count = &count;
    1176          14 :                 r.out.names = &names;
    1177          14 :                 r.out.domains = &domains;
    1178             : 
    1179          14 :                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupSids_r(b, tctx, &r),
    1180             :                         "LookupSids failed");
    1181          14 :                 if (!NT_STATUS_IS_OK(r.out.result)) {
    1182           0 :                         torture_comment(tctx, "LookupSids failed - %s\n",
    1183             :                                         nt_errstr(r.out.result));
    1184           0 :                         return false;
    1185             :                 }
    1186             : 
    1187          14 :                 torture_comment(tctx, "\n");
    1188             : 
    1189          14 :                 if (!test_LookupNames(b, tctx, handle, level, &names)) {
    1190           0 :                         return false;
    1191             :                 }
    1192             :         }
    1193             : 
    1194         295 :         if (transport == NCACN_NP) {
    1195          11 :                 if (!test_LookupSids3_fail(b, tctx, level, &sids)) {
    1196           0 :                         return false;
    1197             :                 }
    1198          11 :                 if (!test_LookupNames4_fail(b, tctx, level)) {
    1199           0 :                         return false;
    1200             :                 }
    1201         284 :         } else if (transport == NCACN_IP_TCP) {
    1202          48 :                 struct lsa_TransNameArray2 names;
    1203          48 :                 enum dcerpc_AuthType auth_type;
    1204          48 :                 enum dcerpc_AuthLevel auth_level;
    1205             : 
    1206         281 :                 names.count = 0;
    1207         281 :                 names.names = NULL;
    1208             : 
    1209         281 :                 dcerpc_binding_handle_auth_info(p->binding_handle,
    1210             :                                                 &auth_type, &auth_level);
    1211             : 
    1212         281 :                 if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL &&
    1213         276 :                     auth_level >= DCERPC_AUTH_LEVEL_INTEGRITY) {
    1214         276 :                         if (!test_LookupSids3(b, tctx, level, &sids)) {
    1215           0 :                                 return false;
    1216             :                         }
    1217         276 :                         if (!test_LookupNames4(b, tctx, level, &names, true)) {
    1218           0 :                                 return false;
    1219             :                         }
    1220             :                 } else {
    1221             :                         /*
    1222             :                          * If we don't have a secure channel these tests must
    1223             :                          * fail with ACCESS_DENIED.
    1224             :                          */
    1225           5 :                         if (!test_LookupSids3_fail(b, tctx, level, &sids)) {
    1226           0 :                                 return false;
    1227             :                         }
    1228           5 :                         if (!test_LookupNames4_fail(b, tctx, level)) {
    1229           0 :                                 return false;
    1230             :                         }
    1231             :                 }
    1232             :         }
    1233             : 
    1234         295 :         torture_comment(tctx, "\n");
    1235             : 
    1236             : 
    1237             : 
    1238         295 :         return true;
    1239             : }
    1240             : 
    1241         700 : static void lookupsids_cb(struct tevent_req *subreq)
    1242             : {
    1243         700 :         int *replies = (int *)tevent_req_callback_data_void(subreq);
    1244           0 :         NTSTATUS status;
    1245             : 
    1246         700 :         status = dcerpc_lsa_LookupSids_r_recv(subreq, subreq);
    1247         700 :         TALLOC_FREE(subreq);
    1248         700 :         if (!NT_STATUS_IS_OK(status)) {
    1249           0 :                 printf("lookupsids returned %s\n", nt_errstr(status));
    1250           0 :                 *replies = -1;
    1251             :         }
    1252             : 
    1253         700 :         if (*replies >= 0) {
    1254         700 :                 *replies += 1;
    1255             :         }
    1256         700 : }
    1257             : 
    1258          14 : static bool test_LookupSids_async(struct dcerpc_binding_handle *b,
    1259             :                                   struct torture_context *tctx,
    1260             :                                   struct policy_handle *handle,
    1261             :                                   enum lsa_LookupNamesLevel level)
    1262             : {
    1263           0 :         struct lsa_SidArray sids;
    1264           0 :         struct lsa_SidPtr sidptr;
    1265           0 :         uint32_t *count;
    1266           0 :         struct lsa_TransNameArray *names;
    1267           0 :         struct lsa_LookupSids *r;
    1268          14 :         struct lsa_RefDomainList *domains = NULL;
    1269           0 :         struct tevent_req **req;
    1270           0 :         int i, replies;
    1271          14 :         bool ret = true;
    1272          14 :         const int num_async_requests = 50;
    1273             : 
    1274          14 :         count = talloc_array(tctx, uint32_t, num_async_requests);
    1275          14 :         names = talloc_array(tctx, struct lsa_TransNameArray, num_async_requests);
    1276          14 :         r = talloc_array(tctx, struct lsa_LookupSids, num_async_requests);
    1277             : 
    1278          14 :         torture_comment(tctx, "\nTesting %d async lookupsids request\n", num_async_requests);
    1279             : 
    1280          14 :         req = talloc_array(tctx, struct tevent_req *, num_async_requests);
    1281             : 
    1282          14 :         sids.num_sids = 1;
    1283          14 :         sids.sids = &sidptr;
    1284          14 :         sidptr.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-545");
    1285             : 
    1286          14 :         replies = 0;
    1287             : 
    1288         714 :         for (i=0; i<num_async_requests; i++) {
    1289         700 :                 count[i] = 0;
    1290         700 :                 names[i].count = 0;
    1291         700 :                 names[i].names = NULL;
    1292             : 
    1293         700 :                 r[i].in.handle = handle;
    1294         700 :                 r[i].in.sids = &sids;
    1295         700 :                 r[i].in.names = &names[i];
    1296         700 :                 r[i].in.level = level;
    1297         700 :                 r[i].in.count = &names[i].count;
    1298         700 :                 r[i].out.count = &count[i];
    1299         700 :                 r[i].out.names = &names[i];
    1300         700 :                 r[i].out.domains = &domains;
    1301             : 
    1302         700 :                 req[i] = dcerpc_lsa_LookupSids_r_send(tctx, tctx->ev, b, &r[i]);
    1303         700 :                 if (req[i] == NULL) {
    1304           0 :                         ret = false;
    1305           0 :                         break;
    1306             :                 }
    1307             : 
    1308         700 :                 tevent_req_set_callback(req[i], lookupsids_cb, &replies);
    1309             :         }
    1310             : 
    1311        7553 :         while (replies >= 0 && replies < num_async_requests) {
    1312        7539 :                 tevent_loop_once(tctx->ev);
    1313             :         }
    1314             : 
    1315          14 :         talloc_free(req);
    1316             : 
    1317          14 :         if (replies < 0) {
    1318           0 :                 ret = false;
    1319             :         }
    1320             : 
    1321          14 :         return ret;
    1322             : }
    1323             : 
    1324          93 : static bool test_LookupPrivValue(struct dcerpc_binding_handle *b,
    1325             :                                  struct torture_context *tctx,
    1326             :                                  struct policy_handle *handle,
    1327             :                                  struct lsa_String *name)
    1328             : {
    1329           0 :         struct lsa_LookupPrivValue r;
    1330           0 :         struct lsa_LUID luid;
    1331             : 
    1332          93 :         r.in.handle = handle;
    1333          93 :         r.in.name = name;
    1334          93 :         r.out.luid = &luid;
    1335             : 
    1336          93 :         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupPrivValue_r(b, tctx, &r),
    1337             :                 "LookupPrivValue failed");
    1338          93 :         torture_assert_ntstatus_ok(tctx, r.out.result,
    1339             :                 "LookupPrivValue failed");
    1340             : 
    1341          93 :         return true;
    1342             : }
    1343             : 
    1344         146 : static bool test_LookupPrivName(struct dcerpc_binding_handle *b,
    1345             :                                 struct torture_context *tctx,
    1346             :                                 struct policy_handle *handle,
    1347             :                                 struct lsa_LUID *luid)
    1348             : {
    1349           0 :         struct lsa_LookupPrivName r;
    1350         146 :         struct lsa_StringLarge *name = NULL;
    1351             : 
    1352         146 :         r.in.handle = handle;
    1353         146 :         r.in.luid = luid;
    1354         146 :         r.out.name = &name;
    1355             : 
    1356         146 :         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupPrivName_r(b, tctx, &r),
    1357             :                 "LookupPrivName failed");
    1358         146 :         torture_assert_ntstatus_ok(tctx, r.out.result, "LookupPrivName failed");
    1359             : 
    1360         146 :         return true;
    1361             : }
    1362             : 
    1363          17 : static bool test_RemovePrivilegesFromAccount(struct dcerpc_binding_handle *b,
    1364             :                                              struct torture_context *tctx,
    1365             :                                              struct policy_handle *handle,
    1366             :                                              struct policy_handle *acct_handle,
    1367             :                                              struct lsa_LUID *luid)
    1368             : {
    1369           0 :         struct lsa_RemovePrivilegesFromAccount r;
    1370           0 :         struct lsa_PrivilegeSet privs;
    1371          17 :         bool ret = true;
    1372             : 
    1373          17 :         torture_comment(tctx, "\nTesting RemovePrivilegesFromAccount\n");
    1374             : 
    1375          17 :         r.in.handle = acct_handle;
    1376          17 :         r.in.remove_all = 0;
    1377          17 :         r.in.privs = &privs;
    1378             : 
    1379          17 :         privs.count = 1;
    1380          17 :         privs.unknown = 0;
    1381          17 :         privs.set = talloc_array(tctx, struct lsa_LUIDAttribute, 1);
    1382          17 :         privs.set[0].luid = *luid;
    1383          17 :         privs.set[0].attribute = 0;
    1384             : 
    1385          17 :         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_RemovePrivilegesFromAccount_r(b, tctx, &r),
    1386             :                 "RemovePrivilegesFromAccount failed");
    1387          17 :         if (!NT_STATUS_IS_OK(r.out.result)) {
    1388             : 
    1389           0 :                 struct lsa_LookupPrivName r_name;
    1390           0 :                 struct lsa_StringLarge *name = NULL;
    1391             : 
    1392           0 :                 r_name.in.handle = handle;
    1393           0 :                 r_name.in.luid = luid;
    1394           0 :                 r_name.out.name = &name;
    1395             : 
    1396           0 :                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupPrivName_r(b, tctx, &r_name),
    1397             :                         "LookupPrivName failed");
    1398           0 :                 if (!NT_STATUS_IS_OK(r_name.out.result)) {
    1399           0 :                         torture_comment(tctx, "\nLookupPrivName failed - %s\n",
    1400             :                                         nt_errstr(r_name.out.result));
    1401           0 :                         return false;
    1402             :                 }
    1403             :                 /* Windows 2008 does not allow this to be removed */
    1404           0 :                 if (strcmp("SeAuditPrivilege", name->string) == 0) {
    1405           0 :                         return ret;
    1406             :                 }
    1407             : 
    1408           0 :                 torture_comment(tctx, "RemovePrivilegesFromAccount failed to remove %s - %s\n",
    1409           0 :                        name->string,
    1410             :                        nt_errstr(r.out.result));
    1411           0 :                 return false;
    1412             :         }
    1413             : 
    1414          17 :         return ret;
    1415             : }
    1416             : 
    1417          17 : static bool test_AddPrivilegesToAccount(struct dcerpc_binding_handle *b,
    1418             :                                         struct torture_context *tctx,
    1419             :                                         struct policy_handle *acct_handle,
    1420             :                                         struct lsa_LUID *luid)
    1421             : {
    1422           0 :         struct lsa_AddPrivilegesToAccount r;
    1423           0 :         struct lsa_PrivilegeSet privs;
    1424          17 :         bool ret = true;
    1425             : 
    1426          17 :         torture_comment(tctx, "\nTesting AddPrivilegesToAccount\n");
    1427             : 
    1428          17 :         r.in.handle = acct_handle;
    1429          17 :         r.in.privs = &privs;
    1430             : 
    1431          17 :         privs.count = 1;
    1432          17 :         privs.unknown = 0;
    1433          17 :         privs.set = talloc_array(tctx, struct lsa_LUIDAttribute, 1);
    1434          17 :         privs.set[0].luid = *luid;
    1435          17 :         privs.set[0].attribute = 0;
    1436             : 
    1437          17 :         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_AddPrivilegesToAccount_r(b, tctx, &r),
    1438             :                 "AddPrivilegesToAccount failed");
    1439          17 :         torture_assert_ntstatus_ok(tctx, r.out.result,
    1440             :                 "AddPrivilegesToAccount failed");
    1441          17 :         return ret;
    1442             : }
    1443             : 
    1444          30 : static bool test_EnumPrivsAccount(struct dcerpc_binding_handle *b,
    1445             :                                   struct torture_context *tctx,
    1446             :                                   struct policy_handle *handle,
    1447             :                                   struct policy_handle *acct_handle)
    1448             : {
    1449           0 :         struct lsa_EnumPrivsAccount r;
    1450          30 :         struct lsa_PrivilegeSet *privs = NULL;
    1451          30 :         bool ret = true;
    1452             : 
    1453          30 :         torture_comment(tctx, "\nTesting EnumPrivsAccount\n");
    1454             : 
    1455          30 :         r.in.handle = acct_handle;
    1456          30 :         r.out.privs = &privs;
    1457             : 
    1458          30 :         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumPrivsAccount_r(b, tctx, &r),
    1459             :                 "EnumPrivsAccount failed");
    1460          30 :         torture_assert_ntstatus_ok(tctx, r.out.result,
    1461             :                 "EnumPrivsAccount failed");
    1462             : 
    1463          30 :         if (privs && privs->count > 0) {
    1464             :                 int i;
    1465         163 :                 for (i=0;i<privs->count;i++) {
    1466         146 :                         test_LookupPrivName(b, tctx, handle,
    1467         146 :                                             &privs->set[i].luid);
    1468             :                 }
    1469             : 
    1470          34 :                 ret &= test_RemovePrivilegesFromAccount(b, tctx, handle, acct_handle,
    1471          17 :                                                         &privs->set[0].luid);
    1472          17 :                 ret &= test_AddPrivilegesToAccount(b, tctx, acct_handle,
    1473          17 :                                                    &privs->set[0].luid);
    1474             :         }
    1475             : 
    1476          30 :         return ret;
    1477             : }
    1478             : 
    1479          30 : static bool test_GetSystemAccessAccount(struct dcerpc_binding_handle *b,
    1480             :                                         struct torture_context *tctx,
    1481             :                                         struct policy_handle *handle,
    1482             :                                         struct policy_handle *acct_handle)
    1483             : {
    1484           0 :         uint32_t access_mask;
    1485           0 :         struct lsa_GetSystemAccessAccount r;
    1486             : 
    1487          30 :         torture_comment(tctx, "\nTesting GetSystemAccessAccount\n");
    1488             : 
    1489          30 :         r.in.handle = acct_handle;
    1490          30 :         r.out.access_mask = &access_mask;
    1491             : 
    1492          30 :         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetSystemAccessAccount_r(b, tctx, &r),
    1493             :                 "GetSystemAccessAccount failed");
    1494          30 :         torture_assert_ntstatus_ok(tctx, r.out.result,
    1495             :                 "GetSystemAccessAccount failed");
    1496             : 
    1497          30 :         if (r.out.access_mask != NULL) {
    1498          30 :                 torture_comment(tctx, "Rights:");
    1499          30 :                 if (*(r.out.access_mask) & LSA_POLICY_MODE_INTERACTIVE)
    1500          27 :                         torture_comment(tctx, " LSA_POLICY_MODE_INTERACTIVE");
    1501          30 :                 if (*(r.out.access_mask) & LSA_POLICY_MODE_NETWORK)
    1502          15 :                         torture_comment(tctx, " LSA_POLICY_MODE_NETWORK");
    1503          30 :                 if (*(r.out.access_mask) & LSA_POLICY_MODE_BATCH)
    1504           0 :                         torture_comment(tctx, " LSA_POLICY_MODE_BATCH");
    1505          30 :                 if (*(r.out.access_mask) & LSA_POLICY_MODE_SERVICE)
    1506           0 :                         torture_comment(tctx, " LSA_POLICY_MODE_SERVICE");
    1507          30 :                 if (*(r.out.access_mask) & LSA_POLICY_MODE_PROXY)
    1508           0 :                         torture_comment(tctx, " LSA_POLICY_MODE_PROXY");
    1509          30 :                 if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_INTERACTIVE)
    1510           0 :                         torture_comment(tctx, " LSA_POLICY_MODE_DENY_INTERACTIVE");
    1511          30 :                 if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_NETWORK)
    1512           0 :                         torture_comment(tctx, " LSA_POLICY_MODE_DENY_NETWORK");
    1513          30 :                 if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_BATCH)
    1514           0 :                         torture_comment(tctx, " LSA_POLICY_MODE_DENY_BATCH");
    1515          30 :                 if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_SERVICE)
    1516           0 :                         torture_comment(tctx, " LSA_POLICY_MODE_DENY_SERVICE");
    1517          30 :                 if (*(r.out.access_mask) & LSA_POLICY_MODE_REMOTE_INTERACTIVE)
    1518           6 :                         torture_comment(tctx, " LSA_POLICY_MODE_REMOTE_INTERACTIVE");
    1519          30 :                 if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_REMOTE_INTERACTIVE)
    1520           0 :                         torture_comment(tctx, " LSA_POLICY_MODE_DENY_REMOTE_INTERACTIVE");
    1521          30 :                 if (*(r.out.access_mask) & LSA_POLICY_MODE_ALL)
    1522          30 :                         torture_comment(tctx, " LSA_POLICY_MODE_ALL");
    1523          30 :                 if (*(r.out.access_mask) & LSA_POLICY_MODE_ALL_NT4)
    1524          27 :                         torture_comment(tctx, " LSA_POLICY_MODE_ALL_NT4");
    1525          30 :                 torture_comment(tctx, "\n");
    1526             :         }
    1527             : 
    1528          30 :         return true;
    1529             : }
    1530             : 
    1531          41 : static bool test_Delete(struct dcerpc_binding_handle *b,
    1532             :                         struct torture_context *tctx,
    1533             :                         struct policy_handle *handle)
    1534             : {
    1535           0 :         struct lsa_Delete r;
    1536             : 
    1537          41 :         torture_comment(tctx, "\nTesting Delete\n");
    1538             : 
    1539          41 :         r.in.handle = handle;
    1540          41 :         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_Delete_r(b, tctx, &r),
    1541             :                 "Delete failed");
    1542          41 :         torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_SUPPORTED,
    1543             :                 "Delete should have failed NT_STATUS_NOT_SUPPORTED");
    1544             : 
    1545          41 :         return true;
    1546             : }
    1547             : 
    1548          27 : static bool test_DeleteObject(struct dcerpc_binding_handle *b,
    1549             :                               struct torture_context *tctx,
    1550             :                               struct policy_handle *handle)
    1551             : {
    1552           0 :         struct lsa_DeleteObject r;
    1553             : 
    1554          27 :         torture_comment(tctx, "\nTesting DeleteObject\n");
    1555             : 
    1556          27 :         r.in.handle = handle;
    1557          27 :         r.out.handle = handle;
    1558          27 :         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_DeleteObject_r(b, tctx, &r),
    1559             :                 "DeleteObject failed");
    1560          27 :         torture_assert_ntstatus_ok(tctx, r.out.result,
    1561             :                 "DeleteObject failed");
    1562             : 
    1563          27 :         return true;
    1564             : }
    1565             : 
    1566             : 
    1567           5 : static bool test_CreateAccount(struct dcerpc_binding_handle *b,
    1568             :                                struct torture_context *tctx,
    1569             :                                struct policy_handle *handle)
    1570             : {
    1571           0 :         struct lsa_CreateAccount r;
    1572           0 :         struct dom_sid2 *newsid;
    1573           0 :         struct policy_handle acct_handle;
    1574             : 
    1575           5 :         newsid = dom_sid_parse_talloc(tctx, "S-1-5-12349876-4321-2854");
    1576             : 
    1577           5 :         torture_comment(tctx, "\nTesting CreateAccount\n");
    1578             : 
    1579           5 :         r.in.handle = handle;
    1580           5 :         r.in.sid = newsid;
    1581           5 :         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    1582           5 :         r.out.acct_handle = &acct_handle;
    1583             : 
    1584           5 :         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_CreateAccount_r(b, tctx, &r),
    1585             :                 "CreateAccount failed");
    1586           5 :         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_OBJECT_NAME_COLLISION)) {
    1587           0 :                 struct lsa_OpenAccount r_o;
    1588           0 :                 r_o.in.handle = handle;
    1589           0 :                 r_o.in.sid = newsid;
    1590           0 :                 r_o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    1591           0 :                 r_o.out.acct_handle = &acct_handle;
    1592             : 
    1593           0 :                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenAccount_r(b, tctx, &r_o),
    1594             :                         "OpenAccount failed");
    1595           0 :                 torture_assert_ntstatus_ok(tctx, r_o.out.result,
    1596             :                         "OpenAccount failed");
    1597             :         } else {
    1598           5 :                 torture_assert_ntstatus_ok(tctx, r.out.result,
    1599             :                                            "CreateAccount failed");
    1600             :         }
    1601             : 
    1602           5 :         if (!test_Delete(b, tctx, &acct_handle)) {
    1603           0 :                 return false;
    1604             :         }
    1605             : 
    1606           5 :         if (!test_DeleteObject(b, tctx, &acct_handle)) {
    1607           0 :                 return false;
    1608             :         }
    1609             : 
    1610           5 :         return true;
    1611             : }
    1612             : 
    1613           0 : static bool test_DeleteTrustedDomain(struct dcerpc_binding_handle *b,
    1614             :                                      struct torture_context *tctx,
    1615             :                                      struct policy_handle *handle,
    1616             :                                      struct lsa_StringLarge name)
    1617             : {
    1618           0 :         struct lsa_OpenTrustedDomainByName r;
    1619           0 :         struct policy_handle trustdom_handle;
    1620             : 
    1621           0 :         r.in.handle = handle;
    1622           0 :         r.in.name.string = name.string;
    1623           0 :         r.in.access_mask = SEC_STD_DELETE;
    1624           0 :         r.out.trustdom_handle = &trustdom_handle;
    1625             : 
    1626           0 :         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenTrustedDomainByName_r(b, tctx, &r),
    1627             :                 "OpenTrustedDomainByName failed");
    1628           0 :         torture_assert_ntstatus_ok(tctx, r.out.result,
    1629             :                 "OpenTrustedDomainByName failed");
    1630             : 
    1631           0 :         if (!test_Delete(b, tctx, &trustdom_handle)) {
    1632           0 :                 return false;
    1633             :         }
    1634             : 
    1635           0 :         if (!test_DeleteObject(b, tctx, &trustdom_handle)) {
    1636           0 :                 return false;
    1637             :         }
    1638             : 
    1639           0 :         return true;
    1640             : }
    1641             : 
    1642         144 : static bool test_DeleteTrustedDomainBySid(struct dcerpc_binding_handle *b,
    1643             :                                           struct torture_context *tctx,
    1644             :                                           struct policy_handle *handle,
    1645             :                                           struct dom_sid *sid)
    1646             : {
    1647           0 :         struct lsa_DeleteTrustedDomain r;
    1648             : 
    1649         144 :         r.in.handle = handle;
    1650         144 :         r.in.dom_sid = sid;
    1651             : 
    1652         144 :         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_DeleteTrustedDomain_r(b, tctx, &r),
    1653             :                 "DeleteTrustedDomain failed");
    1654         144 :         torture_assert_ntstatus_ok(tctx, r.out.result,
    1655             :                 "DeleteTrustedDomain failed");
    1656             : 
    1657         144 :         return true;
    1658             : }
    1659             : 
    1660             : 
    1661          14 : static bool test_CreateSecret(struct dcerpc_pipe *p,
    1662             :                               struct torture_context *tctx,
    1663             :                               struct policy_handle *handle)
    1664             : {
    1665           0 :         struct lsa_CreateSecret r;
    1666           0 :         struct lsa_OpenSecret r2;
    1667           0 :         struct lsa_SetSecret r3;
    1668           0 :         struct lsa_QuerySecret r4;
    1669           0 :         struct lsa_SetSecret r5;
    1670           0 :         struct lsa_QuerySecret r6;
    1671           0 :         struct lsa_SetSecret r7;
    1672           0 :         struct lsa_QuerySecret r8;
    1673           0 :         struct policy_handle sec_handle, sec_handle2, sec_handle3;
    1674           0 :         struct lsa_DeleteObject d_o;
    1675           0 :         struct lsa_DATA_BUF buf1;
    1676           0 :         struct lsa_DATA_BUF_PTR bufp1;
    1677           0 :         struct lsa_DATA_BUF_PTR bufp2;
    1678           0 :         DATA_BLOB enc_key;
    1679          14 :         bool ret = true;
    1680           0 :         DATA_BLOB session_key;
    1681           0 :         NTTIME old_mtime, new_mtime;
    1682           0 :         DATA_BLOB blob1;
    1683          14 :         const char *secret1 = "abcdef12345699qwerty";
    1684           0 :         char *secret2;
    1685          14 :         const char *secret3 = "ABCDEF12345699QWERTY";
    1686           0 :         char *secret4;
    1687          14 :         const char *secret5 = "NEW-SAMBA4-SECRET";
    1688           0 :         char *secret6;
    1689           0 :         char *secname[2];
    1690           0 :         int i;
    1691          14 :         const int LOCAL = 0;
    1692          14 :         const int GLOBAL = 1;
    1693          14 :         struct dcerpc_binding_handle *b = p->binding_handle;
    1694             : 
    1695          14 :         secname[LOCAL] = talloc_asprintf(tctx, "torturesecret-%u", (unsigned int)random());
    1696          14 :         secname[GLOBAL] = talloc_asprintf(tctx, "G$torturesecret-%u", (unsigned int)random());
    1697             : 
    1698          36 :         for (i=0; i< 2; i++) {
    1699          25 :                 torture_comment(tctx, "\nTesting CreateSecret of %s\n", secname[i]);
    1700             : 
    1701          25 :                 init_lsa_String(&r.in.name, secname[i]);
    1702             : 
    1703          25 :                 r.in.handle = handle;
    1704          25 :                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    1705          25 :                 r.out.sec_handle = &sec_handle;
    1706             : 
    1707          25 :                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_CreateSecret_r(b, tctx, &r),
    1708             :                         "CreateSecret failed");
    1709          25 :                 torture_assert_ntstatus_ok(tctx, r.out.result,
    1710             :                         "CreateSecret failed");
    1711             : 
    1712          25 :                 r.in.handle = handle;
    1713          25 :                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    1714          25 :                 r.out.sec_handle = &sec_handle3;
    1715             : 
    1716          25 :                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_CreateSecret_r(b, tctx, &r),
    1717             :                         "CreateSecret failed");
    1718          25 :                 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_OBJECT_NAME_COLLISION,
    1719             :                                               "CreateSecret should have failed OBJECT_NAME_COLLISION");
    1720             : 
    1721          25 :                 r2.in.handle = handle;
    1722          25 :                 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    1723          25 :                 r2.in.name = r.in.name;
    1724          25 :                 r2.out.sec_handle = &sec_handle2;
    1725             : 
    1726          25 :                 torture_comment(tctx, "Testing OpenSecret\n");
    1727             : 
    1728          25 :                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenSecret_r(b, tctx, &r2),
    1729             :                         "OpenSecret failed");
    1730          25 :                 torture_assert_ntstatus_ok(tctx, r2.out.result,
    1731             :                                            "OpenSecret failed");
    1732             : 
    1733          25 :                 torture_assert_ntstatus_ok(tctx, dcerpc_fetch_session_key(p, &session_key),
    1734             :                                            "dcerpc_fetch_session_key failed");
    1735             : 
    1736          22 :                 enc_key = sess_encrypt_string(secret1, &session_key);
    1737             : 
    1738          22 :                 r3.in.sec_handle = &sec_handle;
    1739          22 :                 r3.in.new_val = &buf1;
    1740          22 :                 r3.in.old_val = NULL;
    1741          22 :                 r3.in.new_val->data = enc_key.data;
    1742          22 :                 r3.in.new_val->length = enc_key.length;
    1743          22 :                 r3.in.new_val->size = enc_key.length;
    1744             : 
    1745          22 :                 torture_comment(tctx, "Testing SetSecret\n");
    1746             : 
    1747          22 :                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_SetSecret_r(b, tctx, &r3),
    1748             :                         "SetSecret failed");
    1749          22 :                 torture_assert_ntstatus_ok(tctx, r3.out.result,
    1750             :                         "SetSecret failed");
    1751             : 
    1752          22 :                 r3.in.sec_handle = &sec_handle;
    1753          22 :                 r3.in.new_val = &buf1;
    1754          22 :                 r3.in.old_val = NULL;
    1755          22 :                 r3.in.new_val->data = enc_key.data;
    1756          22 :                 r3.in.new_val->length = enc_key.length;
    1757          22 :                 r3.in.new_val->size = enc_key.length;
    1758             : 
    1759             :                 /* break the encrypted data */
    1760          22 :                 enc_key.data[0]++;
    1761             : 
    1762          22 :                 torture_comment(tctx, "Testing SetSecret with broken key\n");
    1763             : 
    1764          22 :                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_SetSecret_r(b, tctx, &r3),
    1765             :                                            "SetSecret failed");
    1766          22 :                 torture_assert_ntstatus_equal(tctx, r3.out.result, NT_STATUS_UNKNOWN_REVISION,
    1767             :                                               "SetSecret should have failed UNKNOWN_REVISION");
    1768             : 
    1769          22 :                 data_blob_free(&enc_key);
    1770             : 
    1771          22 :                 ZERO_STRUCT(new_mtime);
    1772          22 :                 ZERO_STRUCT(old_mtime);
    1773             : 
    1774             :                 /* fetch the secret back again */
    1775          22 :                 r4.in.sec_handle = &sec_handle;
    1776          22 :                 r4.in.new_val = &bufp1;
    1777          22 :                 r4.in.new_mtime = &new_mtime;
    1778          22 :                 r4.in.old_val = NULL;
    1779          22 :                 r4.in.old_mtime = NULL;
    1780             : 
    1781          22 :                 bufp1.buf = NULL;
    1782             : 
    1783          22 :                 torture_comment(tctx, "Testing QuerySecret\n");
    1784          22 :                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QuerySecret_r(b, tctx, &r4),
    1785             :                         "QuerySecret failed");
    1786          22 :                 if (!NT_STATUS_IS_OK(r4.out.result)) {
    1787           0 :                         torture_comment(tctx, "QuerySecret failed - %s\n", nt_errstr(r4.out.result));
    1788           0 :                         ret = false;
    1789             :                 } else {
    1790          22 :                         if (r4.out.new_val == NULL || r4.out.new_val->buf == NULL) {
    1791           0 :                                 torture_comment(tctx, "No secret buffer returned\n");
    1792           0 :                                 ret = false;
    1793             :                         } else {
    1794          22 :                                 blob1.data = r4.out.new_val->buf->data;
    1795          22 :                                 blob1.length = r4.out.new_val->buf->size;
    1796             : 
    1797          22 :                                 secret2 = sess_decrypt_string(tctx,
    1798             :                                                               &blob1, &session_key);
    1799             : 
    1800          22 :                                 if (strcmp(secret1, secret2) != 0) {
    1801           0 :                                         torture_comment(tctx, "Returned secret (r4) '%s' doesn't match '%s'\n",
    1802             :                                                secret2, secret1);
    1803           0 :                                         ret = false;
    1804             :                                 }
    1805             :                         }
    1806             :                 }
    1807             : 
    1808          22 :                 enc_key = sess_encrypt_string(secret3, &session_key);
    1809             : 
    1810          22 :                 r5.in.sec_handle = &sec_handle;
    1811          22 :                 r5.in.new_val = &buf1;
    1812          22 :                 r5.in.old_val = NULL;
    1813          22 :                 r5.in.new_val->data = enc_key.data;
    1814          22 :                 r5.in.new_val->length = enc_key.length;
    1815          22 :                 r5.in.new_val->size = enc_key.length;
    1816             : 
    1817             : 
    1818          22 :                 smb_msleep(200);
    1819          22 :                 torture_comment(tctx, "Testing SetSecret (existing value should move to old)\n");
    1820             : 
    1821          22 :                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_SetSecret_r(b, tctx, &r5),
    1822             :                         "SetSecret failed");
    1823          22 :                 if (!NT_STATUS_IS_OK(r5.out.result)) {
    1824           0 :                         torture_comment(tctx, "SetSecret failed - %s\n", nt_errstr(r5.out.result));
    1825           0 :                         ret = false;
    1826             :                 }
    1827             : 
    1828          22 :                 data_blob_free(&enc_key);
    1829             : 
    1830          22 :                 ZERO_STRUCT(new_mtime);
    1831          22 :                 ZERO_STRUCT(old_mtime);
    1832             : 
    1833             :                 /* fetch the secret back again */
    1834          22 :                 r6.in.sec_handle = &sec_handle;
    1835          22 :                 r6.in.new_val = &bufp1;
    1836          22 :                 r6.in.new_mtime = &new_mtime;
    1837          22 :                 r6.in.old_val = &bufp2;
    1838          22 :                 r6.in.old_mtime = &old_mtime;
    1839             : 
    1840          22 :                 bufp1.buf = NULL;
    1841          22 :                 bufp2.buf = NULL;
    1842             : 
    1843          22 :                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QuerySecret_r(b, tctx, &r6),
    1844             :                         "QuerySecret failed");
    1845          22 :                 if (!NT_STATUS_IS_OK(r6.out.result)) {
    1846           0 :                         torture_comment(tctx, "QuerySecret failed - %s\n", nt_errstr(r6.out.result));
    1847           0 :                         ret = false;
    1848           0 :                         secret4 = NULL;
    1849             :                 } else {
    1850             : 
    1851          22 :                         if (r6.out.new_val->buf == NULL || r6.out.old_val->buf == NULL
    1852          22 :                                 || r6.out.new_mtime == NULL || r6.out.old_mtime == NULL) {
    1853           0 :                                 torture_comment(tctx, "Both secret buffers and both times not returned\n");
    1854           0 :                                 ret = false;
    1855           0 :                                 secret4 = NULL;
    1856             :                         } else {
    1857          22 :                                 blob1.data = r6.out.new_val->buf->data;
    1858          22 :                                 blob1.length = r6.out.new_val->buf->size;
    1859             : 
    1860          22 :                                 secret4 = sess_decrypt_string(tctx,
    1861             :                                                               &blob1, &session_key);
    1862             : 
    1863          22 :                                 if (strcmp(secret3, secret4) != 0) {
    1864           0 :                                         torture_comment(tctx, "Returned NEW secret %s doesn't match %s\n", secret4, secret3);
    1865           0 :                                         ret = false;
    1866             :                                 }
    1867             : 
    1868          22 :                                 blob1.data = r6.out.old_val->buf->data;
    1869          22 :                                 blob1.length = r6.out.old_val->buf->length;
    1870             : 
    1871          22 :                                 secret2 = sess_decrypt_string(tctx,
    1872             :                                                               &blob1, &session_key);
    1873             : 
    1874          22 :                                 if (strcmp(secret1, secret2) != 0) {
    1875           0 :                                         torture_comment(tctx, "Returned OLD secret %s doesn't match %s\n", secret2, secret1);
    1876           0 :                                         ret = false;
    1877             :                                 }
    1878             : 
    1879          22 :                                 if (*r6.out.new_mtime == *r6.out.old_mtime) {
    1880           0 :                                         torture_comment(tctx, "Returned secret (r6-%d) %s must not have same mtime for both secrets: %s != %s\n",
    1881             :                                                i,
    1882             :                                                secname[i],
    1883           0 :                                                nt_time_string(tctx, *r6.out.old_mtime),
    1884           0 :                                                nt_time_string(tctx, *r6.out.new_mtime));
    1885           0 :                                         ret = false;
    1886             :                                 }
    1887             :                         }
    1888             :                 }
    1889             : 
    1890          22 :                 enc_key = sess_encrypt_string(secret5, &session_key);
    1891             : 
    1892          22 :                 r7.in.sec_handle = &sec_handle;
    1893          22 :                 r7.in.old_val = &buf1;
    1894          22 :                 r7.in.old_val->data = enc_key.data;
    1895          22 :                 r7.in.old_val->length = enc_key.length;
    1896          22 :                 r7.in.old_val->size = enc_key.length;
    1897          22 :                 r7.in.new_val = NULL;
    1898             : 
    1899          22 :                 torture_comment(tctx, "Testing SetSecret of old Secret only\n");
    1900             : 
    1901          22 :                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_SetSecret_r(b, tctx, &r7),
    1902             :                         "SetSecret failed");
    1903          22 :                 if (!NT_STATUS_IS_OK(r7.out.result)) {
    1904           0 :                         torture_comment(tctx, "SetSecret failed - %s\n", nt_errstr(r7.out.result));
    1905           0 :                         ret = false;
    1906             :                 }
    1907             : 
    1908          22 :                 data_blob_free(&enc_key);
    1909             : 
    1910             :                 /* fetch the secret back again */
    1911          22 :                 r8.in.sec_handle = &sec_handle;
    1912          22 :                 r8.in.new_val = &bufp1;
    1913          22 :                 r8.in.new_mtime = &new_mtime;
    1914          22 :                 r8.in.old_val = &bufp2;
    1915          22 :                 r8.in.old_mtime = &old_mtime;
    1916             : 
    1917          22 :                 bufp1.buf = NULL;
    1918          22 :                 bufp2.buf = NULL;
    1919             : 
    1920          22 :                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QuerySecret_r(b, tctx, &r8),
    1921             :                         "QuerySecret failed");
    1922          22 :                 if (!NT_STATUS_IS_OK(r8.out.result)) {
    1923           0 :                         torture_comment(tctx, "QuerySecret failed - %s\n", nt_errstr(r8.out.result));
    1924           0 :                         ret = false;
    1925             :                 } else {
    1926          22 :                         if (!r8.out.new_val || !r8.out.old_val) {
    1927           0 :                                 torture_comment(tctx, "in/out pointers not returned, despite being set on in for QuerySecret\n");
    1928           0 :                                 ret = false;
    1929          22 :                         } else if (r8.out.new_val->buf != NULL) {
    1930           0 :                                 torture_comment(tctx, "NEW secret buffer must not be returned after OLD set\n");
    1931           0 :                                 ret = false;
    1932          22 :                         } else if (r8.out.old_val->buf == NULL) {
    1933           0 :                                 torture_comment(tctx, "OLD secret buffer was not returned after OLD set\n");
    1934           0 :                                 ret = false;
    1935          22 :                         } else if (r8.out.new_mtime == NULL || r8.out.old_mtime == NULL) {
    1936           0 :                                 torture_comment(tctx, "Both times not returned after OLD set\n");
    1937           0 :                                 ret = false;
    1938             :                         } else {
    1939          22 :                                 blob1.data = r8.out.old_val->buf->data;
    1940          22 :                                 blob1.length = r8.out.old_val->buf->size;
    1941             : 
    1942          22 :                                 secret6 = sess_decrypt_string(tctx,
    1943             :                                                               &blob1, &session_key);
    1944             : 
    1945          22 :                                 if (strcmp(secret5, secret6) != 0) {
    1946           0 :                                         torture_comment(tctx, "Returned OLD secret %s doesn't match %s\n", secret5, secret6);
    1947           0 :                                         ret = false;
    1948             :                                 }
    1949             : 
    1950          22 :                                 if (*r8.out.new_mtime != *r8.out.old_mtime) {
    1951           0 :                                         torture_comment(tctx, "Returned secret (r8) %s did not had same mtime for both secrets: %s != %s\n",
    1952             :                                                secname[i],
    1953           0 :                                                nt_time_string(tctx, *r8.out.old_mtime),
    1954           0 :                                                nt_time_string(tctx, *r8.out.new_mtime));
    1955           0 :                                         ret = false;
    1956             :                                 }
    1957             :                         }
    1958             :                 }
    1959             : 
    1960          22 :                 if (!test_Delete(b, tctx, &sec_handle)) {
    1961           0 :                         ret = false;
    1962             :                 }
    1963             : 
    1964          22 :                 if (!test_DeleteObject(b, tctx, &sec_handle)) {
    1965           0 :                         return false;
    1966             :                 }
    1967             : 
    1968          22 :                 d_o.in.handle = &sec_handle2;
    1969          22 :                 d_o.out.handle = &sec_handle2;
    1970          22 :                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_DeleteObject_r(b, tctx, &d_o),
    1971             :                         "DeleteObject failed");
    1972          22 :                 torture_assert_ntstatus_equal(tctx, d_o.out.result, NT_STATUS_INVALID_HANDLE,
    1973             :                                               "OpenSecret expected INVALID_HANDLE");
    1974             : 
    1975          22 :                 torture_comment(tctx, "Testing OpenSecret of just-deleted secret\n");
    1976             : 
    1977          22 :                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenSecret_r(b, tctx, &r2),
    1978             :                                            "OpenSecret failed");
    1979          22 :                 torture_assert_ntstatus_equal(tctx, r2.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND,
    1980             :                                               "OpenSecret expected OBJECT_NAME_NOT_FOUND");
    1981             :         }
    1982          11 :         return ret;
    1983             : }
    1984             : 
    1985             : 
    1986          30 : static bool test_EnumAccountRights(struct dcerpc_binding_handle *b,
    1987             :                                    struct torture_context *tctx,
    1988             :                                    struct policy_handle *acct_handle,
    1989             :                                    struct dom_sid *sid)
    1990             : {
    1991           0 :         struct lsa_EnumAccountRights r;
    1992           0 :         struct lsa_RightSet rights;
    1993             : 
    1994          30 :         torture_comment(tctx, "\nTesting EnumAccountRights\n");
    1995             : 
    1996          30 :         r.in.handle = acct_handle;
    1997          30 :         r.in.sid = sid;
    1998          30 :         r.out.rights = &rights;
    1999             : 
    2000          30 :         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(b, tctx, &r),
    2001             :                 "EnumAccountRights failed");
    2002          30 :         if (!NT_STATUS_IS_OK(r.out.result)) {
    2003           0 :                 torture_comment(tctx, "EnumAccountRights of %s failed - %s\n",
    2004             :                        dom_sid_string(tctx, sid), nt_errstr(r.out.result));
    2005             :         }
    2006          30 :         torture_assert_ntstatus_ok(tctx, r.out.result,
    2007             :                 "EnumAccountRights failed");
    2008             : 
    2009          30 :         return true;
    2010             : }
    2011             : 
    2012             : 
    2013          30 : static bool test_QuerySecurity(struct dcerpc_binding_handle *b,
    2014             :                              struct torture_context *tctx,
    2015             :                              struct policy_handle *handle,
    2016             :                              struct policy_handle *acct_handle)
    2017             : {
    2018           0 :         struct lsa_QuerySecurity r;
    2019          30 :         struct sec_desc_buf *sdbuf = NULL;
    2020             : 
    2021          30 :         if (torture_setting_bool(tctx, "samba4", false)) {
    2022          18 :                 torture_comment(tctx, "\nskipping QuerySecurity test against Samba4\n");
    2023          18 :                 return true;
    2024             :         }
    2025             : 
    2026          12 :         torture_comment(tctx, "\nTesting QuerySecurity\n");
    2027             : 
    2028          12 :         r.in.handle = acct_handle;
    2029          12 :         r.in.sec_info = SECINFO_OWNER |
    2030             :                         SECINFO_GROUP |
    2031             :                         SECINFO_DACL;
    2032          12 :         r.out.sdbuf = &sdbuf;
    2033             : 
    2034          12 :         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QuerySecurity_r(b, tctx, &r),
    2035             :                 "QuerySecurity failed");
    2036          12 :         if (!NT_STATUS_IS_OK(r.out.result)) {
    2037           0 :                 torture_comment(tctx, "QuerySecurity failed - %s\n", nt_errstr(r.out.result));
    2038           0 :                 return false;
    2039             :         }
    2040             : 
    2041          12 :         return true;
    2042             : }
    2043             : 
    2044          30 : static bool test_OpenAccount(struct dcerpc_binding_handle *b,
    2045             :                              struct torture_context *tctx,
    2046             :                              struct policy_handle *handle,
    2047             :                              struct dom_sid *sid)
    2048             : {
    2049           0 :         struct lsa_OpenAccount r;
    2050           0 :         struct policy_handle acct_handle;
    2051             : 
    2052          30 :         torture_comment(tctx, "\nTesting OpenAccount\n");
    2053             : 
    2054          30 :         r.in.handle = handle;
    2055          30 :         r.in.sid = sid;
    2056          30 :         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    2057          30 :         r.out.acct_handle = &acct_handle;
    2058             : 
    2059          30 :         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenAccount_r(b, tctx, &r),
    2060             :                 "OpenAccount failed");
    2061          30 :         torture_assert_ntstatus_ok(tctx, r.out.result,
    2062             :                 "OpenAccount failed");
    2063             : 
    2064          30 :         if (!test_EnumPrivsAccount(b, tctx, handle, &acct_handle)) {
    2065           0 :                 return false;
    2066             :         }
    2067             : 
    2068          30 :         if (!test_GetSystemAccessAccount(b, tctx, handle, &acct_handle)) {
    2069           0 :                 return false;
    2070             :         }
    2071             : 
    2072          30 :         if (!test_QuerySecurity(b, tctx, handle, &acct_handle)) {
    2073           0 :                 return false;
    2074             :         }
    2075             : 
    2076          30 :         return true;
    2077             : }
    2078             : 
    2079           5 : static bool test_EnumAccounts(struct dcerpc_binding_handle *b,
    2080             :                               struct torture_context *tctx,
    2081             :                               struct policy_handle *handle)
    2082             : {
    2083           0 :         struct lsa_EnumAccounts r;
    2084           0 :         struct lsa_SidArray sids1, sids2;
    2085           5 :         uint32_t resume_handle = 0;
    2086           0 :         int i;
    2087           5 :         bool ret = true;
    2088             : 
    2089           5 :         torture_comment(tctx, "\nTesting EnumAccounts\n");
    2090             : 
    2091           5 :         r.in.handle = handle;
    2092           5 :         r.in.resume_handle = &resume_handle;
    2093           5 :         r.in.num_entries = 100;
    2094           5 :         r.out.resume_handle = &resume_handle;
    2095           5 :         r.out.sids = &sids1;
    2096             : 
    2097           5 :         resume_handle = 0;
    2098           0 :         while (true) {
    2099          10 :                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(b, tctx, &r),
    2100             :                         "EnumAccounts failed");
    2101          10 :                 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NO_MORE_ENTRIES)) {
    2102           5 :                         break;
    2103             :                 }
    2104           5 :                 torture_assert_ntstatus_ok(tctx, r.out.result,
    2105             :                         "EnumAccounts failed");
    2106             : 
    2107           5 :                 if (!test_LookupSids(b, tctx, handle, LSA_LOOKUP_NAMES_ALL, &sids1)) {
    2108           0 :                         return false;
    2109             :                 }
    2110             : 
    2111           5 :                 if (!test_LookupSids2(b, tctx, handle, LSA_LOOKUP_NAMES_ALL, &sids1)) {
    2112           0 :                         return false;
    2113             :                 }
    2114             : 
    2115             :                 /* Can't test lookupSids3 here, as clearly we must not
    2116             :                  * be on schannel, or we would not be able to do the
    2117             :                  * rest */
    2118             : 
    2119           5 :                 torture_comment(tctx, "Testing all accounts\n");
    2120          35 :                 for (i=0;i<sids1.num_sids;i++) {
    2121          30 :                         ret &= test_OpenAccount(b, tctx, handle, sids1.sids[i].sid);
    2122          30 :                         ret &= test_EnumAccountRights(b, tctx, handle, sids1.sids[i].sid);
    2123             :                 }
    2124           5 :                 torture_comment(tctx, "\n");
    2125             :         }
    2126             : 
    2127           5 :         if (sids1.num_sids < 3) {
    2128           5 :                 return ret;
    2129             :         }
    2130             : 
    2131           0 :         torture_comment(tctx, "Trying EnumAccounts partial listing (asking for 1 at 2)\n");
    2132           0 :         resume_handle = 2;
    2133           0 :         r.in.num_entries = 1;
    2134           0 :         r.out.sids = &sids2;
    2135             : 
    2136           0 :         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(b, tctx, &r),
    2137             :                 "EnumAccounts failed");
    2138           0 :         torture_assert_ntstatus_ok(tctx, r.out.result,
    2139             :                 "EnumAccounts failed");
    2140             : 
    2141           0 :         if (sids2.num_sids != 1) {
    2142           0 :                 torture_comment(tctx, "Returned wrong number of entries (%d)\n", sids2.num_sids);
    2143           0 :                 return false;
    2144             :         }
    2145             : 
    2146           0 :         return true;
    2147             : }
    2148             : 
    2149          93 : static bool test_LookupPrivDisplayName(struct dcerpc_binding_handle *b,
    2150             :                                        struct torture_context *tctx,
    2151             :                                        struct policy_handle *handle,
    2152             :                                        struct lsa_String *priv_name)
    2153             : {
    2154           0 :         struct lsa_LookupPrivDisplayName r;
    2155             :         /* produce a reasonable range of language output without screwing up
    2156             :            terminals */
    2157          93 :         uint16_t language_id = (random() % 4) + 0x409;
    2158          93 :         uint16_t returned_language_id = 0;
    2159          93 :         struct lsa_StringLarge *disp_name = NULL;
    2160             : 
    2161          93 :         torture_comment(tctx, "\nTesting LookupPrivDisplayName(%s)\n", priv_name->string);
    2162             : 
    2163          93 :         r.in.handle = handle;
    2164          93 :         r.in.name = priv_name;
    2165          93 :         r.in.language_id = language_id;
    2166          93 :         r.in.language_id_sys = 0;
    2167          93 :         r.out.returned_language_id = &returned_language_id;
    2168          93 :         r.out.disp_name = &disp_name;
    2169             : 
    2170          93 :         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupPrivDisplayName_r(b, tctx, &r),
    2171             :                 "LookupPrivDisplayName failed");
    2172          93 :         if (!NT_STATUS_IS_OK(r.out.result)) {
    2173           0 :                 torture_comment(tctx, "LookupPrivDisplayName failed - %s\n", nt_errstr(r.out.result));
    2174           0 :                 return false;
    2175             :         }
    2176          93 :         torture_comment(tctx, "%s -> \"%s\"  (language 0x%x/0x%x)\n",
    2177          93 :                priv_name->string, disp_name->string,
    2178          93 :                r.in.language_id, *r.out.returned_language_id);
    2179             : 
    2180          93 :         return true;
    2181             : }
    2182             : 
    2183          93 : static bool test_EnumAccountsWithUserRight(struct dcerpc_binding_handle *b,
    2184             :                                            struct torture_context *tctx,
    2185             :                                            struct policy_handle *handle,
    2186             :                                            struct lsa_String *priv_name)
    2187             : {
    2188           0 :         struct lsa_EnumAccountsWithUserRight r;
    2189           0 :         struct lsa_SidArray sids;
    2190             : 
    2191          93 :         ZERO_STRUCT(sids);
    2192             : 
    2193          93 :         torture_comment(tctx, "\nTesting EnumAccountsWithUserRight(%s)\n", priv_name->string);
    2194             : 
    2195          93 :         r.in.handle = handle;
    2196          93 :         r.in.name = priv_name;
    2197          93 :         r.out.sids = &sids;
    2198             : 
    2199          93 :         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountsWithUserRight_r(b, tctx, &r),
    2200             :                 "EnumAccountsWithUserRight failed");
    2201             : 
    2202             :         /* NT_STATUS_NO_MORE_ENTRIES means no one has this privilege */
    2203          93 :         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NO_MORE_ENTRIES)) {
    2204          12 :                 return true;
    2205             :         }
    2206             : 
    2207          81 :         if (!NT_STATUS_IS_OK(r.out.result)) {
    2208           0 :                 torture_comment(tctx, "EnumAccountsWithUserRight failed - %s\n", nt_errstr(r.out.result));
    2209           0 :                 return false;
    2210             :         }
    2211             : 
    2212          81 :         return true;
    2213             : }
    2214             : 
    2215             : 
    2216           5 : static bool test_EnumPrivs(struct dcerpc_binding_handle *b,
    2217             :                            struct torture_context *tctx,
    2218             :                            struct policy_handle *handle)
    2219             : {
    2220           0 :         struct lsa_EnumPrivs r;
    2221           0 :         struct lsa_PrivArray privs1;
    2222           5 :         uint32_t resume_handle = 0;
    2223           0 :         int i;
    2224           5 :         bool ret = true;
    2225             : 
    2226           5 :         torture_comment(tctx, "\nTesting EnumPrivs\n");
    2227             : 
    2228           5 :         r.in.handle = handle;
    2229           5 :         r.in.resume_handle = &resume_handle;
    2230           5 :         r.in.max_count = 100;
    2231           5 :         r.out.resume_handle = &resume_handle;
    2232           5 :         r.out.privs = &privs1;
    2233             : 
    2234           5 :         resume_handle = 0;
    2235           5 :         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumPrivs_r(b, tctx, &r),
    2236             :                 "EnumPrivs failed");
    2237           5 :         torture_assert_ntstatus_ok(tctx, r.out.result,
    2238             :                 "EnumPrivs failed");
    2239             : 
    2240          98 :         for (i = 0; i< privs1.count; i++) {
    2241          93 :                 test_LookupPrivDisplayName(b, tctx, handle, (struct lsa_String *)&privs1.privs[i].name);
    2242          93 :                 test_LookupPrivValue(b, tctx, handle, (struct lsa_String *)&privs1.privs[i].name);
    2243          93 :                 if (!test_EnumAccountsWithUserRight(b, tctx, handle, (struct lsa_String *)&privs1.privs[i].name)) {
    2244           0 :                         ret = false;
    2245             :                 }
    2246             :         }
    2247             : 
    2248           5 :         return ret;
    2249             : }
    2250             : 
    2251           0 : static bool test_QueryForestTrustInformation(struct dcerpc_binding_handle *b,
    2252             :                                              struct torture_context *tctx,
    2253             :                                              struct policy_handle *handle,
    2254             :                                              const char *trusted_domain_name)
    2255             : {
    2256           0 :         bool ret = true;
    2257           0 :         struct lsa_lsaRQueryForestTrustInformation r;
    2258           0 :         struct lsa_String string;
    2259           0 :         struct lsa_ForestTrustInformation info, *info_ptr;
    2260             : 
    2261           0 :         torture_comment(tctx, "\nTesting lsaRQueryForestTrustInformation\n");
    2262             : 
    2263           0 :         if (torture_setting_bool(tctx, "samba4", false)) {
    2264           0 :                 torture_comment(tctx, "skipping QueryForestTrustInformation against Samba4\n");
    2265           0 :                 return true;
    2266             :         }
    2267             : 
    2268           0 :         ZERO_STRUCT(string);
    2269             : 
    2270           0 :         if (trusted_domain_name) {
    2271           0 :                 init_lsa_String(&string, trusted_domain_name);
    2272             :         }
    2273             : 
    2274           0 :         info_ptr = &info;
    2275             : 
    2276           0 :         r.in.handle = handle;
    2277           0 :         r.in.trusted_domain_name = &string;
    2278           0 :         r.in.highest_record_type = LSA_FOREST_TRUST_TOP_LEVEL_NAME;
    2279           0 :         r.out.forest_trust_info = &info_ptr;
    2280             : 
    2281           0 :         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_lsaRQueryForestTrustInformation_r(b, tctx, &r),
    2282             :                 "lsaRQueryForestTrustInformation failed");
    2283             : 
    2284           0 :         if (!NT_STATUS_IS_OK(r.out.result)) {
    2285           0 :                 torture_comment(tctx, "lsaRQueryForestTrustInformation of %s failed - %s\n", trusted_domain_name, nt_errstr(r.out.result));
    2286           0 :                 ret = false;
    2287             :         }
    2288             : 
    2289           0 :         return ret;
    2290             : }
    2291             : 
    2292          36 : static bool test_query_each_TrustDomEx(struct dcerpc_binding_handle *b,
    2293             :                                        struct torture_context *tctx,
    2294             :                                        struct policy_handle *handle,
    2295             :                                        struct lsa_DomainListEx *domains)
    2296             : {
    2297           0 :         int i;
    2298          36 :         bool ret = true;
    2299             : 
    2300         180 :         for (i=0; i< domains->count; i++) {
    2301             : 
    2302         144 :                 if (domains->domains[i].trust_attributes & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
    2303           0 :                         ret &= test_QueryForestTrustInformation(b, tctx, handle,
    2304           0 :                                                                 domains->domains[i].domain_name.string);
    2305             :                 }
    2306             :         }
    2307             : 
    2308          36 :         return ret;
    2309             : }
    2310             : 
    2311          36 : static bool test_query_each_TrustDom(struct dcerpc_binding_handle *b,
    2312             :                                      struct torture_context *tctx,
    2313             :                                      struct policy_handle *handle,
    2314             :                                      struct lsa_DomainList *domains)
    2315             : {
    2316           0 :         int i,j;
    2317          36 :         bool ret = true;
    2318             : 
    2319          36 :         torture_comment(tctx, "\nTesting OpenTrustedDomain, OpenTrustedDomainByName and QueryInfoTrustedDomain\n");
    2320         180 :         for (i=0; i< domains->count; i++) {
    2321           0 :                 struct lsa_OpenTrustedDomain trust;
    2322           0 :                 struct lsa_OpenTrustedDomainByName trust_by_name;
    2323           0 :                 struct policy_handle trustdom_handle;
    2324           0 :                 struct policy_handle handle2;
    2325           0 :                 struct lsa_Close c;
    2326           0 :                 struct lsa_CloseTrustedDomainEx c_trust;
    2327         144 :                 int levels [] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
    2328         144 :                 int ok[]      = {1, 0, 1, 0, 0, 1, 0, 1, 0,  0,  0,  1, 1};
    2329             : 
    2330         144 :                 if (domains->domains[i].sid) {
    2331         144 :                         trust.in.handle = handle;
    2332         144 :                         trust.in.sid = domains->domains[i].sid;
    2333         144 :                         trust.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    2334         144 :                         trust.out.trustdom_handle = &trustdom_handle;
    2335             : 
    2336         144 :                         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenTrustedDomain_r(b, tctx, &trust),
    2337             :                                 "OpenTrustedDomain failed");
    2338             : 
    2339         144 :                         if (NT_STATUS_EQUAL(trust.out.result, NT_STATUS_NO_SUCH_DOMAIN)) {
    2340           0 :                                 torture_comment(tctx, "DOMAIN(%s, %s) not a direct trust?\n",
    2341           0 :                                                 domains->domains[i].name.string,
    2342           0 :                                                 dom_sid_string(tctx, domains->domains[i].sid));
    2343           0 :                                 continue;
    2344             :                         }
    2345         144 :                         if (!NT_STATUS_IS_OK(trust.out.result)) {
    2346           0 :                                 torture_comment(tctx, "OpenTrustedDomain failed - %s\n", nt_errstr(trust.out.result));
    2347           0 :                                 return false;
    2348             :                         }
    2349             : 
    2350         144 :                         c.in.handle = &trustdom_handle;
    2351         144 :                         c.out.handle = &handle2;
    2352             : 
    2353         144 :                         c_trust.in.handle = &trustdom_handle;
    2354         144 :                         c_trust.out.handle = &handle2;
    2355             : 
    2356        2016 :                         for (j=0; j < ARRAY_SIZE(levels); j++) {
    2357           0 :                                 struct lsa_QueryTrustedDomainInfo q;
    2358        1872 :                                 union lsa_TrustedDomainInfo *info = NULL;
    2359        1872 :                                 q.in.trustdom_handle = &trustdom_handle;
    2360        1872 :                                 q.in.level = levels[j];
    2361        1872 :                                 q.out.info = &info;
    2362        1872 :                                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryTrustedDomainInfo_r(b, tctx, &q),
    2363             :                                         "QueryTrustedDomainInfo failed");
    2364        1872 :                                 if (!NT_STATUS_IS_OK(q.out.result) && ok[j]) {
    2365           0 :                                         torture_comment(tctx, "QueryTrustedDomainInfo level %d failed - %s\n",
    2366             :                                                levels[j], nt_errstr(q.out.result));
    2367           0 :                                         ret = false;
    2368        1872 :                                 } else if (NT_STATUS_IS_OK(q.out.result) && !ok[j]) {
    2369           0 :                                         torture_comment(tctx, "QueryTrustedDomainInfo level %d unexpectedly succeeded - %s\n",
    2370             :                                                levels[j], nt_errstr(q.out.result));
    2371           0 :                                         ret = false;
    2372             :                                 }
    2373             :                         }
    2374             : 
    2375         144 :                         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_CloseTrustedDomainEx_r(b, tctx, &c_trust),
    2376             :                                 "CloseTrustedDomainEx failed");
    2377         144 :                         if (!NT_STATUS_EQUAL(c_trust.out.result, NT_STATUS_NOT_IMPLEMENTED)) {
    2378           0 :                                 torture_comment(tctx, "Expected CloseTrustedDomainEx to return NT_STATUS_NOT_IMPLEMENTED, instead - %s\n", nt_errstr(c_trust.out.result));
    2379           0 :                                 return false;
    2380             :                         }
    2381             : 
    2382         144 :                         c.in.handle = &trustdom_handle;
    2383         144 :                         c.out.handle = &handle2;
    2384             : 
    2385         144 :                         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_Close_r(b, tctx, &c),
    2386             :                                 "Close failed");
    2387         144 :                         if (!NT_STATUS_IS_OK(c.out.result)) {
    2388           0 :                                 torture_comment(tctx, "Close of trusted domain failed - %s\n", nt_errstr(c.out.result));
    2389           0 :                                 return false;
    2390             :                         }
    2391             : 
    2392        2016 :                         for (j=0; j < ARRAY_SIZE(levels); j++) {
    2393           0 :                                 struct lsa_QueryTrustedDomainInfoBySid q;
    2394        1872 :                                 union lsa_TrustedDomainInfo *info = NULL;
    2395             : 
    2396        1872 :                                 if (!domains->domains[i].sid) {
    2397           0 :                                         continue;
    2398             :                                 }
    2399             : 
    2400        1872 :                                 q.in.handle  = handle;
    2401        1872 :                                 q.in.dom_sid = domains->domains[i].sid;
    2402        1872 :                                 q.in.level   = levels[j];
    2403        1872 :                                 q.out.info   = &info;
    2404             : 
    2405        1872 :                                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryTrustedDomainInfoBySid_r(b, tctx, &q),
    2406             :                                         "lsa_QueryTrustedDomainInfoBySid failed");
    2407        1872 :                                 if (!NT_STATUS_IS_OK(q.out.result) && ok[j]) {
    2408           0 :                                         torture_comment(tctx, "QueryTrustedDomainInfoBySid level %d failed - %s\n",
    2409             :                                                levels[j], nt_errstr(q.out.result));
    2410           0 :                                         ret = false;
    2411        1872 :                                 } else if (NT_STATUS_IS_OK(q.out.result) && !ok[j]) {
    2412           0 :                                         torture_comment(tctx, "QueryTrustedDomainInfoBySid level %d unexpectedly succeeded - %s\n",
    2413             :                                                levels[j], nt_errstr(q.out.result));
    2414           0 :                                         ret = false;
    2415             :                                 }
    2416             :                         }
    2417             :                 }
    2418             : 
    2419         144 :                 trust_by_name.in.handle = handle;
    2420         144 :                 trust_by_name.in.name.string = domains->domains[i].name.string;
    2421         144 :                 trust_by_name.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    2422         144 :                 trust_by_name.out.trustdom_handle = &trustdom_handle;
    2423             : 
    2424         144 :                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenTrustedDomainByName_r(b, tctx, &trust_by_name),
    2425             :                         "OpenTrustedDomainByName failed");
    2426             : 
    2427         144 :                 if (NT_STATUS_EQUAL(trust_by_name.out.result, NT_STATUS_NO_SUCH_DOMAIN)) {
    2428           0 :                         torture_comment(tctx, "DOMAIN(%s, %s) not a direct trust?\n",
    2429           0 :                                         domains->domains[i].name.string,
    2430           0 :                                         dom_sid_string(tctx, domains->domains[i].sid));
    2431           0 :                         continue;
    2432             :                 }
    2433         144 :                 if (!NT_STATUS_IS_OK(trust_by_name.out.result)) {
    2434           0 :                         torture_comment(tctx, "OpenTrustedDomainByName failed - %s\n", nt_errstr(trust_by_name.out.result));
    2435           0 :                         return false;
    2436             :                 }
    2437             : 
    2438        2016 :                 for (j=0; j < ARRAY_SIZE(levels); j++) {
    2439           0 :                         struct lsa_QueryTrustedDomainInfo q;
    2440        1872 :                         union lsa_TrustedDomainInfo *info = NULL;
    2441        1872 :                         q.in.trustdom_handle = &trustdom_handle;
    2442        1872 :                         q.in.level = levels[j];
    2443        1872 :                         q.out.info = &info;
    2444        1872 :                         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryTrustedDomainInfo_r(b, tctx, &q),
    2445             :                                 "QueryTrustedDomainInfo failed");
    2446        1872 :                         if (!NT_STATUS_IS_OK(q.out.result) && ok[j]) {
    2447           0 :                                 torture_comment(tctx, "QueryTrustedDomainInfo level %d failed - %s\n",
    2448             :                                        levels[j], nt_errstr(q.out.result));
    2449           0 :                                 ret = false;
    2450        1872 :                         } else if (NT_STATUS_IS_OK(q.out.result) && !ok[j]) {
    2451           0 :                                 torture_comment(tctx, "QueryTrustedDomainInfo level %d unexpectedly succeeded - %s\n",
    2452             :                                        levels[j], nt_errstr(q.out.result));
    2453           0 :                                 ret = false;
    2454             :                         }
    2455             :                 }
    2456             : 
    2457         144 :                 c.in.handle = &trustdom_handle;
    2458         144 :                 c.out.handle = &handle2;
    2459             : 
    2460         144 :                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_Close_r(b, tctx, &c),
    2461             :                         "Close failed");
    2462         144 :                 if (!NT_STATUS_IS_OK(c.out.result)) {
    2463           0 :                         torture_comment(tctx, "Close of trusted domain failed - %s\n", nt_errstr(c.out.result));
    2464           0 :                         return false;
    2465             :                 }
    2466             : 
    2467        2016 :                 for (j=0; j < ARRAY_SIZE(levels); j++) {
    2468           0 :                         struct lsa_QueryTrustedDomainInfoByName q;
    2469        1872 :                         union lsa_TrustedDomainInfo *info = NULL;
    2470           0 :                         struct lsa_String name;
    2471             : 
    2472        1872 :                         name.string = domains->domains[i].name.string;
    2473             : 
    2474        1872 :                         q.in.handle         = handle;
    2475        1872 :                         q.in.trusted_domain = &name;
    2476        1872 :                         q.in.level          = levels[j];
    2477        1872 :                         q.out.info          = &info;
    2478        1872 :                         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryTrustedDomainInfoByName_r(b, tctx, &q),
    2479             :                                 "QueryTrustedDomainInfoByName failed");
    2480        1872 :                         if (!NT_STATUS_IS_OK(q.out.result) && ok[j]) {
    2481           0 :                                 torture_comment(tctx, "QueryTrustedDomainInfoByName level %d failed - %s\n",
    2482             :                                        levels[j], nt_errstr(q.out.result));
    2483           0 :                                 ret = false;
    2484        1872 :                         } else if (NT_STATUS_IS_OK(q.out.result) && !ok[j]) {
    2485           0 :                                 torture_comment(tctx, "QueryTrustedDomainInfoByName level %d unexpectedly succeeded - %s\n",
    2486             :                                        levels[j], nt_errstr(q.out.result));
    2487           0 :                                 ret = false;
    2488             :                         }
    2489             :                 }
    2490             :         }
    2491          36 :         return ret;
    2492             : }
    2493             : 
    2494          15 : static bool test_EnumTrustDom(struct dcerpc_binding_handle *b,
    2495             :                               struct torture_context *tctx,
    2496             :                               struct policy_handle *handle)
    2497             : {
    2498           0 :         struct lsa_EnumTrustDom r;
    2499          15 :         uint32_t in_resume_handle = 0;
    2500           0 :         uint32_t out_resume_handle;
    2501           0 :         struct lsa_DomainList domains;
    2502          15 :         bool ret = true;
    2503             : 
    2504          15 :         torture_comment(tctx, "\nTesting EnumTrustDom\n");
    2505             : 
    2506          15 :         r.in.handle = handle;
    2507          15 :         r.in.resume_handle = &in_resume_handle;
    2508          15 :         r.in.max_size = 0;
    2509          15 :         r.out.domains = &domains;
    2510          15 :         r.out.resume_handle = &out_resume_handle;
    2511             : 
    2512          15 :         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumTrustDom_r(b, tctx, &r),
    2513             :                 "lsa_EnumTrustDom failed");
    2514             : 
    2515             :         /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
    2516             :          * always be larger than the previous input resume handle, in
    2517             :          * particular when hitting the last query it is vital to set the
    2518             :          * resume handle correctly to avoid infinite client loops, as
    2519             :          * seen e.g.  with Windows XP SP3 when resume handle is 0 and
    2520             :          * status is NT_STATUS_OK - gd */
    2521             : 
    2522          15 :         if (NT_STATUS_IS_OK(r.out.result) ||
    2523          15 :             NT_STATUS_EQUAL(r.out.result, NT_STATUS_NO_MORE_ENTRIES) ||
    2524          12 :             NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
    2525             :         {
    2526          15 :                 if (out_resume_handle <= in_resume_handle) {
    2527           0 :                         torture_comment(tctx, "EnumTrustDom failed - should have returned output resume_handle (0x%08x) larger than input resume handle (0x%08x)\n",
    2528             :                                 out_resume_handle, in_resume_handle);
    2529           0 :                         return false;
    2530             :                 }
    2531             :         }
    2532             : 
    2533          15 :         if (NT_STATUS_IS_OK(r.out.result)) {
    2534           0 :                 if (domains.count == 0) {
    2535           0 :                         torture_comment(tctx, "EnumTrustDom failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
    2536           0 :                         return false;
    2537             :                 }
    2538          15 :         } else if (!(NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) || NT_STATUS_EQUAL(r.out.result, NT_STATUS_NO_MORE_ENTRIES))) {
    2539           0 :                 torture_comment(tctx, "EnumTrustDom of zero size failed - %s\n", nt_errstr(r.out.result));
    2540           0 :                 return false;
    2541             :         }
    2542             : 
    2543             :         /* Start from the bottom again */
    2544          15 :         in_resume_handle = 0;
    2545             : 
    2546           0 :         do {
    2547          39 :                 r.in.handle = handle;
    2548          39 :                 r.in.resume_handle = &in_resume_handle;
    2549          39 :                 r.in.max_size = LSA_ENUM_TRUST_DOMAIN_MULTIPLIER * 3;
    2550          39 :                 r.out.domains = &domains;
    2551          39 :                 r.out.resume_handle = &out_resume_handle;
    2552             : 
    2553          39 :                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumTrustDom_r(b, tctx, &r),
    2554             :                         "EnumTrustDom failed");
    2555             : 
    2556             :                 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
    2557             :                  * always be larger than the previous input resume handle, in
    2558             :                  * particular when hitting the last query it is vital to set the
    2559             :                  * resume handle correctly to avoid infinite client loops, as
    2560             :                  * seen e.g.  with Windows XP SP3 when resume handle is 0 and
    2561             :                  * status is NT_STATUS_OK - gd */
    2562             : 
    2563          39 :                 if (NT_STATUS_IS_OK(r.out.result) ||
    2564          27 :                     NT_STATUS_EQUAL(r.out.result, NT_STATUS_NO_MORE_ENTRIES) ||
    2565          24 :                     NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
    2566             :                 {
    2567          39 :                         if (out_resume_handle <= in_resume_handle) {
    2568           0 :                                 torture_comment(tctx, "EnumTrustDom failed - should have returned output resume_handle (0x%08x) larger than input resume handle (0x%08x)\n",
    2569             :                                         out_resume_handle, in_resume_handle);
    2570           0 :                                 return false;
    2571             :                         }
    2572             :                 }
    2573             : 
    2574             :                 /* NO_MORE_ENTRIES is allowed */
    2575          39 :                 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NO_MORE_ENTRIES)) {
    2576           3 :                         if (domains.count == 0) {
    2577           3 :                                 return true;
    2578             :                         }
    2579           0 :                         torture_comment(tctx, "EnumTrustDom failed - should have returned 0 trusted domains with 'NT_STATUS_NO_MORE_ENTRIES'\n");
    2580           0 :                         return false;
    2581          36 :                 } else if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES)) {
    2582             :                         /* Windows 2003 gets this off by one on the first run */
    2583          24 :                         if (r.out.domains->count < 3 || r.out.domains->count > 4) {
    2584           0 :                                 torture_comment(tctx, "EnumTrustDom didn't fill the buffer we "
    2585             :                                        "asked it to (got %d, expected %d / %d == %d entries)\n",
    2586           0 :                                        r.out.domains->count, LSA_ENUM_TRUST_DOMAIN_MULTIPLIER * 3,
    2587             :                                        LSA_ENUM_TRUST_DOMAIN_MULTIPLIER, r.in.max_size);
    2588           0 :                                 ret = false;
    2589             :                         }
    2590          12 :                 } else if (!NT_STATUS_IS_OK(r.out.result)) {
    2591           0 :                         torture_comment(tctx, "EnumTrustDom failed - %s\n", nt_errstr(r.out.result));
    2592           0 :                         return false;
    2593             :                 }
    2594             : 
    2595          36 :                 if (domains.count == 0) {
    2596           0 :                         torture_comment(tctx, "EnumTrustDom failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
    2597           0 :                         return false;
    2598             :                 }
    2599             : 
    2600          36 :                 ret &= test_query_each_TrustDom(b, tctx, handle, &domains);
    2601             : 
    2602          36 :                 in_resume_handle = out_resume_handle;
    2603             : 
    2604          36 :         } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
    2605             : 
    2606          12 :         return ret;
    2607             : }
    2608             : 
    2609          15 : static bool test_EnumTrustDomEx(struct dcerpc_binding_handle *b,
    2610             :                                 struct torture_context *tctx,
    2611             :                                 struct policy_handle *handle)
    2612             : {
    2613           0 :         struct lsa_EnumTrustedDomainsEx r_ex;
    2614          15 :         uint32_t in_resume_handle = 0;
    2615           0 :         uint32_t out_resume_handle;
    2616           0 :         struct lsa_DomainListEx domains_ex;
    2617          15 :         bool ret = true;
    2618             : 
    2619          15 :         torture_comment(tctx, "\nTesting EnumTrustedDomainsEx\n");
    2620             : 
    2621          15 :         r_ex.in.handle = handle;
    2622          15 :         r_ex.in.resume_handle = &in_resume_handle;
    2623          15 :         r_ex.in.max_size = 0;
    2624          15 :         r_ex.out.domains = &domains_ex;
    2625          15 :         r_ex.out.resume_handle = &out_resume_handle;
    2626             : 
    2627          15 :         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumTrustedDomainsEx_r(b, tctx, &r_ex),
    2628             :                 "EnumTrustedDomainsEx failed");
    2629             : 
    2630             :         /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
    2631             :          * always be larger than the previous input resume handle, in
    2632             :          * particular when hitting the last query it is vital to set the
    2633             :          * resume handle correctly to avoid infinite client loops, as
    2634             :          * seen e.g.  with Windows XP SP3 when resume handle is 0 and
    2635             :          * status is NT_STATUS_OK - gd */
    2636             : 
    2637          15 :         if (NT_STATUS_IS_OK(r_ex.out.result) ||
    2638          15 :             NT_STATUS_EQUAL(r_ex.out.result, NT_STATUS_NO_MORE_ENTRIES) ||
    2639          12 :             NT_STATUS_EQUAL(r_ex.out.result, STATUS_MORE_ENTRIES))
    2640             :         {
    2641          15 :                 if (out_resume_handle <= in_resume_handle) {
    2642           0 :                         torture_comment(tctx, "EnumTrustDomEx failed - should have returned output resume_handle (0x%08x) larger than input resume handle (0x%08x)\n",
    2643             :                                 out_resume_handle, in_resume_handle);
    2644           0 :                         return false;
    2645             :                 }
    2646             :         }
    2647             : 
    2648          15 :         if (NT_STATUS_IS_OK(r_ex.out.result)) {
    2649           0 :                 if (domains_ex.count == 0) {
    2650           0 :                         torture_comment(tctx, "EnumTrustDom failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
    2651           0 :                         return false;
    2652             :                 }
    2653          15 :         } else if (!(NT_STATUS_EQUAL(r_ex.out.result, STATUS_MORE_ENTRIES) ||
    2654           3 :                     NT_STATUS_EQUAL(r_ex.out.result, NT_STATUS_NO_MORE_ENTRIES))) {
    2655           0 :                 torture_comment(tctx, "EnumTrustDom of zero size failed - %s\n",
    2656             :                                 nt_errstr(r_ex.out.result));
    2657           0 :                 return false;
    2658             :         }
    2659             : 
    2660          15 :         in_resume_handle = 0;
    2661           0 :         do {
    2662          39 :                 r_ex.in.handle = handle;
    2663          39 :                 r_ex.in.resume_handle = &in_resume_handle;
    2664          39 :                 r_ex.in.max_size = LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER * 3;
    2665          39 :                 r_ex.out.domains = &domains_ex;
    2666          39 :                 r_ex.out.resume_handle = &out_resume_handle;
    2667             : 
    2668          39 :                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumTrustedDomainsEx_r(b, tctx, &r_ex),
    2669             :                         "EnumTrustedDomainsEx failed");
    2670             : 
    2671          39 :                 in_resume_handle = out_resume_handle;
    2672             : 
    2673             :                 /* NO_MORE_ENTRIES is allowed */
    2674          39 :                 if (NT_STATUS_EQUAL(r_ex.out.result, NT_STATUS_NO_MORE_ENTRIES)) {
    2675           3 :                         if (domains_ex.count == 0) {
    2676           3 :                                 return true;
    2677             :                         }
    2678           0 :                         torture_comment(tctx, "EnumTrustDomainsEx failed - should have returned 0 trusted domains with 'NT_STATUS_NO_MORE_ENTRIES'\n");
    2679           0 :                         return false;
    2680          36 :                 } else if (NT_STATUS_EQUAL(r_ex.out.result, STATUS_MORE_ENTRIES)) {
    2681             :                         /* Windows 2003 gets this off by one on the first run */
    2682          24 :                         if (r_ex.out.domains->count < 3 || r_ex.out.domains->count > 4) {
    2683           0 :                                 torture_comment(tctx, "EnumTrustDom didn't fill the buffer we "
    2684             :                                        "asked it to (got %d, expected %d / %d == %d entries)\n",
    2685           0 :                                        r_ex.out.domains->count,
    2686             :                                        r_ex.in.max_size,
    2687             :                                        LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER,
    2688           0 :                                        r_ex.in.max_size / LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER);
    2689             :                         }
    2690          12 :                 } else if (!NT_STATUS_IS_OK(r_ex.out.result)) {
    2691           0 :                         torture_comment(tctx, "EnumTrustedDomainEx failed - %s\n", nt_errstr(r_ex.out.result));
    2692           0 :                         return false;
    2693             :                 }
    2694             : 
    2695          36 :                 if (domains_ex.count == 0) {
    2696           0 :                         torture_comment(tctx, "EnumTrustDomainEx failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
    2697           0 :                         return false;
    2698             :                 }
    2699             : 
    2700          36 :                 ret &= test_query_each_TrustDomEx(b, tctx, handle, &domains_ex);
    2701             : 
    2702          36 :         } while (NT_STATUS_EQUAL(r_ex.out.result, STATUS_MORE_ENTRIES));
    2703             : 
    2704          12 :         return ret;
    2705             : }
    2706             : 
    2707             : 
    2708           3 : static bool test_CreateTrustedDomain(struct dcerpc_binding_handle *b,
    2709             :                                      struct torture_context *tctx,
    2710             :                                      struct policy_handle *handle,
    2711             :                                      uint32_t num_trusts)
    2712             : {
    2713           3 :         bool ret = true;
    2714           0 :         struct lsa_CreateTrustedDomain r;
    2715           0 :         struct lsa_DomainInfo trustinfo;
    2716           0 :         struct dom_sid **domsid;
    2717           0 :         struct policy_handle *trustdom_handle;
    2718           0 :         struct lsa_QueryTrustedDomainInfo q;
    2719           3 :         union lsa_TrustedDomainInfo *info = NULL;
    2720           0 :         int i;
    2721             : 
    2722           3 :         torture_comment(tctx, "\nTesting CreateTrustedDomain for %d domains\n", num_trusts);
    2723             : 
    2724           3 :         if (!test_EnumTrustDom(b, tctx, handle)) {
    2725           0 :                 ret = false;
    2726             :         }
    2727             : 
    2728           3 :         if (!test_EnumTrustDomEx(b, tctx, handle)) {
    2729           0 :                 ret = false;
    2730             :         }
    2731             : 
    2732           3 :         domsid = talloc_array(tctx, struct dom_sid *, num_trusts);
    2733           3 :         trustdom_handle = talloc_array(tctx, struct policy_handle, num_trusts);
    2734             : 
    2735          39 :         for (i=0; i< num_trusts; i++) {
    2736          36 :                 char *trust_name = talloc_asprintf(tctx, "TORTURE1%02d", i);
    2737          36 :                 char *trust_sid = talloc_asprintf(tctx, "S-1-5-21-97398-379795-1%02d", i);
    2738             : 
    2739          36 :                 domsid[i] = dom_sid_parse_talloc(tctx, trust_sid);
    2740             : 
    2741          36 :                 trustinfo.sid = domsid[i];
    2742          36 :                 init_lsa_String((struct lsa_String *)&trustinfo.name, trust_name);
    2743             : 
    2744          36 :                 r.in.policy_handle = handle;
    2745          36 :                 r.in.info = &trustinfo;
    2746          36 :                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    2747          36 :                 r.out.trustdom_handle = &trustdom_handle[i];
    2748             : 
    2749          36 :                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_CreateTrustedDomain_r(b, tctx, &r),
    2750             :                         "CreateTrustedDomain failed");
    2751          36 :                 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_OBJECT_NAME_COLLISION)) {
    2752           0 :                         test_DeleteTrustedDomain(b, tctx, handle, trustinfo.name);
    2753           0 :                         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_CreateTrustedDomain_r(b, tctx, &r),
    2754             :                                 "CreateTrustedDomain failed");
    2755             :                 }
    2756          36 :                 if (!NT_STATUS_IS_OK(r.out.result)) {
    2757           0 :                         torture_comment(tctx, "CreateTrustedDomain failed - %s\n", nt_errstr(r.out.result));
    2758           0 :                         ret = false;
    2759             :                 } else {
    2760             : 
    2761          36 :                         q.in.trustdom_handle = &trustdom_handle[i];
    2762          36 :                         q.in.level = LSA_TRUSTED_DOMAIN_INFO_INFO_EX;
    2763          36 :                         q.out.info = &info;
    2764          36 :                         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryTrustedDomainInfo_r(b, tctx, &q),
    2765             :                                 "QueryTrustedDomainInfo failed");
    2766          36 :                         if (!NT_STATUS_IS_OK(q.out.result)) {
    2767           0 :                                 torture_comment(tctx, "QueryTrustedDomainInfo level %d failed - %s\n", q.in.level, nt_errstr(q.out.result));
    2768           0 :                                 ret = false;
    2769          36 :                         } else if (!q.out.info) {
    2770           0 :                                 ret = false;
    2771             :                         } else {
    2772          36 :                                 if (strcmp(info->info_ex.domain_name.string, trustinfo.name.string) != 0) {
    2773           0 :                                         torture_comment(tctx, "QueryTrustedDomainInfo returned inconsistent long name: %s != %s\n",
    2774           0 :                                                info->info_ex.domain_name.string, trustinfo.name.string);
    2775           0 :                                         ret = false;
    2776             :                                 }
    2777          36 :                                 if (strcmp(info->info_ex.netbios_name.string, trustinfo.name.string) != 0) {
    2778           0 :                                         torture_comment(tctx, "QueryTrustedDomainInfo returned inconsistent short name: %s != %s\n",
    2779           0 :                                                info->info_ex.netbios_name.string, trustinfo.name.string);
    2780           0 :                                         ret = false;
    2781             :                                 }
    2782          36 :                                 if (info->info_ex.trust_type != LSA_TRUST_TYPE_DOWNLEVEL) {
    2783           0 :                                         torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust type %d != %d\n",
    2784           0 :                                                trust_name, info->info_ex.trust_type, LSA_TRUST_TYPE_DOWNLEVEL);
    2785           0 :                                         ret = false;
    2786             :                                 }
    2787          36 :                                 if (info->info_ex.trust_attributes != 0) {
    2788           0 :                                         torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust attributes %d != %d\n",
    2789           0 :                                                trust_name, info->info_ex.trust_attributes, 0);
    2790           0 :                                         ret = false;
    2791             :                                 }
    2792          36 :                                 if (info->info_ex.trust_direction != LSA_TRUST_DIRECTION_OUTBOUND) {
    2793           0 :                                         torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust direction %d != %d\n",
    2794           0 :                                                trust_name, info->info_ex.trust_direction, LSA_TRUST_DIRECTION_OUTBOUND);
    2795           0 :                                         ret = false;
    2796             :                                 }
    2797             :                         }
    2798             :                 }
    2799             :         }
    2800             : 
    2801             :         /* now that we have some domains to look over, we can test the enum calls */
    2802           3 :         if (!test_EnumTrustDom(b, tctx, handle)) {
    2803           0 :                 ret = false;
    2804             :         }
    2805             : 
    2806           3 :         if (!test_EnumTrustDomEx(b, tctx, handle)) {
    2807           0 :                 ret = false;
    2808             :         }
    2809             : 
    2810          39 :         for (i=0; i<num_trusts; i++) {
    2811          36 :                 if (!test_DeleteTrustedDomainBySid(b, tctx, handle, domsid[i])) {
    2812           0 :                         ret = false;
    2813             :                 }
    2814             :         }
    2815             : 
    2816           3 :         return ret;
    2817             : }
    2818             : 
    2819          36 : static bool gen_authinfo(TALLOC_CTX *mem_ctx,
    2820             :                          const char *incoming_old, const char *incoming_new,
    2821             :                          const char *outgoing_old, const char *outgoing_new,
    2822             :                          struct lsa_TrustDomainInfoAuthInfo **_authinfo)
    2823             : {
    2824           0 :         struct lsa_TrustDomainInfoAuthInfo *authinfo;
    2825           0 :         struct lsa_TrustDomainInfoBuffer *in_buffer;
    2826           0 :         struct lsa_TrustDomainInfoBuffer *io_buffer;
    2827           0 :         struct lsa_TrustDomainInfoBuffer *on_buffer;
    2828           0 :         struct lsa_TrustDomainInfoBuffer *oo_buffer;
    2829           0 :         size_t converted_size;
    2830           0 :         bool ok;
    2831             : 
    2832          36 :         authinfo = talloc_zero(mem_ctx, struct lsa_TrustDomainInfoAuthInfo);
    2833          36 :         if (authinfo == NULL) {
    2834           0 :                 return false;
    2835             :         }
    2836             : 
    2837          36 :         in_buffer = talloc_zero(authinfo, struct lsa_TrustDomainInfoBuffer);
    2838          36 :         if (in_buffer == NULL) {
    2839           0 :                 return false;
    2840             :         }
    2841          36 :         in_buffer->AuthType = TRUST_AUTH_TYPE_CLEAR;
    2842          36 :         ok = convert_string_talloc(in_buffer, CH_UNIX, CH_UTF16,
    2843             :                                    incoming_new,
    2844             :                                    strlen(incoming_new),
    2845          36 :                                    &in_buffer->data.data,
    2846             :                                    &converted_size);
    2847          36 :         if (!ok) {
    2848           0 :                 return false;
    2849             :         }
    2850          36 :         in_buffer->data.size = converted_size;
    2851             : 
    2852          36 :         io_buffer = talloc_zero(authinfo, struct lsa_TrustDomainInfoBuffer);
    2853          36 :         if (io_buffer == NULL) {
    2854           0 :                 return false;
    2855             :         }
    2856          36 :         io_buffer->AuthType = TRUST_AUTH_TYPE_CLEAR;
    2857          36 :         ok = convert_string_talloc(io_buffer, CH_UNIX, CH_UTF16,
    2858             :                                    incoming_old,
    2859             :                                    strlen(incoming_old),
    2860          36 :                                    &io_buffer->data.data,
    2861             :                                    &converted_size);
    2862          36 :         if (!ok) {
    2863           0 :                 return false;
    2864             :         }
    2865          36 :         io_buffer->data.size = converted_size;
    2866             : 
    2867          36 :         on_buffer = talloc_zero(authinfo, struct lsa_TrustDomainInfoBuffer);
    2868          36 :         if (on_buffer == NULL) {
    2869           0 :                 return false;
    2870             :         }
    2871          36 :         on_buffer->AuthType = TRUST_AUTH_TYPE_CLEAR;
    2872          36 :         ok = convert_string_talloc(on_buffer, CH_UNIX, CH_UTF16,
    2873             :                                    outgoing_new,
    2874             :                                    strlen(outgoing_new),
    2875          36 :                                    &on_buffer->data.data,
    2876             :                                    &converted_size);
    2877          36 :         if (!ok) {
    2878           0 :                 return false;
    2879             :         }
    2880          36 :         on_buffer->data.size = converted_size;
    2881             : 
    2882          36 :         oo_buffer = talloc_zero(authinfo, struct lsa_TrustDomainInfoBuffer);
    2883          36 :         if (oo_buffer == NULL) {
    2884           0 :                 return false;
    2885             :         }
    2886          36 :         oo_buffer->AuthType = TRUST_AUTH_TYPE_CLEAR;
    2887          36 :         ok = convert_string_talloc(oo_buffer, CH_UNIX, CH_UTF16,
    2888             :                                    outgoing_old,
    2889             :                                    strlen(outgoing_old),
    2890          36 :                                    &oo_buffer->data.data,
    2891             :                                    &converted_size);
    2892          36 :         if (!ok) {
    2893           0 :                 return false;
    2894             :         }
    2895          36 :         oo_buffer->data.size = converted_size;
    2896             : 
    2897          36 :         authinfo->incoming_count = 1;
    2898          36 :         authinfo->incoming_current_auth_info = in_buffer;
    2899          36 :         authinfo->incoming_previous_auth_info = io_buffer;
    2900          36 :         authinfo->outgoing_count = 1;
    2901          36 :         authinfo->outgoing_current_auth_info = on_buffer;
    2902          36 :         authinfo->outgoing_previous_auth_info = oo_buffer;
    2903             : 
    2904          36 :         *_authinfo = authinfo;
    2905             : 
    2906          36 :         return true;
    2907             : }
    2908             : 
    2909         252 : static bool check_pw_with_ServerAuthenticate3(struct dcerpc_pipe *p,
    2910             :                                              struct torture_context *tctx,
    2911             :                                              uint32_t negotiate_flags,
    2912             :                                              const char *server_name,
    2913             :                                              struct cli_credentials *machine_credentials,
    2914             :                                              struct netlogon_creds_CredentialState **creds_out)
    2915             : {
    2916           0 :         struct netr_ServerReqChallenge r;
    2917           0 :         struct netr_ServerAuthenticate3 a;
    2918           0 :         struct netr_Credential credentials1, credentials2, credentials3;
    2919           0 :         struct netlogon_creds_CredentialState *creds;
    2920         252 :         const struct samr_Password *new_password = NULL;
    2921         252 :         const struct samr_Password *old_password = NULL;
    2922           0 :         uint32_t rid;
    2923         252 :         struct dcerpc_binding_handle *b = p->binding_handle;
    2924             : 
    2925         252 :         new_password = cli_credentials_get_nt_hash(machine_credentials, tctx);
    2926         252 :         old_password = cli_credentials_get_old_nt_hash(machine_credentials, tctx);
    2927             : 
    2928         252 :         r.in.server_name = server_name;
    2929         252 :         r.in.computer_name = cli_credentials_get_workstation(machine_credentials);
    2930         252 :         r.in.credentials = &credentials1;
    2931         252 :         r.out.return_credentials = &credentials2;
    2932             : 
    2933         252 :         netlogon_creds_random_challenge(&credentials1);
    2934             : 
    2935         252 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
    2936             :                 "ServerReqChallenge failed");
    2937         252 :         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
    2938             : 
    2939         252 :         a.in.server_name = server_name;
    2940         252 :         a.in.account_name = cli_credentials_get_username(machine_credentials);
    2941         252 :         a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
    2942         252 :         a.in.computer_name = cli_credentials_get_workstation(machine_credentials);
    2943         252 :         a.in.negotiate_flags = &negotiate_flags;
    2944         252 :         a.in.credentials = &credentials3;
    2945         252 :         a.out.return_credentials = &credentials3;
    2946         252 :         a.out.negotiate_flags = &negotiate_flags;
    2947         252 :         a.out.rid = &rid;
    2948             : 
    2949         252 :         creds = netlogon_creds_client_init(tctx, a.in.account_name,
    2950             :                                            a.in.computer_name,
    2951         252 :                                            a.in.secure_channel_type,
    2952             :                                            &credentials1, &credentials2,
    2953             :                                            new_password, &credentials3,
    2954             :                                            negotiate_flags);
    2955             : 
    2956         252 :         torture_assert(tctx, creds != NULL, "memory allocation");
    2957             : 
    2958         252 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
    2959             :                 "ServerAuthenticate3 failed");
    2960         252 :         if (!NT_STATUS_IS_OK(a.out.result)) {
    2961          36 :                 if (!NT_STATUS_EQUAL(a.out.result, NT_STATUS_ACCESS_DENIED)) {
    2962           0 :                         torture_assert_ntstatus_ok(tctx, a.out.result,
    2963             :                                                    "ServerAuthenticate3 failed");
    2964             :                 }
    2965          36 :                 return false;
    2966             :         }
    2967         216 :         torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
    2968             : 
    2969         216 :         if (old_password != NULL) {
    2970         216 :                 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
    2971             :                         "ServerReqChallenge failed");
    2972         216 :                 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
    2973             : 
    2974         216 :                 creds = netlogon_creds_client_init(tctx, a.in.account_name,
    2975             :                                                    a.in.computer_name,
    2976         216 :                                                    a.in.secure_channel_type,
    2977             :                                                    &credentials1, &credentials2,
    2978             :                                                    old_password, &credentials3,
    2979             :                                                    negotiate_flags);
    2980             : 
    2981         216 :                 torture_assert(tctx, creds != NULL, "memory allocation");
    2982             : 
    2983         216 :                 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
    2984             :                         "ServerAuthenticate3 failed");
    2985         216 :                 if (!NT_STATUS_IS_OK(a.out.result)) {
    2986           0 :                         if (!NT_STATUS_EQUAL(a.out.result, NT_STATUS_ACCESS_DENIED)) {
    2987           0 :                                 torture_assert_ntstatus_ok(tctx, a.out.result,
    2988             :                                                            "ServerAuthenticate3 (old) failed");
    2989             :                         }
    2990           0 :                         return false;
    2991             :                 }
    2992         216 :                 torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential (old) chaining failed");
    2993             :         }
    2994             : 
    2995             :         /* Prove that requesting a challenge again won't break it */
    2996         216 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
    2997             :                 "ServerReqChallenge failed");
    2998         216 :         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
    2999             : 
    3000         216 :         *creds_out = creds;
    3001         216 :         return true;
    3002             : }
    3003             : 
    3004             : #ifdef SAMBA4_USES_HEIMDAL
    3005             : 
    3006             : /*
    3007             :  * This function is set in torture_krb5_init_context as krb5
    3008             :  * send_and_recv function.  This allows us to override what server the
    3009             :  * test is aimed at, and to inspect the packets just before they are
    3010             :  * sent to the network, and before they are processed on the recv
    3011             :  * side.
    3012             :  *
    3013             :  * The torture_krb5_pre_send_test() and torture_krb5_post_recv_test()
    3014             :  * functions are implement the actual tests.
    3015             :  *
    3016             :  * When this asserts, the caller will get a spurious 'cannot contact
    3017             :  * any KDC' message.
    3018             :  *
    3019             :  */
    3020             : struct check_pw_with_krb5_ctx {
    3021             :         struct addrinfo *server;
    3022             :         const char *server_nb_domain;
    3023             :         const char *server_dns_domain;
    3024             :         struct {
    3025             :                 unsigned io;
    3026             :                 unsigned fail;
    3027             :                 unsigned errors;
    3028             :                 unsigned error_io;
    3029             :                 unsigned ok;
    3030             :         } counts;
    3031             :         krb5_error error;
    3032             :         struct smb_krb5_context *smb_krb5_context;
    3033             :         krb5_get_init_creds_opt *krb_options;
    3034             :         krb5_creds my_creds;
    3035             :         krb5_get_creds_opt opt_canon;
    3036             :         krb5_get_creds_opt opt_nocanon;
    3037             :         krb5_principal upn_realm;
    3038             :         krb5_principal upn_dns;
    3039             :         krb5_principal upn_netbios;
    3040             :         krb5_ccache krbtgt_ccache;
    3041             :         krb5_principal krbtgt_trust_realm;
    3042             :         krb5_creds *krbtgt_trust_realm_creds;
    3043             :         krb5_principal krbtgt_trust_dns;
    3044             :         krb5_creds *krbtgt_trust_dns_creds;
    3045             :         krb5_principal krbtgt_trust_netbios;
    3046             :         krb5_creds *krbtgt_trust_netbios_creds;
    3047             :         krb5_principal cifs_trust_dns;
    3048             :         krb5_creds *cifs_trust_dns_creds;
    3049             :         krb5_principal cifs_trust_netbios;
    3050             :         krb5_creds *cifs_trust_netbios_creds;
    3051             :         krb5_principal drs_trust_dns;
    3052             :         krb5_creds *drs_trust_dns_creds;
    3053             :         krb5_principal drs_trust_netbios;
    3054             :         krb5_creds *drs_trust_netbios_creds;
    3055             :         krb5_principal four_trust_dns;
    3056             :         krb5_creds *four_trust_dns_creds;
    3057             :         krb5_creds krbtgt_referral_creds;
    3058             :         Ticket krbtgt_referral_ticket;
    3059             :         krb5_keyblock krbtgt_referral_keyblock;
    3060             :         EncTicketPart krbtgt_referral_enc_part;
    3061             : };
    3062             : 
    3063        4368 : static krb5_error_code check_pw_with_krb5_send_to_realm(
    3064             :                                         struct smb_krb5_context *smb_krb5_context,
    3065             :                                         void *data, /* struct check_pw_with_krb5_ctx */
    3066             :                                         krb5_const_realm realm,
    3067             :                                         time_t timeout,
    3068             :                                         const krb5_data *send_buf,
    3069             :                                         krb5_data *recv_buf)
    3070             : {
    3071           0 :         struct check_pw_with_krb5_ctx *ctx =
    3072        4368 :                 talloc_get_type_abort(data, struct check_pw_with_krb5_ctx);
    3073           0 :         krb5_error_code k5ret;
    3074           0 :         size_t used;
    3075           0 :         int ret;
    3076             : 
    3077        4368 :         SMB_ASSERT(smb_krb5_context == ctx->smb_krb5_context);
    3078             : 
    3079        4368 :         if (!strequal_m(realm, ctx->server_nb_domain) &&
    3080        4368 :             !strequal_m(realm, ctx->server_dns_domain))
    3081             :         {
    3082        1080 :                 return KRB5_KDC_UNREACH;
    3083             :         }
    3084             : 
    3085        3288 :         krb5_free_error_contents(ctx->smb_krb5_context->krb5_context,
    3086             :                                  &ctx->error);
    3087        3288 :         ctx->counts.io++;
    3088             : 
    3089        3288 :         k5ret = smb_krb5_send_and_recv_func_forced_tcp(ctx->smb_krb5_context,
    3090             :                                                        ctx->server,
    3091             :                                                        timeout, send_buf, recv_buf);
    3092        3288 :         if (k5ret != 0) {
    3093           0 :                 ctx->counts.fail++;
    3094           0 :                 return k5ret;
    3095             :         }
    3096             : 
    3097        3288 :         ret = decode_KRB_ERROR(recv_buf->data, recv_buf->length,
    3098        3288 :                                &ctx->error, &used);
    3099        3288 :         if (ret == 0) {
    3100        1272 :                 ctx->counts.errors++;
    3101        1272 :                 ctx->counts.error_io = ctx->counts.io;
    3102             :         } else {
    3103        2016 :                 ctx->counts.ok++;
    3104             :         }
    3105             : 
    3106        3288 :         return k5ret;
    3107             : }
    3108             : 
    3109         168 : static int check_pw_with_krb5_ctx_destructor(struct check_pw_with_krb5_ctx *ctx)
    3110             : {
    3111         168 :         if (ctx->server != NULL) {
    3112         168 :                 freeaddrinfo(ctx->server);
    3113         168 :                 ctx->server = NULL;
    3114             :         }
    3115             : 
    3116         168 :         if (ctx->krb_options != NULL) {
    3117         168 :                 krb5_get_init_creds_opt_free(ctx->smb_krb5_context->krb5_context,
    3118             :                                              ctx->krb_options);
    3119         168 :                 ctx->krb_options = NULL;
    3120             :         }
    3121             : 
    3122         168 :         krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
    3123             :                                 &ctx->my_creds);
    3124             : 
    3125         168 :         if (ctx->opt_canon != NULL) {
    3126         144 :                 krb5_get_creds_opt_free(ctx->smb_krb5_context->krb5_context,
    3127             :                                         ctx->opt_canon);
    3128         144 :                 ctx->opt_canon = NULL;
    3129             :         }
    3130             : 
    3131         168 :         if (ctx->opt_nocanon != NULL) {
    3132         144 :                 krb5_get_creds_opt_free(ctx->smb_krb5_context->krb5_context,
    3133             :                                         ctx->opt_nocanon);
    3134         144 :                 ctx->opt_nocanon = NULL;
    3135             :         }
    3136             : 
    3137         168 :         if (ctx->krbtgt_ccache != NULL) {
    3138         144 :                 krb5_cc_close(ctx->smb_krb5_context->krb5_context,
    3139             :                               ctx->krbtgt_ccache);
    3140         144 :                 ctx->krbtgt_ccache = NULL;
    3141             :         }
    3142             : 
    3143         168 :         if (ctx->upn_realm != NULL) {
    3144         168 :                 krb5_free_principal(ctx->smb_krb5_context->krb5_context,
    3145             :                                     ctx->upn_realm);
    3146         168 :                 ctx->upn_realm = NULL;
    3147             :         }
    3148             : 
    3149         168 :         if (ctx->upn_dns != NULL) {
    3150         168 :                 krb5_free_principal(ctx->smb_krb5_context->krb5_context,
    3151             :                                     ctx->upn_dns);
    3152         168 :                 ctx->upn_dns = NULL;
    3153             :         }
    3154             : 
    3155         168 :         if (ctx->upn_netbios != NULL) {
    3156         168 :                 krb5_free_principal(ctx->smb_krb5_context->krb5_context,
    3157             :                                     ctx->upn_netbios);
    3158         168 :                 ctx->upn_netbios = NULL;
    3159             :         }
    3160             : 
    3161         168 :         if (ctx->krbtgt_trust_realm != NULL) {
    3162         144 :                 krb5_free_principal(ctx->smb_krb5_context->krb5_context,
    3163             :                                     ctx->krbtgt_trust_realm);
    3164         144 :                 ctx->krbtgt_trust_realm = NULL;
    3165             :         }
    3166             : 
    3167         168 :         if (ctx->krbtgt_trust_realm_creds != NULL) {
    3168         144 :                 krb5_free_creds(ctx->smb_krb5_context->krb5_context,
    3169             :                                 ctx->krbtgt_trust_realm_creds);
    3170         144 :                 ctx->krbtgt_trust_realm_creds = NULL;
    3171             :         }
    3172             : 
    3173         168 :         if (ctx->krbtgt_trust_dns != NULL) {
    3174         144 :                 krb5_free_principal(ctx->smb_krb5_context->krb5_context,
    3175             :                                     ctx->krbtgt_trust_dns);
    3176         144 :                 ctx->krbtgt_trust_dns = NULL;
    3177             :         }
    3178             : 
    3179         168 :         if (ctx->krbtgt_trust_dns_creds != NULL) {
    3180         144 :                 krb5_free_creds(ctx->smb_krb5_context->krb5_context,
    3181             :                                 ctx->krbtgt_trust_dns_creds);
    3182         144 :                 ctx->krbtgt_trust_dns_creds = NULL;
    3183             :         }
    3184             : 
    3185         168 :         if (ctx->krbtgt_trust_netbios != NULL) {
    3186         144 :                 krb5_free_principal(ctx->smb_krb5_context->krb5_context,
    3187             :                                     ctx->krbtgt_trust_netbios);
    3188         144 :                 ctx->krbtgt_trust_netbios = NULL;
    3189             :         }
    3190             : 
    3191         168 :         if (ctx->krbtgt_trust_netbios_creds != NULL) {
    3192         144 :                 krb5_free_creds(ctx->smb_krb5_context->krb5_context,
    3193             :                                 ctx->krbtgt_trust_netbios_creds);
    3194         144 :                 ctx->krbtgt_trust_netbios_creds = NULL;
    3195             :         }
    3196             : 
    3197         168 :         if (ctx->cifs_trust_dns != NULL) {
    3198         144 :                 krb5_free_principal(ctx->smb_krb5_context->krb5_context,
    3199             :                                     ctx->cifs_trust_dns);
    3200         144 :                 ctx->cifs_trust_dns = NULL;
    3201             :         }
    3202             : 
    3203         168 :         if (ctx->cifs_trust_dns_creds != NULL) {
    3204           0 :                 krb5_free_creds(ctx->smb_krb5_context->krb5_context,
    3205             :                                 ctx->cifs_trust_dns_creds);
    3206           0 :                 ctx->cifs_trust_dns_creds = NULL;
    3207             :         }
    3208             : 
    3209         168 :         if (ctx->cifs_trust_netbios != NULL) {
    3210         144 :                 krb5_free_principal(ctx->smb_krb5_context->krb5_context,
    3211             :                                     ctx->cifs_trust_netbios);
    3212         144 :                 ctx->cifs_trust_netbios = NULL;
    3213             :         }
    3214             : 
    3215         168 :         if (ctx->cifs_trust_netbios_creds != NULL) {
    3216           0 :                 krb5_free_creds(ctx->smb_krb5_context->krb5_context,
    3217             :                                 ctx->cifs_trust_netbios_creds);
    3218           0 :                 ctx->cifs_trust_netbios_creds = NULL;
    3219             :         }
    3220             : 
    3221         168 :         if (ctx->drs_trust_dns != NULL) {
    3222         144 :                 krb5_free_principal(ctx->smb_krb5_context->krb5_context,
    3223             :                                     ctx->drs_trust_dns);
    3224         144 :                 ctx->drs_trust_dns = NULL;
    3225             :         }
    3226             : 
    3227         168 :         if (ctx->drs_trust_dns_creds != NULL) {
    3228           0 :                 krb5_free_creds(ctx->smb_krb5_context->krb5_context,
    3229             :                                 ctx->drs_trust_dns_creds);
    3230           0 :                 ctx->drs_trust_dns_creds = NULL;
    3231             :         }
    3232             : 
    3233         168 :         if (ctx->drs_trust_netbios != NULL) {
    3234         144 :                 krb5_free_principal(ctx->smb_krb5_context->krb5_context,
    3235             :                                     ctx->drs_trust_netbios);
    3236         144 :                 ctx->drs_trust_netbios = NULL;
    3237             :         }
    3238             : 
    3239         168 :         if (ctx->drs_trust_netbios_creds != NULL) {
    3240           0 :                 krb5_free_creds(ctx->smb_krb5_context->krb5_context,
    3241             :                                 ctx->drs_trust_netbios_creds);
    3242           0 :                 ctx->drs_trust_netbios_creds = NULL;
    3243             :         }
    3244             : 
    3245         168 :         if (ctx->four_trust_dns != NULL) {
    3246         144 :                 krb5_free_principal(ctx->smb_krb5_context->krb5_context,
    3247             :                                     ctx->four_trust_dns);
    3248         144 :                 ctx->four_trust_dns = NULL;
    3249             :         }
    3250             : 
    3251         168 :         if (ctx->four_trust_dns_creds != NULL) {
    3252           0 :                 krb5_free_creds(ctx->smb_krb5_context->krb5_context,
    3253             :                                 ctx->four_trust_dns_creds);
    3254           0 :                 ctx->four_trust_dns_creds = NULL;
    3255             :         }
    3256             : 
    3257         168 :         krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
    3258             :                                 &ctx->krbtgt_referral_creds);
    3259             : 
    3260         168 :         free_Ticket(&ctx->krbtgt_referral_ticket);
    3261             : 
    3262         168 :         krb5_free_keyblock_contents(ctx->smb_krb5_context->krb5_context,
    3263             :                                     &ctx->krbtgt_referral_keyblock);
    3264             : 
    3265         168 :         free_EncTicketPart(&ctx->krbtgt_referral_enc_part);
    3266             : 
    3267         168 :         krb5_free_error_contents(ctx->smb_krb5_context->krb5_context,
    3268             :                                  &ctx->error);
    3269             : 
    3270         168 :         talloc_unlink(ctx, ctx->smb_krb5_context);
    3271         168 :         ctx->smb_krb5_context = NULL;
    3272         168 :         return 0;
    3273             : }
    3274             : 
    3275         168 : static bool check_pw_with_krb5(struct torture_context *tctx,
    3276             :                                struct cli_credentials *credentials,
    3277             :                                const struct lsa_TrustDomainInfoInfoEx *trusted)
    3278             : {
    3279         168 :         const char *trusted_dns_name = trusted->domain_name.string;
    3280         168 :         const char *trusted_netbios_name = trusted->netbios_name.string;
    3281         168 :         char *trusted_realm_name = NULL;
    3282         168 :         krb5_principal principal = NULL;
    3283           0 :         enum credentials_obtained obtained;
    3284         168 :         const char *error_string = NULL;
    3285         168 :         const char *workstation = cli_credentials_get_workstation(credentials);
    3286         168 :         const char *password = cli_credentials_get_password(credentials);
    3287             : #ifndef USING_EMBEDDED_HEIMDAL
    3288           0 :         const struct samr_Password *nthash = NULL;
    3289           0 :         const struct samr_Password *old_nthash = NULL;
    3290             : #endif
    3291         168 :         const char *old_password = cli_credentials_get_old_password(credentials);
    3292             : #ifndef USING_EMBEDDED_HEIMDAL
    3293           0 :         int kvno = cli_credentials_get_kvno(credentials);
    3294           0 :         int expected_kvno = 0;
    3295           0 :         krb5uint32 t_kvno = 0;
    3296             : #endif
    3297         168 :         const char *host = torture_setting_string(tctx, "host", NULL);
    3298           0 :         krb5_error_code k5ret;
    3299           0 :         krb5_boolean k5ok;
    3300           0 :         int type;
    3301           0 :         bool ok;
    3302         168 :         struct check_pw_with_krb5_ctx *ctx = NULL;
    3303         168 :         char *assertion_message = NULL;
    3304         168 :         const char *realm = NULL;
    3305         168 :         char *upn_realm_string = NULL;
    3306         168 :         char *upn_dns_string = NULL;
    3307         168 :         char *upn_netbios_string = NULL;
    3308         168 :         char *krbtgt_cc_name = NULL;
    3309         168 :         char *krbtgt_trust_realm_string = NULL;
    3310         168 :         char *krbtgt_trust_dns_string = NULL;
    3311         168 :         char *krbtgt_trust_netbios_string = NULL;
    3312         168 :         char *cifs_trust_dns_string = NULL;
    3313         168 :         char *cifs_trust_netbios_string = NULL;
    3314         168 :         char *drs_trust_dns_string = NULL;
    3315         168 :         char *drs_trust_netbios_string = NULL;
    3316         168 :         char *four_trust_dns_string = NULL;
    3317             : 
    3318         168 :         ctx = talloc_zero(tctx, struct check_pw_with_krb5_ctx);
    3319         168 :         torture_assert(tctx, ctx != NULL, "Failed to allocate");
    3320             : 
    3321         168 :         realm = cli_credentials_get_realm(credentials);
    3322         168 :         trusted_realm_name = strupper_talloc(tctx, trusted_dns_name);
    3323             : 
    3324             : #ifndef USING_EMBEDDED_HEIMDAL
    3325           0 :         nthash = cli_credentials_get_nt_hash(credentials, ctx);
    3326           0 :         old_nthash = cli_credentials_get_old_nt_hash(credentials, ctx);
    3327             : #endif
    3328             : 
    3329         168 :         k5ret = smb_krb5_init_context(ctx, tctx->lp_ctx, &ctx->smb_krb5_context);
    3330         168 :         torture_assert_int_equal(tctx, k5ret, 0, "smb_krb5_init_context failed");
    3331             : 
    3332         168 :         ctx->server_nb_domain = cli_credentials_get_domain(credentials);
    3333         168 :         ctx->server_dns_domain = cli_credentials_get_realm(credentials);
    3334             : 
    3335         168 :         ok = interpret_string_addr_internal(&ctx->server, host, 0);
    3336         168 :         torture_assert(tctx, ok, "Failed to parse target server");
    3337         168 :         talloc_set_destructor(ctx, check_pw_with_krb5_ctx_destructor);
    3338             : 
    3339         168 :         set_sockaddr_port(ctx->server->ai_addr, 88);
    3340             : 
    3341         168 :         k5ret = smb_krb5_set_send_to_kdc_func(ctx->smb_krb5_context,
    3342             :                                               check_pw_with_krb5_send_to_realm,
    3343             :                                               NULL, /* send_to_kdc */
    3344             :                                               ctx);
    3345         168 :         torture_assert_int_equal(tctx, k5ret, 0, "krb5_set_send_to_kdc_func failed");
    3346             : 
    3347         168 :         torture_assert_int_equal(tctx,
    3348             :                         krb5_get_init_creds_opt_alloc(ctx->smb_krb5_context->krb5_context,
    3349             :                                                       &ctx->krb_options),
    3350             :                         0, "krb5_get_init_creds_opt_alloc failed");
    3351         168 :         torture_assert_int_equal(tctx,
    3352             :                         krb5_get_init_creds_opt_set_pac_request(
    3353             :                                 ctx->smb_krb5_context->krb5_context,
    3354             :                                 ctx->krb_options, true),
    3355             :                         0, "krb5_get_init_creds_opt_set_pac_request failed");
    3356             : 
    3357         168 :         upn_realm_string = talloc_asprintf(ctx, "user@%s",
    3358             :                                            trusted_realm_name);
    3359         168 :         torture_assert_int_equal(tctx,
    3360             :                         smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
    3361             :                                                 &ctx->upn_realm,
    3362             :                                                 realm, upn_realm_string, NULL),
    3363             :                         0, "smb_krb5_make_principal failed");
    3364         168 :         smb_krb5_principal_set_type(ctx->smb_krb5_context->krb5_context,
    3365             :                                     ctx->upn_realm, KRB5_NT_ENTERPRISE_PRINCIPAL);
    3366             : 
    3367         168 :         upn_dns_string = talloc_asprintf(ctx, "user@%s",
    3368             :                                          trusted_dns_name);
    3369         168 :         torture_assert_int_equal(tctx,
    3370             :                         smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
    3371             :                                                 &ctx->upn_dns,
    3372             :                                                 realm, upn_dns_string, NULL),
    3373             :                         0, "smb_krb5_make_principal failed");
    3374         168 :         smb_krb5_principal_set_type(ctx->smb_krb5_context->krb5_context,
    3375             :                                     ctx->upn_dns, KRB5_NT_ENTERPRISE_PRINCIPAL);
    3376             : 
    3377         168 :         upn_netbios_string = talloc_asprintf(ctx, "user@%s",
    3378             :                                          trusted_netbios_name);
    3379         168 :         torture_assert_int_equal(tctx,
    3380             :                         smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
    3381             :                                                 &ctx->upn_netbios,
    3382             :                                                 realm, upn_netbios_string, NULL),
    3383             :                         0, "smb_krb5_make_principal failed");
    3384         168 :         smb_krb5_principal_set_type(ctx->smb_krb5_context->krb5_context,
    3385             :                                     ctx->upn_netbios, KRB5_NT_ENTERPRISE_PRINCIPAL);
    3386             : 
    3387         168 :         k5ret = principal_from_credentials(ctx, credentials, ctx->smb_krb5_context,
    3388             :                                            &principal, &obtained,  &error_string);
    3389         168 :         torture_assert_int_equal(tctx, k5ret, 0, error_string);
    3390             : 
    3391         168 :         ZERO_STRUCT(ctx->counts);
    3392         168 :         k5ret = krb5_get_init_creds_password(ctx->smb_krb5_context->krb5_context,
    3393             :                                              &ctx->my_creds, ctx->upn_realm,
    3394             :                                              "_none_", NULL, NULL, 0,
    3395             :                                              NULL, ctx->krb_options);
    3396         168 :         assertion_message = talloc_asprintf(ctx,
    3397             :                                 "krb5_get_init_creds_password(%s, canon) for failed: "
    3398             :                                 "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u/%u,ok=%u]",
    3399             :                                 upn_realm_string,
    3400             :                                 k5ret,
    3401         168 :                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
    3402             :                                                            k5ret, ctx),
    3403         168 :                                 trusted->trust_direction,
    3404         168 :                                 trusted->trust_type,
    3405         168 :                                 trusted->trust_attributes,
    3406             :                                 ctx->counts.io, ctx->counts.error_io, ctx->counts.errors, ctx->counts.ok);
    3407         168 :         torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
    3408         168 :         torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
    3409         168 :         torture_assert_int_equal(tctx, ctx->counts.error_io, 1, assertion_message);
    3410         168 :         torture_assert_int_equal(tctx, KRB5_ERROR_CODE(&ctx->error), 68, assertion_message);
    3411         168 :         torture_assert(tctx, ctx->error.crealm != NULL, assertion_message);
    3412         168 :         torture_assert_str_equal(tctx, *ctx->error.crealm, trusted_realm_name, assertion_message);
    3413             : #ifdef USING_EMBEDDED_HEIMDAL
    3414         168 :         torture_assert(tctx, ctx->error.cname != NULL, assertion_message);
    3415         168 :         torture_assert_int_equal(tctx, ctx->error.cname->name_type, KRB5_NT_ENTERPRISE_PRINCIPAL, assertion_message);
    3416         168 :         torture_assert_int_equal(tctx, ctx->error.cname->name_string.len, 1, assertion_message);
    3417         168 :         torture_assert_str_equal(tctx, ctx->error.cname->name_string.val[0], upn_realm_string, assertion_message);
    3418             : #else
    3419           0 :         torture_assert(tctx, ctx->error.cname == NULL, assertion_message);
    3420             : #endif
    3421         168 :         torture_assert_str_equal(tctx, ctx->error.realm, realm, assertion_message);
    3422             : 
    3423         168 :         ZERO_STRUCT(ctx->counts);
    3424         168 :         k5ret = krb5_get_init_creds_password(ctx->smb_krb5_context->krb5_context,
    3425             :                                              &ctx->my_creds, ctx->upn_dns,
    3426             :                                              "_none_", NULL, NULL, 0,
    3427             :                                              NULL, ctx->krb_options);
    3428         168 :         assertion_message = talloc_asprintf(ctx,
    3429             :                                 "krb5_get_init_creds_password(%s, canon) for failed: "
    3430             :                                 "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u/%u,ok=%u]",
    3431             :                                 upn_dns_string,
    3432             :                                 k5ret,
    3433         168 :                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
    3434             :                                                            k5ret, ctx),
    3435         168 :                                 trusted->trust_direction,
    3436         168 :                                 trusted->trust_type,
    3437         168 :                                 trusted->trust_attributes,
    3438             :                                 ctx->counts.io, ctx->counts.error_io, ctx->counts.errors, ctx->counts.ok);
    3439         168 :         torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
    3440         168 :         torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
    3441         168 :         torture_assert_int_equal(tctx, ctx->counts.error_io, 1, assertion_message);
    3442         168 :         torture_assert_int_equal(tctx, KRB5_ERROR_CODE(&ctx->error), 68, assertion_message);
    3443         168 :         torture_assert(tctx, ctx->error.crealm != NULL, assertion_message);
    3444         168 :         torture_assert_str_equal(tctx, *ctx->error.crealm, trusted_realm_name, assertion_message);
    3445             : #ifdef USING_EMBEDDED_HEIMDAL
    3446         168 :         torture_assert(tctx, ctx->error.cname != NULL, assertion_message);
    3447         168 :         torture_assert_int_equal(tctx, ctx->error.cname->name_type, KRB5_NT_ENTERPRISE_PRINCIPAL, assertion_message);
    3448         168 :         torture_assert_int_equal(tctx, ctx->error.cname->name_string.len, 1, assertion_message);
    3449         168 :         torture_assert_str_equal(tctx, ctx->error.cname->name_string.val[0], upn_dns_string, assertion_message);
    3450             : #else
    3451           0 :         torture_assert(tctx, ctx->error.cname == NULL, assertion_message);
    3452             : #endif
    3453         168 :         torture_assert_str_equal(tctx, ctx->error.realm, realm, assertion_message);
    3454             : 
    3455         168 :         ZERO_STRUCT(ctx->counts);
    3456         168 :         k5ret = krb5_get_init_creds_password(ctx->smb_krb5_context->krb5_context,
    3457             :                                              &ctx->my_creds, ctx->upn_netbios,
    3458             :                                              "_none_", NULL, NULL, 0,
    3459             :                                              NULL, ctx->krb_options);
    3460         168 :         assertion_message = talloc_asprintf(ctx,
    3461             :                                 "krb5_get_init_creds_password(%s, canon) for failed: "
    3462             :                                 "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u/%u,ok=%u]",
    3463             :                                 upn_netbios_string,
    3464             :                                 k5ret,
    3465         168 :                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
    3466             :                                                            k5ret, ctx),
    3467         168 :                                 trusted->trust_direction,
    3468         168 :                                 trusted->trust_type,
    3469         168 :                                 trusted->trust_attributes,
    3470             :                                 ctx->counts.io, ctx->counts.error_io, ctx->counts.errors, ctx->counts.ok);
    3471         168 :         torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
    3472         168 :         torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
    3473         168 :         torture_assert_int_equal(tctx, ctx->counts.error_io, 1, assertion_message);
    3474         168 :         torture_assert_int_equal(tctx, KRB5_ERROR_CODE(&ctx->error), 68, assertion_message);
    3475         168 :         torture_assert(tctx, ctx->error.crealm != NULL, assertion_message);
    3476         168 :         torture_assert_str_equal(tctx, *ctx->error.crealm, trusted_realm_name, assertion_message);
    3477             : #ifdef USING_EMBEDDED_HEIMDAL
    3478         168 :         torture_assert(tctx, ctx->error.cname != NULL, assertion_message);
    3479         168 :         torture_assert_int_equal(tctx, ctx->error.cname->name_type, KRB5_NT_ENTERPRISE_PRINCIPAL, assertion_message);
    3480         168 :         torture_assert_int_equal(tctx, ctx->error.cname->name_string.len, 1, assertion_message);
    3481         168 :         torture_assert_str_equal(tctx, ctx->error.cname->name_string.val[0], upn_netbios_string, assertion_message);
    3482             : #else
    3483           0 :         torture_assert(tctx, ctx->error.cname == NULL, assertion_message);
    3484             : #endif
    3485         168 :         torture_assert_str_equal(tctx, ctx->error.realm, realm, assertion_message);
    3486             : 
    3487         168 :         torture_comment(tctx, "(%s:%s) password[%s] old_password[%s]\n",
    3488             :                         __location__, __FUNCTION__,
    3489             :                         password, old_password);
    3490         168 :         if (old_password != NULL) {
    3491         144 :                 k5ret = krb5_get_init_creds_password(ctx->smb_krb5_context->krb5_context,
    3492             :                                                      &ctx->my_creds, principal,
    3493             :                                                      old_password, NULL, NULL, 0,
    3494             :                                                      NULL, ctx->krb_options);
    3495         144 :                 torture_assert_int_equal(tctx, k5ret, KRB5KDC_ERR_PREAUTH_FAILED,
    3496             :                                          "preauth should fail with old password");
    3497             :         }
    3498             : 
    3499         168 :         k5ret = krb5_get_init_creds_password(ctx->smb_krb5_context->krb5_context,
    3500             :                                              &ctx->my_creds, principal,
    3501             :                                              password, NULL, NULL, 0,
    3502             :                                              NULL, ctx->krb_options);
    3503         168 :         if (k5ret == KRB5KDC_ERR_PREAUTH_FAILED) {
    3504          24 :                 TALLOC_FREE(ctx);
    3505          24 :                 return false;
    3506             :         }
    3507             : 
    3508         144 :         assertion_message = talloc_asprintf(ctx,
    3509             :                                 "krb5_get_init_creds_password for failed: %s",
    3510         144 :                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
    3511             :                                                            k5ret, ctx));
    3512         144 :         torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
    3513             : 
    3514         144 :         torture_assert_int_equal(tctx,
    3515             :                         krb5_get_creds_opt_alloc(ctx->smb_krb5_context->krb5_context,
    3516             :                                                  &ctx->opt_canon),
    3517             :                         0, "krb5_get_creds_opt_alloc");
    3518             : 
    3519         144 :         krb5_get_creds_opt_add_options(ctx->smb_krb5_context->krb5_context,
    3520             :                                        ctx->opt_canon,
    3521             :                                        KRB5_GC_CANONICALIZE);
    3522             : 
    3523         144 :         krb5_get_creds_opt_add_options(ctx->smb_krb5_context->krb5_context,
    3524             :                                        ctx->opt_canon,
    3525             :                                        KRB5_GC_NO_STORE);
    3526             : 
    3527         144 :         torture_assert_int_equal(tctx,
    3528             :                         krb5_get_creds_opt_alloc(ctx->smb_krb5_context->krb5_context,
    3529             :                                                  &ctx->opt_nocanon),
    3530             :                         0, "krb5_get_creds_opt_alloc");
    3531             : 
    3532         144 :         krb5_get_creds_opt_add_options(ctx->smb_krb5_context->krb5_context,
    3533             :                                        ctx->opt_nocanon,
    3534             :                                        KRB5_GC_NO_STORE);
    3535             : 
    3536         144 :         krbtgt_cc_name = talloc_asprintf(ctx, "MEMORY:%p.krbtgt", ctx->smb_krb5_context);
    3537         144 :         torture_assert_int_equal(tctx,
    3538             :                         krb5_cc_resolve(ctx->smb_krb5_context->krb5_context,
    3539             :                                         krbtgt_cc_name,
    3540             :                                         &ctx->krbtgt_ccache),
    3541             :                         0, "krb5_cc_resolve failed");
    3542             : 
    3543         144 :         torture_assert_int_equal(tctx,
    3544             :                         krb5_cc_initialize(ctx->smb_krb5_context->krb5_context,
    3545             :                                            ctx->krbtgt_ccache,
    3546             :                                            ctx->my_creds.client),
    3547             :                         0, "krb5_cc_initialize failed");
    3548             : 
    3549         144 :         torture_assert_int_equal(tctx,
    3550             :                         krb5_cc_store_cred(ctx->smb_krb5_context->krb5_context,
    3551             :                                            ctx->krbtgt_ccache,
    3552             :                                            &ctx->my_creds),
    3553             :                         0, "krb5_cc_store_cred failed");
    3554             : 
    3555         144 :         krbtgt_trust_realm_string = talloc_asprintf(ctx, "krbtgt/%s@%s",
    3556             :                                                     trusted_realm_name, realm);
    3557         144 :         torture_assert_int_equal(tctx,
    3558             :                         smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
    3559             :                                                 &ctx->krbtgt_trust_realm,
    3560             :                                                 realm, "krbtgt",
    3561             :                                                 trusted_realm_name, NULL),
    3562             :                         0, "smb_krb5_make_principal failed");
    3563             : 
    3564         144 :         krbtgt_trust_dns_string = talloc_asprintf(ctx, "krbtgt/%s@%s",
    3565             :                                                   trusted_dns_name, realm);
    3566         144 :         torture_assert_int_equal(tctx,
    3567             :                         smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
    3568             :                                                 &ctx->krbtgt_trust_dns,
    3569             :                                                 realm, "krbtgt",
    3570             :                                                 trusted_dns_name, NULL),
    3571             :                         0, "smb_krb5_make_principal failed");
    3572             : 
    3573         144 :         krbtgt_trust_netbios_string = talloc_asprintf(ctx, "krbtgt/%s@%s",
    3574             :                                                       trusted_netbios_name, realm);
    3575         144 :         torture_assert_int_equal(tctx,
    3576             :                         smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
    3577             :                                                 &ctx->krbtgt_trust_netbios,
    3578             :                                                 realm, "krbtgt",
    3579             :                                                 trusted_netbios_name, NULL),
    3580             :                         0, "smb_krb5_make_principal failed");
    3581             : 
    3582             :         /* Confirm if we can do a TGS for krbtgt/trusted_realm */
    3583         144 :         ZERO_STRUCT(ctx->counts);
    3584         144 :         k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
    3585             :                                ctx->opt_nocanon,
    3586             :                                ctx->krbtgt_ccache,
    3587         144 :                                ctx->krbtgt_trust_realm,
    3588             :                                &ctx->krbtgt_trust_realm_creds);
    3589         144 :         assertion_message = talloc_asprintf(ctx,
    3590             :                                 "krb5_get_creds(%s, canon) for failed: "
    3591             :                                 "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
    3592             :                                 krbtgt_trust_realm_string,
    3593             :                                 k5ret,
    3594         144 :                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
    3595             :                                                            k5ret, ctx),
    3596         144 :                                 trusted->trust_direction,
    3597         144 :                                 trusted->trust_type,
    3598         144 :                                 trusted->trust_attributes,
    3599             :                                 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
    3600         144 :         torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
    3601         144 :         torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
    3602         144 :         torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
    3603             : 
    3604         144 :         k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
    3605         144 :                                       ctx->krbtgt_trust_realm_creds->server,
    3606         144 :                                       ctx->krbtgt_trust_realm);
    3607         144 :         torture_assert(tctx, k5ok, assertion_message);
    3608         144 :         type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
    3609         144 :                                            ctx->krbtgt_trust_realm_creds->server);
    3610         144 :         torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
    3611             : 
    3612             :         /* Confirm if we have no referral ticket in the cache */
    3613         144 :         krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
    3614             :                                 &ctx->krbtgt_referral_creds);
    3615         144 :         k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
    3616             :                                       ctx->krbtgt_ccache,
    3617             :                                       0,
    3618         144 :                                       ctx->krbtgt_trust_realm_creds,
    3619             :                                       &ctx->krbtgt_referral_creds);
    3620         144 :         assertion_message = talloc_asprintf(ctx,
    3621             :                                 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
    3622             :                                 krbtgt_trust_realm_string,
    3623             :                                 k5ret,
    3624         144 :                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
    3625             :                                                            k5ret, ctx));
    3626         144 :         torture_assert_int_equal(tctx, k5ret, KRB5_CC_END, assertion_message);
    3627             : 
    3628             :         /* Confirm if we can do a TGS for krbtgt/trusted_dns with CANON */
    3629         144 :         ZERO_STRUCT(ctx->counts);
    3630         144 :         k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
    3631             :                                ctx->opt_canon,
    3632             :                                ctx->krbtgt_ccache,
    3633         144 :                                ctx->krbtgt_trust_dns,
    3634             :                                &ctx->krbtgt_trust_dns_creds);
    3635         144 :         assertion_message = talloc_asprintf(ctx,
    3636             :                                 "krb5_get_creds(%s, canon) for failed: "
    3637             :                                 "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
    3638             :                                 krbtgt_trust_dns_string,
    3639             :                                 k5ret,
    3640         144 :                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
    3641             :                                                            k5ret, ctx),
    3642         144 :                                 trusted->trust_direction,
    3643         144 :                                 trusted->trust_type,
    3644         144 :                                 trusted->trust_attributes,
    3645             :                                 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
    3646             : #ifdef USING_EMBEDDED_HEIMDAL
    3647         144 :         torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
    3648             : #else
    3649           0 :         torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
    3650             : #endif
    3651         144 :         torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
    3652         144 :         torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
    3653             : 
    3654             :         /* Confirm if we have the referral ticket in the cache */
    3655         144 :         krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
    3656             :                                 &ctx->krbtgt_referral_creds);
    3657         144 :         k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
    3658             :                                       ctx->krbtgt_ccache,
    3659             :                                       0,
    3660         144 :                                       ctx->krbtgt_trust_realm_creds,
    3661             :                                       &ctx->krbtgt_referral_creds);
    3662         144 :         assertion_message = talloc_asprintf(ctx,
    3663             :                                 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
    3664             :                                 krbtgt_trust_realm_string,
    3665             :                                 k5ret,
    3666         144 :                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
    3667             :                                                            k5ret, ctx));
    3668             : #ifdef USING_EMBEDDED_HEIMDAL
    3669         144 :         torture_assert_int_equal(tctx, k5ret, KRB5_CC_END, assertion_message);
    3670             : #else
    3671           0 :         torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
    3672             : 
    3673           0 :         k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
    3674           0 :                                       ctx->krbtgt_referral_creds.server,
    3675           0 :                                       ctx->krbtgt_trust_realm);
    3676           0 :         torture_assert(tctx, k5ok, assertion_message);
    3677           0 :         type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
    3678           0 :                                            ctx->krbtgt_referral_creds.server);
    3679           0 :         torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
    3680           0 :         k5ret = decode_Ticket(ctx->krbtgt_referral_creds.ticket.data,
    3681             :                               ctx->krbtgt_referral_creds.ticket.length,
    3682             :                               &ctx->krbtgt_referral_ticket, NULL);
    3683           0 :         torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
    3684           0 :         if (kvno > 0) {
    3685           0 :                 expected_kvno = kvno - 1;
    3686             :         }
    3687           0 :         if (ctx->krbtgt_referral_ticket.enc_part.kvno != NULL) {
    3688           0 :                 t_kvno = *ctx->krbtgt_referral_ticket.enc_part.kvno;
    3689           0 :                 assertion_message = talloc_asprintf(ctx,
    3690             :                                 "krbtgt_referral_ticket(%s) kvno(%u) expected(%u) current(%u)",
    3691             :                                 krbtgt_trust_realm_string,
    3692             :                                 (unsigned)t_kvno, (unsigned)expected_kvno,(unsigned)kvno);
    3693           0 :                 torture_comment(tctx, "%s\n", assertion_message);
    3694           0 :                 torture_assert_int_not_equal(tctx, t_kvno, 0, assertion_message);
    3695             :         } else {
    3696           0 :                 assertion_message = talloc_asprintf(ctx,
    3697             :                                 "krbtgt_referral_ticket(%s) kvno(NULL) expected(%u) current(%u)",
    3698             :                                 krbtgt_trust_realm_string,
    3699             :                                 (unsigned)expected_kvno,(unsigned)kvno);
    3700           0 :                 torture_comment(tctx, "%s\n", assertion_message);
    3701             :         }
    3702           0 :         torture_assert_int_equal(tctx, t_kvno, expected_kvno, assertion_message);
    3703             : 
    3704           0 :         if (old_nthash != NULL && expected_kvno != kvno) {
    3705           0 :                 torture_comment(tctx, "old_nthash: %s\n", assertion_message);
    3706           0 :                 k5ret = smb_krb5_keyblock_init_contents(ctx->smb_krb5_context->krb5_context,
    3707             :                                                         ENCTYPE_ARCFOUR_HMAC,
    3708           0 :                                                         old_nthash->hash,
    3709             :                                                         sizeof(old_nthash->hash),
    3710             :                                                         &ctx->krbtgt_referral_keyblock);
    3711           0 :                 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
    3712             :         } else {
    3713           0 :                 torture_comment(tctx, "nthash: %s\n", assertion_message);
    3714           0 :                 k5ret = smb_krb5_keyblock_init_contents(ctx->smb_krb5_context->krb5_context,
    3715             :                                                         ENCTYPE_ARCFOUR_HMAC,
    3716           0 :                                                         nthash->hash,
    3717             :                                                         sizeof(nthash->hash),
    3718             :                                                         &ctx->krbtgt_referral_keyblock);
    3719           0 :                 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
    3720             :         }
    3721           0 :         k5ret = krb5_decrypt_ticket(ctx->smb_krb5_context->krb5_context,
    3722             :                                     &ctx->krbtgt_referral_ticket,
    3723             :                                     &ctx->krbtgt_referral_keyblock,
    3724             :                                     &ctx->krbtgt_referral_enc_part,
    3725             :                                     0);
    3726           0 :         torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
    3727             : 
    3728             :         /* Delete the referral ticket from the cache */
    3729           0 :         k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
    3730             :                                     ctx->krbtgt_ccache,
    3731             :                                     0,
    3732             :                                     &ctx->krbtgt_referral_creds);
    3733           0 :         assertion_message = talloc_asprintf(ctx,
    3734             :                                 "krb5_cc_remove_cred(%s) for failed: (%d) %s",
    3735             :                                 krbtgt_trust_realm_string,
    3736             :                                 k5ret,
    3737           0 :                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
    3738             :                                                            k5ret, ctx));
    3739           0 :         torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
    3740             : #endif
    3741             : 
    3742             :         /* Confirm if we can do a TGS for krbtgt/trusted_dns no CANON */
    3743         144 :         ZERO_STRUCT(ctx->counts);
    3744         144 :         k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
    3745             :                                ctx->opt_nocanon,
    3746             :                                ctx->krbtgt_ccache,
    3747         144 :                                ctx->krbtgt_trust_dns,
    3748             :                                &ctx->krbtgt_trust_dns_creds);
    3749         144 :         assertion_message = talloc_asprintf(ctx,
    3750             :                                 "krb5_get_creds(%s, nocanon) for failed: "
    3751             :                                 "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
    3752             :                                 krbtgt_trust_dns_string,
    3753             :                                 k5ret,
    3754         144 :                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
    3755             :                                                            k5ret, ctx),
    3756         144 :                                 trusted->trust_direction,
    3757         144 :                                 trusted->trust_type,
    3758         144 :                                 trusted->trust_attributes,
    3759             :                                 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
    3760         144 :         torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
    3761             : #ifdef USING_EMBEDDED_HEIMDAL
    3762         144 :         torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
    3763         144 :         torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
    3764             : #else
    3765           0 :         torture_assert_int_equal(tctx, ctx->counts.io, 2, assertion_message);
    3766           0 :         torture_assert_int_equal(tctx, ctx->counts.ok, 2, assertion_message);
    3767             : #endif
    3768             : 
    3769         144 :         k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
    3770         144 :                                       ctx->krbtgt_trust_dns_creds->server,
    3771             : #ifdef USING_EMBEDDED_HEIMDAL
    3772         144 :                                       ctx->krbtgt_trust_dns);
    3773             : #else
    3774           0 :                                       ctx->krbtgt_trust_realm);
    3775             : #endif
    3776         144 :         torture_assert(tctx, k5ok, assertion_message);
    3777         144 :         type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
    3778         144 :                                            ctx->krbtgt_trust_dns_creds->server);
    3779         144 :         torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
    3780             : 
    3781             :         /* Confirm if we have the referral ticket in the cache */
    3782         144 :         krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
    3783             :                                 &ctx->krbtgt_referral_creds);
    3784         144 :         k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
    3785             :                                       ctx->krbtgt_ccache,
    3786             :                                       0,
    3787         144 :                                       ctx->krbtgt_trust_realm_creds,
    3788             :                                       &ctx->krbtgt_referral_creds);
    3789         144 :         assertion_message = talloc_asprintf(ctx,
    3790             :                                 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
    3791             :                                 krbtgt_trust_realm_string,
    3792             :                                 k5ret,
    3793         144 :                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
    3794             :                                                            k5ret, ctx));
    3795             : #ifdef USING_EMBEDDED_HEIMDAL
    3796         144 :         torture_assert_int_equal(tctx, k5ret, KRB5_CC_END, assertion_message);
    3797             : #else
    3798           0 :         torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
    3799             : 
    3800           0 :         k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
    3801           0 :                                       ctx->krbtgt_referral_creds.server,
    3802           0 :                                       ctx->krbtgt_trust_realm);
    3803           0 :         torture_assert(tctx, k5ok, assertion_message);
    3804           0 :         type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
    3805           0 :                                            ctx->krbtgt_referral_creds.server);
    3806           0 :         torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
    3807             : 
    3808             :         /* Delete the referral ticket from the cache */
    3809           0 :         k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
    3810             :                                     ctx->krbtgt_ccache,
    3811             :                                     0,
    3812             :                                     &ctx->krbtgt_referral_creds);
    3813           0 :         assertion_message = talloc_asprintf(ctx,
    3814             :                                 "krb5_cc_remove_cred(%s) for failed: (%d) %s",
    3815             :                                 krbtgt_trust_realm_string,
    3816             :                                 k5ret,
    3817           0 :                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
    3818             :                                                            k5ret, ctx));
    3819           0 :         torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
    3820             : #endif
    3821             : 
    3822             :         /* Confirm if we can do a TGS for krbtgt/NETBIOS with CANON */
    3823         144 :         ZERO_STRUCT(ctx->counts);
    3824         144 :         k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
    3825             :                                ctx->opt_canon,
    3826             :                                ctx->krbtgt_ccache,
    3827         144 :                                ctx->krbtgt_trust_netbios,
    3828             :                                &ctx->krbtgt_trust_netbios_creds);
    3829         144 :         assertion_message = talloc_asprintf(ctx,
    3830             :                                 "krb5_get_creds(%s, canon) for failed: "
    3831             :                                 "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
    3832             :                                 krbtgt_trust_netbios_string,
    3833             :                                 k5ret,
    3834         144 :                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
    3835             :                                                            k5ret, ctx),
    3836         144 :                                 trusted->trust_direction,
    3837         144 :                                 trusted->trust_type,
    3838         144 :                                 trusted->trust_attributes,
    3839             :                                 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
    3840             : #ifdef USING_EMBEDDED_HEIMDAL
    3841         144 :         torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
    3842             : #else
    3843           0 :         torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
    3844             : #endif
    3845         144 :         torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
    3846         144 :         torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
    3847             : 
    3848             :         /* Confirm if we have the referral ticket in the cache */
    3849         144 :         krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
    3850             :                                 &ctx->krbtgt_referral_creds);
    3851         144 :         k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
    3852             :                                       ctx->krbtgt_ccache,
    3853             :                                       0,
    3854         144 :                                       ctx->krbtgt_trust_realm_creds,
    3855             :                                       &ctx->krbtgt_referral_creds);
    3856         144 :         assertion_message = talloc_asprintf(ctx,
    3857             :                                 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
    3858             :                                 krbtgt_trust_netbios_string,
    3859             :                                 k5ret,
    3860         144 :                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
    3861             :                                                            k5ret, ctx));
    3862             : #ifdef USING_EMBEDDED_HEIMDAL
    3863         144 :         torture_assert_int_equal(tctx, k5ret, KRB5_CC_END, assertion_message);
    3864             : #else
    3865           0 :         torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
    3866             : 
    3867           0 :         k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
    3868           0 :                                       ctx->krbtgt_referral_creds.server,
    3869           0 :                                       ctx->krbtgt_trust_realm);
    3870           0 :         torture_assert(tctx, k5ok, assertion_message);
    3871           0 :         type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
    3872           0 :                                            ctx->krbtgt_referral_creds.server);
    3873           0 :         torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
    3874             : 
    3875             :         /* Delete the referral ticket from the cache */
    3876           0 :         k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
    3877             :                                     ctx->krbtgt_ccache,
    3878             :                                     0,
    3879             :                                     &ctx->krbtgt_referral_creds);
    3880           0 :         assertion_message = talloc_asprintf(ctx,
    3881             :                                 "krb5_cc_remove_cred(%s) for failed: (%d) %s",
    3882             :                                 krbtgt_trust_realm_string,
    3883             :                                 k5ret,
    3884           0 :                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
    3885             :                                                            k5ret, ctx));
    3886           0 :         torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
    3887             : #endif
    3888             : 
    3889             :         /* Confirm if we can do a TGS for krbtgt/NETBIOS no CANON */
    3890         144 :         ZERO_STRUCT(ctx->counts);
    3891         144 :         k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
    3892             :                                ctx->opt_nocanon,
    3893             :                                ctx->krbtgt_ccache,
    3894         144 :                                ctx->krbtgt_trust_netbios,
    3895             :                                &ctx->krbtgt_trust_netbios_creds);
    3896         144 :         assertion_message = talloc_asprintf(ctx,
    3897             :                                 "krb5_get_creds(%s, nocanon) for failed: "
    3898             :                                 "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
    3899             :                                 krbtgt_trust_netbios_string,
    3900             :                                 k5ret,
    3901         144 :                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
    3902             :                                                            k5ret, ctx),
    3903         144 :                                 trusted->trust_direction,
    3904         144 :                                 trusted->trust_type,
    3905         144 :                                 trusted->trust_attributes,
    3906             :                                 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
    3907         144 :         torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
    3908             : #ifdef USING_EMBEDDED_HEIMDAL
    3909         144 :         torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
    3910         144 :         torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
    3911             : #else
    3912           0 :         torture_assert_int_equal(tctx, ctx->counts.io, 2, assertion_message);
    3913           0 :         torture_assert_int_equal(tctx, ctx->counts.ok, 2, assertion_message);
    3914             : #endif
    3915             : 
    3916         144 :         k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
    3917         144 :                                       ctx->krbtgt_trust_netbios_creds->server,
    3918             : #ifdef USING_EMBEDDED_HEIMDAL
    3919         144 :                                       ctx->krbtgt_trust_netbios);
    3920             : #else
    3921           0 :                                       ctx->krbtgt_trust_realm);
    3922             : #endif
    3923         144 :         torture_assert(tctx, k5ok, assertion_message);
    3924         144 :         type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
    3925         144 :                                            ctx->krbtgt_trust_netbios_creds->server);
    3926         144 :         torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
    3927             : 
    3928             :         /* Confirm if we have the referral ticket in the cache */
    3929         144 :         krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
    3930             :                                 &ctx->krbtgt_referral_creds);
    3931         144 :         k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
    3932             :                                       ctx->krbtgt_ccache,
    3933             :                                       0,
    3934         144 :                                       ctx->krbtgt_trust_realm_creds,
    3935             :                                       &ctx->krbtgt_referral_creds);
    3936         144 :         assertion_message = talloc_asprintf(ctx,
    3937             :                                 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
    3938             :                                 krbtgt_trust_realm_string,
    3939             :                                 k5ret,
    3940         144 :                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
    3941             :                                                            k5ret, ctx));
    3942             : #ifdef USING_EMBEDDED_HEIMDAL
    3943         144 :         torture_assert_int_equal(tctx, k5ret, KRB5_CC_END, assertion_message);
    3944             : #else
    3945           0 :         torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
    3946             : 
    3947           0 :         k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
    3948           0 :                                       ctx->krbtgt_referral_creds.server,
    3949           0 :                                       ctx->krbtgt_trust_realm);
    3950           0 :         torture_assert(tctx, k5ok, assertion_message);
    3951           0 :         type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
    3952           0 :                                            ctx->krbtgt_referral_creds.server);
    3953           0 :         torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
    3954             : 
    3955             :         /* Delete the referral ticket from the cache */
    3956           0 :         k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
    3957             :                                     ctx->krbtgt_ccache,
    3958             :                                     0,
    3959             :                                     &ctx->krbtgt_referral_creds);
    3960           0 :         assertion_message = talloc_asprintf(ctx,
    3961             :                                 "krb5_cc_remove_cred(%s) for failed: (%d) %s",
    3962             :                                 krbtgt_trust_realm_string,
    3963             :                                 k5ret,
    3964           0 :                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
    3965             :                                                            k5ret, ctx));
    3966           0 :         torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
    3967             : #endif
    3968             : 
    3969         144 :         cifs_trust_dns_string = talloc_asprintf(ctx, "cifs/%s@%s",
    3970             :                                                 trusted_dns_name, realm);
    3971         144 :         torture_assert_int_equal(tctx,
    3972             :                         smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
    3973             :                                                 &ctx->cifs_trust_dns,
    3974             :                                                 realm, "cifs",
    3975             :                                                 trusted_dns_name, NULL),
    3976             :                         0, "smb_krb5_make_principal failed");
    3977             : 
    3978             :         /* Confirm if we get krbtgt/trusted_realm back when asking for cifs/trusted_realm */
    3979         144 :         ZERO_STRUCT(ctx->counts);
    3980         144 :         k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
    3981             :                                ctx->opt_canon,
    3982             :                                ctx->krbtgt_ccache,
    3983         144 :                                ctx->cifs_trust_dns,
    3984             :                                &ctx->cifs_trust_dns_creds);
    3985         144 :         assertion_message = talloc_asprintf(ctx,
    3986             :                                 "krb5_get_creds(%s) for failed: (%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
    3987             :                                 cifs_trust_dns_string,
    3988             :                                 k5ret,
    3989         144 :                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
    3990             :                                                            k5ret, ctx),
    3991         144 :                                 trusted->trust_direction,
    3992         144 :                                 trusted->trust_type,
    3993         144 :                                 trusted->trust_attributes,
    3994             :                                 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
    3995         144 :         torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
    3996             : #ifdef USING_EMBEDDED_HEIMDAL
    3997         144 :         torture_assert_int_equal(tctx, ctx->counts.io, 2, assertion_message);
    3998         144 :         torture_assert_int_equal(tctx, ctx->counts.ok, 2, assertion_message);
    3999             : #else
    4000           0 :         torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
    4001           0 :         torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
    4002             : #endif
    4003             : 
    4004             :         /* Confirm if we have the referral ticket in the cache */
    4005         144 :         krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
    4006             :                                 &ctx->krbtgt_referral_creds);
    4007         144 :         k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
    4008             :                                       ctx->krbtgt_ccache,
    4009             :                                       0,
    4010         144 :                                       ctx->krbtgt_trust_realm_creds,
    4011             :                                       &ctx->krbtgt_referral_creds);
    4012         144 :         assertion_message = talloc_asprintf(ctx,
    4013             :                                 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
    4014             :                                 krbtgt_trust_realm_string,
    4015             :                                 k5ret,
    4016         144 :                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
    4017             :                                                            k5ret, ctx));
    4018             : #ifdef USING_EMBEDDED_HEIMDAL
    4019         144 :         torture_assert_int_equal(tctx, k5ret, KRB5_CC_END, assertion_message);
    4020             : #else
    4021           0 :         torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
    4022             : 
    4023           0 :         k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
    4024           0 :                                       ctx->krbtgt_referral_creds.server,
    4025           0 :                                       ctx->krbtgt_trust_realm);
    4026           0 :         torture_assert(tctx, k5ok, assertion_message);
    4027           0 :         type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
    4028           0 :                                            ctx->krbtgt_referral_creds.server);
    4029           0 :         torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
    4030             : 
    4031             :         /* Delete the referral ticket from the cache */
    4032           0 :         k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
    4033             :                                     ctx->krbtgt_ccache,
    4034             :                                     0,
    4035             :                                     &ctx->krbtgt_referral_creds);
    4036           0 :         assertion_message = talloc_asprintf(ctx,
    4037             :                                 "krb5_cc_remove_cred(%s) for failed: (%d) %s",
    4038             :                                 krbtgt_trust_realm_string,
    4039             :                                 k5ret,
    4040           0 :                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
    4041             :                                                            k5ret, ctx));
    4042           0 :         torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
    4043             : #endif
    4044             : 
    4045         144 :         cifs_trust_netbios_string = talloc_asprintf(ctx, "cifs/%s@%s",
    4046             :                                                 trusted_netbios_name, realm);
    4047         144 :         torture_assert_int_equal(tctx,
    4048             :                         smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
    4049             :                                                 &ctx->cifs_trust_netbios,
    4050             :                                                 realm, "cifs",
    4051             :                                                 trusted_netbios_name, NULL),
    4052             :                         0, "smb_krb5_make_principal failed");
    4053             : 
    4054             :         /* Confirm if we get krbtgt/trusted_realm back when asking for cifs/trusted_realm */
    4055         144 :         ZERO_STRUCT(ctx->counts);
    4056         144 :         k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
    4057             :                                ctx->opt_canon,
    4058             :                                ctx->krbtgt_ccache,
    4059         144 :                                ctx->cifs_trust_netbios,
    4060             :                                &ctx->cifs_trust_netbios_creds);
    4061         144 :         assertion_message = talloc_asprintf(ctx,
    4062             :                                 "krb5_get_creds(%s) for failed: (%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
    4063             :                                 cifs_trust_netbios_string,
    4064             :                                 k5ret,
    4065         144 :                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
    4066             :                                                            k5ret, ctx),
    4067         144 :                                 trusted->trust_direction,
    4068         144 :                                 trusted->trust_type,
    4069         144 :                                 trusted->trust_attributes,
    4070             :                                 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
    4071         144 :         torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
    4072             : #ifdef USING_EMBEDDED_HEIMDAL
    4073         144 :         torture_assert_int_equal(tctx, ctx->counts.io, 2, assertion_message);
    4074         144 :         torture_assert_int_equal(tctx, ctx->counts.ok, 2, assertion_message);
    4075             : #else
    4076           0 :         torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
    4077           0 :         torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
    4078             : #endif
    4079             : 
    4080             :         /* Confirm if we have the referral ticket in the cache */
    4081         144 :         krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
    4082             :                                 &ctx->krbtgt_referral_creds);
    4083         144 :         k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
    4084             :                                       ctx->krbtgt_ccache,
    4085             :                                       0,
    4086         144 :                                       ctx->krbtgt_trust_realm_creds,
    4087             :                                       &ctx->krbtgt_referral_creds);
    4088         144 :         assertion_message = talloc_asprintf(ctx,
    4089             :                                 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
    4090             :                                 krbtgt_trust_realm_string,
    4091             :                                 k5ret,
    4092         144 :                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
    4093             :                                                            k5ret, ctx));
    4094             : #ifdef USING_EMBEDDED_HEIMDAL
    4095         144 :         torture_assert_int_equal(tctx, k5ret, KRB5_CC_END, assertion_message);
    4096             : #else
    4097           0 :         torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
    4098             : 
    4099           0 :         k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
    4100           0 :                                       ctx->krbtgt_referral_creds.server,
    4101           0 :                                       ctx->krbtgt_trust_realm);
    4102           0 :         torture_assert(tctx, k5ok, assertion_message);
    4103           0 :         type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
    4104           0 :                                            ctx->krbtgt_referral_creds.server);
    4105           0 :         torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
    4106             : 
    4107             :         /* Delete the referral ticket from the cache */
    4108           0 :         k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
    4109             :                                     ctx->krbtgt_ccache,
    4110             :                                     0,
    4111             :                                     &ctx->krbtgt_referral_creds);
    4112           0 :         assertion_message = talloc_asprintf(ctx,
    4113             :                                 "krb5_cc_remove_cred(%s) for failed: (%d) %s",
    4114             :                                 krbtgt_trust_realm_string,
    4115             :                                 k5ret,
    4116           0 :                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
    4117             :                                                            k5ret, ctx));
    4118           0 :         torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
    4119             : #endif
    4120             : 
    4121         144 :         drs_trust_dns_string = talloc_asprintf(ctx,
    4122             :                         "E3514235-4B06-11D1-AB04-00C04FC2DCD2/%s/%s@%s",
    4123             :                         workstation, trusted_dns_name, realm);
    4124         144 :         torture_assert_int_equal(tctx,
    4125             :                         smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
    4126             :                                                 &ctx->drs_trust_dns,
    4127             :                                                 realm, "E3514235-4B06-11D1-AB04-00C04FC2DCD2",
    4128             :                                                 workstation, trusted_dns_name, NULL),
    4129             :                         0, "smb_krb5_make_principal failed");
    4130             : 
    4131             :         /* Confirm if we get krbtgt/trusted_realm back when asking for a 3 part principal */
    4132         144 :         ZERO_STRUCT(ctx->counts);
    4133         144 :         k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
    4134             :                                ctx->opt_canon,
    4135             :                                ctx->krbtgt_ccache,
    4136         144 :                                ctx->drs_trust_dns,
    4137             :                                &ctx->drs_trust_dns_creds);
    4138         144 :         assertion_message = talloc_asprintf(ctx,
    4139             :                                 "krb5_get_creds(%s) for failed: (%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
    4140             :                                 drs_trust_dns_string,
    4141             :                                 k5ret,
    4142         144 :                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
    4143             :                                                            k5ret, ctx),
    4144         144 :                                 trusted->trust_direction,
    4145         144 :                                 trusted->trust_type,
    4146         144 :                                 trusted->trust_attributes,
    4147             :                                 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
    4148         144 :         torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
    4149             : #ifdef USING_EMBEDDED_HEIMDAL
    4150         144 :         torture_assert_int_equal(tctx, ctx->counts.io, 2, assertion_message);
    4151         144 :         torture_assert_int_equal(tctx, ctx->counts.ok, 2, assertion_message);
    4152             : #else
    4153           0 :         torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
    4154           0 :         torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
    4155             : #endif
    4156             : 
    4157             :         /* Confirm if we have the referral ticket in the cache */
    4158         144 :         krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
    4159             :                                 &ctx->krbtgt_referral_creds);
    4160         144 :         k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
    4161             :                                       ctx->krbtgt_ccache,
    4162             :                                       0,
    4163         144 :                                       ctx->krbtgt_trust_realm_creds,
    4164             :                                       &ctx->krbtgt_referral_creds);
    4165         144 :         assertion_message = talloc_asprintf(ctx,
    4166             :                                 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
    4167             :                                 krbtgt_trust_realm_string,
    4168             :                                 k5ret,
    4169         144 :                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
    4170             :                                                            k5ret, ctx));
    4171             : #ifdef USING_EMBEDDED_HEIMDAL
    4172         144 :         torture_assert_int_equal(tctx, k5ret, KRB5_CC_END, assertion_message);
    4173             : #else
    4174           0 :         torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
    4175             : 
    4176           0 :         k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
    4177           0 :                                       ctx->krbtgt_referral_creds.server,
    4178           0 :                                       ctx->krbtgt_trust_realm);
    4179           0 :         torture_assert(tctx, k5ok, assertion_message);
    4180           0 :         type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
    4181           0 :                                            ctx->krbtgt_referral_creds.server);
    4182           0 :         torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
    4183             : 
    4184             :         /* Delete the referral ticket from the cache */
    4185           0 :         k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
    4186             :                                     ctx->krbtgt_ccache,
    4187             :                                     0,
    4188             :                                     &ctx->krbtgt_referral_creds);
    4189           0 :         assertion_message = talloc_asprintf(ctx,
    4190             :                                 "krb5_cc_remove_cred(%s) for failed: (%d) %s",
    4191             :                                 krbtgt_trust_realm_string,
    4192             :                                 k5ret,
    4193           0 :                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
    4194             :                                                            k5ret, ctx));
    4195           0 :         torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
    4196             : #endif
    4197             : 
    4198         144 :         drs_trust_netbios_string = talloc_asprintf(ctx,
    4199             :                         "E3514235-4B06-11D1-AB04-00C04FC2DCD2/%s/%s@%s",
    4200             :                         workstation, trusted_netbios_name, realm);
    4201         144 :         torture_assert_int_equal(tctx,
    4202             :                         smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
    4203             :                                                 &ctx->drs_trust_netbios,
    4204             :                                                 realm, "E3514235-4B06-11D1-AB04-00C04FC2DCD2",
    4205             :                                                 workstation, trusted_netbios_name, NULL),
    4206             :                         0, "smb_krb5_make_principal failed");
    4207             : 
    4208             :         /* Confirm if we get krbtgt/trusted_realm back when asking for a 3 part principal */
    4209         144 :         ZERO_STRUCT(ctx->counts);
    4210         144 :         k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
    4211             :                                ctx->opt_canon,
    4212             :                                ctx->krbtgt_ccache,
    4213         144 :                                ctx->drs_trust_netbios,
    4214             :                                &ctx->drs_trust_netbios_creds);
    4215         144 :         assertion_message = talloc_asprintf(ctx,
    4216             :                                 "krb5_get_creds(%s) for failed: (%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
    4217             :                                 drs_trust_netbios_string,
    4218             :                                 k5ret,
    4219         144 :                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
    4220             :                                                            k5ret, ctx),
    4221         144 :                                 trusted->trust_direction,
    4222         144 :                                 trusted->trust_type,
    4223         144 :                                 trusted->trust_attributes,
    4224             :                                 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
    4225         144 :         torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
    4226             : #ifdef USING_EMBEDDED_HEIMDAL
    4227         144 :         torture_assert_int_equal(tctx, ctx->counts.io, 2, assertion_message);
    4228         144 :         torture_assert_int_equal(tctx, ctx->counts.ok, 2, assertion_message);
    4229             : #else
    4230           0 :         torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
    4231           0 :         torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
    4232             : #endif
    4233             : 
    4234             :         /* Confirm if we have the referral ticket in the cache */
    4235         144 :         krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
    4236             :                                 &ctx->krbtgt_referral_creds);
    4237         144 :         k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
    4238             :                                       ctx->krbtgt_ccache,
    4239             :                                       0,
    4240         144 :                                       ctx->krbtgt_trust_realm_creds,
    4241             :                                       &ctx->krbtgt_referral_creds);
    4242         144 :         assertion_message = talloc_asprintf(ctx,
    4243             :                                 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
    4244             :                                 krbtgt_trust_realm_string,
    4245             :                                 k5ret,
    4246         144 :                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
    4247             :                                                            k5ret, ctx));
    4248             : #ifdef USING_EMBEDDED_HEIMDAL
    4249         144 :         torture_assert_int_equal(tctx, k5ret, KRB5_CC_END, assertion_message);
    4250             : #else
    4251           0 :         torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
    4252             : 
    4253           0 :         k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
    4254           0 :                                       ctx->krbtgt_referral_creds.server,
    4255           0 :                                       ctx->krbtgt_trust_realm);
    4256           0 :         torture_assert(tctx, k5ok, assertion_message);
    4257           0 :         type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
    4258           0 :                                            ctx->krbtgt_referral_creds.server);
    4259           0 :         torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
    4260             : 
    4261             :         /* Delete the referral ticket from the cache */
    4262           0 :         k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
    4263             :                                     ctx->krbtgt_ccache,
    4264             :                                     0,
    4265             :                                     &ctx->krbtgt_referral_creds);
    4266           0 :         assertion_message = talloc_asprintf(ctx,
    4267             :                                 "krb5_cc_remove_cred(%s) for failed: (%d) %s",
    4268             :                                 krbtgt_trust_realm_string,
    4269             :                                 k5ret,
    4270           0 :                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
    4271             :                                                            k5ret, ctx));
    4272           0 :         torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
    4273             : #endif
    4274             : 
    4275         144 :         four_trust_dns_string = talloc_asprintf(ctx, "four/tree/two/%s@%s",
    4276             :                                                 trusted_dns_name, realm);
    4277         144 :         torture_assert_int_equal(tctx,
    4278             :                         smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
    4279             :                                                 &ctx->four_trust_dns,
    4280             :                                                 realm, "four", "tree", "two",
    4281             :                                                 trusted_dns_name, NULL),
    4282             :                         0, "smb_krb5_make_principal failed");
    4283             : 
    4284             :         /* Confirm if we get an error back for a 4 part principal */
    4285         144 :         ZERO_STRUCT(ctx->counts);
    4286         144 :         k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
    4287             :                                ctx->opt_canon,
    4288             :                                ctx->krbtgt_ccache,
    4289         144 :                                ctx->four_trust_dns,
    4290             :                                &ctx->four_trust_dns_creds);
    4291         144 :         assertion_message = talloc_asprintf(ctx,
    4292             :                                 "krb5_get_creds(%s) for failed: (%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
    4293             :                                 four_trust_dns_string,
    4294             :                                 k5ret,
    4295         144 :                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
    4296             :                                                            k5ret, ctx),
    4297         144 :                                 trusted->trust_direction,
    4298         144 :                                 trusted->trust_type,
    4299         144 :                                 trusted->trust_attributes,
    4300             :                                 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
    4301         144 :         torture_assert_int_equal(tctx, k5ret, KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN, assertion_message);
    4302             : #ifdef USING_EMBEDDED_HEIMDAL
    4303         144 :         torture_assert_int_equal(tctx, ctx->counts.io, 2, assertion_message);
    4304         144 :         torture_assert_int_equal(tctx, ctx->counts.error_io, 2, assertion_message);
    4305             : #else
    4306           0 :         torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
    4307           0 :         torture_assert_int_equal(tctx, ctx->counts.error_io, 1, assertion_message);
    4308             : #endif
    4309         144 :         torture_assert_int_equal(tctx, KRB5_ERROR_CODE(&ctx->error), 7, assertion_message);
    4310             : 
    4311             :         /* Confirm if we have no referral ticket in the cache */
    4312         144 :         krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
    4313             :                                 &ctx->krbtgt_referral_creds);
    4314         144 :         k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
    4315             :                                       ctx->krbtgt_ccache,
    4316             :                                       0,
    4317         144 :                                       ctx->krbtgt_trust_realm_creds,
    4318             :                                       &ctx->krbtgt_referral_creds);
    4319         144 :         assertion_message = talloc_asprintf(ctx,
    4320             :                                 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
    4321             :                                 krbtgt_trust_realm_string,
    4322             :                                 k5ret,
    4323         144 :                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
    4324             :                                                            k5ret, ctx));
    4325         144 :         torture_assert_int_equal(tctx, k5ret, KRB5_CC_END, assertion_message);
    4326             : 
    4327         144 :         TALLOC_FREE(ctx);
    4328         144 :         return true;
    4329             : }
    4330             : #endif
    4331             : 
    4332         144 : static bool check_dom_trust_pw(struct dcerpc_pipe *p,
    4333             :                                struct torture_context *tctx,
    4334             :                                const char *our_netbios_name,
    4335             :                                const char *our_dns_name,
    4336             :                                enum netr_SchannelType secure_channel_type,
    4337             :                                const struct lsa_TrustDomainInfoInfoEx *trusted,
    4338             :                                const char *previous_password,
    4339             :                                const char *current_password,
    4340             :                                uint32_t current_version,
    4341             :                                const char *next_password,
    4342             :                                uint32_t next_version,
    4343             :                                bool expected_result)
    4344             : {
    4345           0 :         struct cli_credentials *incoming_creds;
    4346         144 :         char *server_name = NULL;
    4347         144 :         char *account = NULL;
    4348         144 :         char *principal = NULL;
    4349         144 :         char *workstation = NULL;
    4350         144 :         const char *binding = torture_setting_string(tctx, "binding", NULL);
    4351         144 :         const char *host = torture_setting_string(tctx, "host", NULL);
    4352           0 :         const char *ip;
    4353           0 :         struct nbt_name nbt_name;
    4354           0 :         struct dcerpc_binding *b2;
    4355           0 :         struct netlogon_creds_CredentialState *creds;
    4356           0 :         struct samr_CryptPassword samr_crypt_password;
    4357           0 :         struct netr_CryptPassword netr_crypt_password;
    4358           0 :         struct netr_Authenticator req_auth;
    4359           0 :         struct netr_Authenticator rep_auth;
    4360           0 :         struct netr_ServerPasswordSet2 s;
    4361         144 :         struct dcerpc_pipe *p1 = NULL;
    4362         144 :         struct dcerpc_pipe *p2 = NULL;
    4363           0 :         NTSTATUS status;
    4364           0 :         bool ok;
    4365           0 :         int rc;
    4366         144 :         const char *trusted_netbios_name = trusted->netbios_name.string;
    4367         144 :         const char *trusted_dns_name = trusted->domain_name.string;
    4368           0 :         struct tsocket_address *dest_addr;
    4369           0 :         struct cldap_socket *cldap;
    4370           0 :         struct cldap_netlogon cldap1;
    4371             : 
    4372         144 :         incoming_creds = cli_credentials_init(tctx);
    4373         144 :         torture_assert(tctx, incoming_creds, "cli_credentials_init");
    4374             : 
    4375         144 :         cli_credentials_set_domain(incoming_creds, our_netbios_name, CRED_SPECIFIED);
    4376         144 :         cli_credentials_set_realm(incoming_creds, our_dns_name, CRED_SPECIFIED);
    4377             : 
    4378         144 :         if (secure_channel_type == SEC_CHAN_DNS_DOMAIN) {
    4379          72 :                 account = talloc_asprintf(tctx, "%s.", trusted_dns_name);
    4380          72 :                 torture_assert(tctx, account, __location__);
    4381             : 
    4382          72 :                 principal = talloc_asprintf(tctx, "%s$@%s",
    4383             :                                             trusted_netbios_name,
    4384             :                                             cli_credentials_get_realm(incoming_creds));
    4385          72 :                 torture_assert(tctx, principal, __location__);
    4386             : 
    4387          72 :                 workstation = talloc_asprintf(tctx, "%sUP",
    4388             :                                               trusted_netbios_name);
    4389          72 :                 torture_assert(tctx, workstation, __location__);
    4390             :         } else {
    4391          72 :                 account = talloc_asprintf(tctx, "%s$", trusted_netbios_name);
    4392          72 :                 torture_assert(tctx, account, __location__);
    4393             : 
    4394          72 :                 workstation = talloc_asprintf(tctx, "%sDOWN",
    4395             :                                               trusted_netbios_name);
    4396          72 :                 torture_assert(tctx, workstation, __location__);
    4397             :         }
    4398             : 
    4399         144 :         cli_credentials_set_username(incoming_creds, account, CRED_SPECIFIED);
    4400         144 :         if (principal != NULL) {
    4401          72 :                 cli_credentials_set_principal(incoming_creds, principal,
    4402             :                                               CRED_SPECIFIED);
    4403             :         }
    4404         144 :         cli_credentials_set_kvno(incoming_creds, current_version);
    4405         144 :         cli_credentials_set_password(incoming_creds, current_password, CRED_SPECIFIED);
    4406         144 :         cli_credentials_set_old_password(incoming_creds, previous_password, CRED_SPECIFIED);
    4407         144 :         cli_credentials_set_workstation(incoming_creds, workstation, CRED_SPECIFIED);
    4408         144 :         cli_credentials_set_secure_channel_type(incoming_creds, secure_channel_type);
    4409             : 
    4410         144 :         make_nbt_name_server(&nbt_name, host);
    4411             : 
    4412         144 :         status = resolve_name_ex(lpcfg_resolve_context(tctx->lp_ctx),
    4413             :                                  0, 0, &nbt_name, tctx, &ip, tctx->ev);
    4414         144 :         torture_assert_ntstatus_ok(tctx, status,
    4415             :                         talloc_asprintf(tctx,"Failed to resolve %s: %s",
    4416             :                                         nbt_name.name, nt_errstr(status)));
    4417             : 
    4418         144 :         rc = tsocket_address_inet_from_strings(tctx, "ip",
    4419             :                                                ip,
    4420             :                                                lpcfg_cldap_port(tctx->lp_ctx),
    4421             :                                                &dest_addr);
    4422         144 :         torture_assert_int_equal(tctx, rc, 0,
    4423             :                                  talloc_asprintf(tctx,
    4424             :                                                  "tsocket_address_inet_from_strings failed parsing %s:%d",
    4425             :                                                  host, lpcfg_cldap_port(tctx->lp_ctx)));
    4426             : 
    4427             :         /* cldap_socket_init should now know about the dest. address */
    4428         144 :         status = cldap_socket_init(tctx, NULL, dest_addr, &cldap);
    4429         144 :         torture_assert_ntstatus_ok(tctx, status, "cldap_socket_init");
    4430             : 
    4431         144 :         ZERO_STRUCT(cldap1);
    4432         144 :         cldap1.in.dest_address = NULL;
    4433         144 :         cldap1.in.dest_port = 0;
    4434         144 :         cldap1.in.version = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX;
    4435         144 :         cldap1.in.user = account;
    4436         144 :         if (secure_channel_type == SEC_CHAN_DNS_DOMAIN) {
    4437          72 :                 cldap1.in.acct_control = ACB_AUTOLOCK;
    4438             :         } else {
    4439          72 :                 cldap1.in.acct_control = ACB_DOMTRUST;
    4440             :         }
    4441         144 :         status = cldap_netlogon(cldap, tctx, &cldap1);
    4442         144 :         torture_assert_ntstatus_ok(tctx, status, "cldap_netlogon");
    4443         144 :         torture_assert_int_equal(tctx, cldap1.out.netlogon.ntver,
    4444             :                                  NETLOGON_NT_VERSION_5EX,
    4445             :                                  "ntver");
    4446         144 :         torture_assert_int_equal(tctx, cldap1.out.netlogon.data.nt5_ex.nt_version,
    4447             :                                  NETLOGON_NT_VERSION_1 | NETLOGON_NT_VERSION_5EX,
    4448             :                                  "nt_version");
    4449         144 :         torture_assert_int_equal(tctx, cldap1.out.netlogon.data.nt5_ex.command,
    4450             :                                  LOGON_SAM_LOGON_RESPONSE_EX,
    4451             :                                  "command");
    4452         144 :         torture_assert_str_equal(tctx, cldap1.out.netlogon.data.nt5_ex.user_name,
    4453             :                                  cldap1.in.user,
    4454             :                                  "user_name");
    4455         144 :         server_name = talloc_asprintf(tctx, "\\\\%s",
    4456             :                         cldap1.out.netlogon.data.nt5_ex.pdc_dns_name);
    4457         144 :         torture_assert(tctx, server_name, __location__);
    4458             : 
    4459         144 :         status = dcerpc_parse_binding(tctx, binding, &b2);
    4460         144 :         torture_assert_ntstatus_ok(tctx, status, "Bad binding string");
    4461             : 
    4462         144 :         status = dcerpc_pipe_connect_b(tctx, &p1, b2,
    4463             :                                        &ndr_table_netlogon,
    4464             :                                        cli_credentials_init_anon(tctx),
    4465             :                                        tctx->ev, tctx->lp_ctx);
    4466         144 :         torture_assert_ntstatus_ok(tctx, status, "dcerpc_pipe_connect_b");
    4467             : 
    4468         144 :         ok = check_pw_with_ServerAuthenticate3(p1, tctx,
    4469             :                                                NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES,
    4470             :                                                server_name,
    4471             :                                                incoming_creds, &creds);
    4472         144 :         torture_assert_int_equal(tctx, ok, expected_result,
    4473             :                                  "check_pw_with_ServerAuthenticate3");
    4474         144 :         if (expected_result == true) {
    4475         108 :                 ok = test_SetupCredentialsPipe(p1, tctx, incoming_creds, creds,
    4476             :                                                DCERPC_SIGN | DCERPC_SEAL, &p2);
    4477         108 :                 torture_assert_int_equal(tctx, ok, true,
    4478             :                                          "test_SetupCredentialsPipe");
    4479             :         }
    4480         144 :         TALLOC_FREE(p1);
    4481             : 
    4482         144 :         if (trusted->trust_type != LSA_TRUST_TYPE_DOWNLEVEL) {
    4483             : #ifdef SAMBA4_USES_HEIMDAL
    4484          96 :                 ok = check_pw_with_krb5(tctx, incoming_creds, trusted);
    4485          96 :                 torture_assert_int_equal(tctx, ok, expected_result,
    4486             :                                          "check_pw_with_krb5");
    4487             : #else
    4488           0 :                 torture_comment(tctx, "skipping check_pw_with_krb5 for MIT Kerberos build");
    4489             : #endif
    4490             :         }
    4491             : 
    4492         144 :         if (expected_result != true || next_password == NULL) {
    4493          36 :                 TALLOC_FREE(p2);
    4494          36 :                 return true;
    4495             :         }
    4496             : 
    4497             :         /*
    4498             :          * netr_ServerPasswordSet2
    4499             :          */
    4500         108 :         ok = encode_pw_buffer(samr_crypt_password.data,
    4501             :                               next_password, STR_UNICODE);
    4502         108 :         torture_assert(tctx, ok, "encode_pw_buffer");
    4503             : 
    4504         108 :         if (next_version != 0) {
    4505           0 :                 struct NL_PASSWORD_VERSION version;
    4506         108 :                 uint32_t len = IVAL(samr_crypt_password.data, 512);
    4507         108 :                 uint32_t ofs = 512 - len;
    4508           0 :                 uint8_t *ptr;
    4509             : 
    4510         108 :                 ofs -= 12;
    4511             : 
    4512         108 :                 version.ReservedField = 0;
    4513         108 :                 version.PasswordVersionNumber = next_version;
    4514         108 :                 version.PasswordVersionPresent =
    4515             :                         NETLOGON_PASSWORD_VERSION_NUMBER_PRESENT;
    4516             : 
    4517         108 :                 ptr = samr_crypt_password.data + ofs;
    4518         108 :                 SIVAL(ptr, 0, version.ReservedField);
    4519         108 :                 SIVAL(ptr, 4, version.PasswordVersionNumber);
    4520         108 :                 SIVAL(ptr, 8, version.PasswordVersionPresent);
    4521             :         }
    4522             : 
    4523         108 :         netlogon_creds_client_authenticator(creds, &req_auth);
    4524         108 :         ZERO_STRUCT(rep_auth);
    4525             : 
    4526         108 :         if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
    4527         108 :                 netlogon_creds_aes_encrypt(creds,
    4528             :                                            samr_crypt_password.data,
    4529             :                                            516);
    4530             :         } else {
    4531           0 :                 netlogon_creds_arcfour_crypt(creds,
    4532             :                                              samr_crypt_password.data,
    4533             :                                              516);
    4534             :         }
    4535             : 
    4536         108 :         memcpy(netr_crypt_password.data,
    4537             :                samr_crypt_password.data, 512);
    4538         108 :         netr_crypt_password.length = IVAL(samr_crypt_password.data, 512);
    4539             : 
    4540             : 
    4541         108 :         s.in.server_name = server_name;
    4542         108 :         s.in.account_name = cli_credentials_get_username(incoming_creds);
    4543         108 :         s.in.secure_channel_type = cli_credentials_get_secure_channel_type(incoming_creds);
    4544         108 :         s.in.computer_name = cli_credentials_get_workstation(incoming_creds);
    4545         108 :         s.in.credential = &req_auth;
    4546         108 :         s.in.new_password = &netr_crypt_password;
    4547         108 :         s.out.return_authenticator = &rep_auth;
    4548         108 :         status = dcerpc_netr_ServerPasswordSet2_r(p2->binding_handle, tctx, &s);
    4549         108 :         torture_assert_ntstatus_ok(tctx, status, "failed to set password");
    4550             : 
    4551         108 :         ok = netlogon_creds_client_check(creds, &rep_auth.cred);
    4552         108 :         torture_assert(tctx, ok, "netlogon_creds_client_check");
    4553             : 
    4554         108 :         cli_credentials_set_kvno(incoming_creds, next_version);
    4555         108 :         cli_credentials_set_password(incoming_creds, next_password, CRED_SPECIFIED);
    4556         108 :         cli_credentials_set_old_password(incoming_creds, current_password, CRED_SPECIFIED);
    4557             : 
    4558         108 :         TALLOC_FREE(p2);
    4559         108 :         status = dcerpc_pipe_connect_b(tctx, &p2, b2,
    4560             :                                        &ndr_table_netlogon,
    4561             :                                        cli_credentials_init_anon(tctx),
    4562             :                                        tctx->ev, tctx->lp_ctx);
    4563         108 :         torture_assert_ntstatus_ok(tctx, status, "dcerpc_pipe_connect_b");
    4564             : 
    4565         108 :         ok = check_pw_with_ServerAuthenticate3(p2, tctx,
    4566             :                                                NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES,
    4567             :                                                server_name,
    4568             :                                                incoming_creds, &creds);
    4569         108 :         torture_assert(tctx, ok, "check_pw_with_ServerAuthenticate3 with changed password");
    4570             : 
    4571         108 :         if (trusted->trust_type != LSA_TRUST_TYPE_DOWNLEVEL) {
    4572             : #if SAMBA4_USES_HEIMDAL
    4573          72 :                 ok = check_pw_with_krb5(tctx, incoming_creds, trusted);
    4574          72 :                 torture_assert(tctx, ok, "check_pw_with_krb5 with changed password");
    4575             : #else
    4576           0 :                 torture_comment(tctx, "skipping check_pw_with_krb5 for MIT Kerberos build");
    4577             : #endif
    4578             :         }
    4579             : 
    4580         108 :         TALLOC_FREE(p2);
    4581         108 :         return true;
    4582             : }
    4583             : 
    4584             : enum ex_call {
    4585             :         CREATE_TRUSTED_DOMAIN_EX1 = 1,
    4586             :         CREATE_TRUSTED_DOMAIN_EX2 = 2,
    4587             :         CREATE_TRUSTED_DOMAIN_EX3 = 3,
    4588             : };
    4589             : 
    4590           9 : static bool test_CreateTrustedDomainEx_common(struct dcerpc_pipe *p,
    4591             :                                               struct torture_context *tctx,
    4592             :                                               struct policy_handle *handle,
    4593             :                                               uint32_t num_trusts,
    4594             :                                               enum ex_call ex_call)
    4595             : {
    4596           0 :         NTSTATUS status;
    4597           9 :         bool ret = true;
    4598           0 :         struct lsa_QueryInfoPolicy2 p2;
    4599           9 :         union lsa_PolicyInformation *our_info = NULL;
    4600           0 :         struct lsa_CreateTrustedDomainEx r;
    4601           0 :         struct lsa_CreateTrustedDomainEx2 r2;
    4602           9 :         struct lsa_CreateTrustedDomainEx3 r3 = {
    4603             :                 .in = {
    4604             :                         .access_mask = 0,
    4605             :                 }
    4606             :         };
    4607           0 :         struct lsa_TrustDomainInfoInfoEx trustinfo;
    4608           9 :         struct lsa_TrustDomainInfoAuthInfoInternal *authinfo_internal = NULL;
    4609           0 :         struct lsa_TrustDomainInfoAuthInfoInternalAES
    4610           9 :                 *authinfo_internal_aes = NULL;
    4611           9 :         struct lsa_TrustDomainInfoAuthInfo *authinfo = NULL;
    4612           0 :         struct dom_sid **domsid;
    4613           0 :         struct policy_handle *trustdom_handle;
    4614           0 :         struct lsa_QueryTrustedDomainInfo q;
    4615           9 :         union lsa_TrustedDomainInfo *info = NULL;
    4616           0 :         DATA_BLOB session_key;
    4617           0 :         int i;
    4618           9 :         struct dcerpc_binding_handle *b = p->binding_handle;
    4619           9 :         const char *id = "0";
    4620           9 :         const char *incoming_v00 = TRUSTPW "InV00";
    4621           9 :         const char *incoming_v0 = TRUSTPW "InV0";
    4622           9 :         const char *incoming_v1 = TRUSTPW "InV1";
    4623           9 :         const char *incoming_v2 = TRUSTPW "InV2";
    4624           9 :         const char *incoming_v40 = TRUSTPW "InV40";
    4625           9 :         const char *outgoing_v00 = TRUSTPW "OutV00";
    4626           9 :         const char *outgoing_v0 = TRUSTPW "OutV0";
    4627             : 
    4628           9 :         switch (ex_call) {
    4629           3 :         case CREATE_TRUSTED_DOMAIN_EX3:
    4630           3 :                 torture_comment(
    4631             :                         tctx,
    4632             :                         "\nTesting CreateTrustedDomainEx3 for %d domains\n",
    4633             :                         num_trusts
    4634             :                 );
    4635           3 :                 id = "4";
    4636           3 :                 break;
    4637           3 :         case CREATE_TRUSTED_DOMAIN_EX2:
    4638           3 :                 torture_comment(
    4639             :                         tctx,
    4640             :                         "\nTesting CreateTrustedDomainEx2 for %d domains\n",
    4641             :                         num_trusts
    4642             :                 );
    4643           3 :                 id = "3";
    4644           3 :                 break;
    4645           3 :         case CREATE_TRUSTED_DOMAIN_EX1:
    4646           3 :                 torture_comment(
    4647             :                         tctx,
    4648             :                         "\nTesting CreateTrustedDomainEx for %d domains\n",
    4649             :                         num_trusts
    4650             :                 );
    4651           3 :                 id = "2";
    4652           3 :                 break;
    4653             :         }
    4654             : 
    4655           9 :         domsid = talloc_array(tctx, struct dom_sid *, num_trusts);
    4656           9 :         trustdom_handle = talloc_array(tctx, struct policy_handle, num_trusts);
    4657             : 
    4658           9 :         status = dcerpc_fetch_session_key(p, &session_key);
    4659           9 :         if (!NT_STATUS_IS_OK(status)) {
    4660           0 :                 torture_comment(tctx, "dcerpc_fetch_session_key failed - %s\n", nt_errstr(status));
    4661           0 :                 return false;
    4662             :         }
    4663             : 
    4664           9 :         ZERO_STRUCT(p2);
    4665           9 :         p2.in.handle = handle;
    4666           9 :         p2.in.level = LSA_POLICY_INFO_DNS;
    4667           9 :         p2.out.info = &our_info;
    4668             : 
    4669           9 :         torture_assert_ntstatus_ok(tctx,
    4670             :                                 dcerpc_lsa_QueryInfoPolicy2_r(b, tctx, &p2),
    4671             :                                 "lsa_QueryInfoPolicy2 failed");
    4672           9 :         torture_assert_ntstatus_ok(tctx, p2.out.result,
    4673             :                                 "lsa_QueryInfoPolicy2 failed");
    4674           9 :         torture_assert(tctx, our_info != NULL, "lsa_QueryInfoPolicy2 our_info");
    4675             : 
    4676         117 :         for (i=0; i< num_trusts; i++) {
    4677         108 :                 char *trust_name = talloc_asprintf(tctx, "TORTURE%s%02d", id, i);
    4678         108 :                 char *trust_name_dns = talloc_asprintf(tctx, "torturedom%s%02d.samba._none_.example.com", id, i);
    4679         108 :                 char *trust_sid = talloc_asprintf(tctx, "S-1-5-21-97398-379795-%s%02d", id, i);
    4680           0 :                 bool ok;
    4681             : 
    4682         108 :                 domsid[i] = dom_sid_parse_talloc(tctx, trust_sid);
    4683             : 
    4684         108 :                 trustinfo.sid = domsid[i];
    4685         108 :                 trustinfo.netbios_name.string = trust_name;
    4686         108 :                 trustinfo.domain_name.string = trust_name_dns;
    4687             : 
    4688             :                 /* Create inbound, some outbound, and some
    4689             :                  * bi-directional trusts in a repeating pattern based
    4690             :                  * on i */
    4691             : 
    4692             :                 /* 1 == inbound, 2 == outbound, 3 == both */
    4693         108 :                 trustinfo.trust_direction = (i % 3) + 1;
    4694             : 
    4695             :                 /* Try different trust types too */
    4696             : 
    4697             :                 /* 1 == downlevel (NT4), 2 == uplevel (ADS), 3 == MIT (kerberos but not AD) */
    4698         108 :                 trustinfo.trust_type = (((i / 3) + 1) % 3) + 1;
    4699             : 
    4700         108 :                 trustinfo.trust_attributes = LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION;
    4701             : 
    4702         108 :                 switch(ex_call) {
    4703          36 :                 case CREATE_TRUSTED_DOMAIN_EX3:
    4704          36 :                         ok = rpc_lsa_encrypt_trustdom_info_aes(
    4705             :                                 tctx,
    4706             :                                 incoming_v00,
    4707             :                                 incoming_v0,
    4708             :                                 outgoing_v00,
    4709             :                                 outgoing_v0,
    4710             :                                 session_key,
    4711             :                                 &authinfo_internal_aes);
    4712          36 :                         if (!ok) {
    4713           0 :                                 torture_comment(tctx,
    4714             :                                                 "gen_authinfo_internal failed");
    4715           0 :                                 ret = false;
    4716             :                         }
    4717             : 
    4718          36 :                         r3.in.policy_handle = handle;
    4719          36 :                         r3.in.info = &trustinfo;
    4720          36 :                         r3.in.auth_info_internal = authinfo_internal_aes;
    4721          36 :                         r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    4722          36 :                         r3.out.trustdom_handle = &trustdom_handle[i];
    4723             : 
    4724          36 :                         torture_assert_ntstatus_ok(
    4725             :                                 tctx,
    4726             :                                 dcerpc_lsa_CreateTrustedDomainEx3_r(b,
    4727             :                                                                     tctx,
    4728             :                                                                     &r3),
    4729             :                                 "CreateTrustedDomainEx3 failed");
    4730             : 
    4731          36 :                         status = r3.out.result;
    4732          36 :                         break;
    4733          36 :                 case CREATE_TRUSTED_DOMAIN_EX2:
    4734          36 :                         ok = rpc_lsa_encrypt_trustdom_info(tctx,
    4735             :                                                            incoming_v00,
    4736             :                                                            incoming_v0,
    4737             :                                                            outgoing_v00,
    4738             :                                                            outgoing_v0,
    4739             :                                                            session_key,
    4740             :                                                            &authinfo_internal);
    4741          36 :                         if (!ok) {
    4742           0 :                                 torture_comment(
    4743             :                                         tctx,
    4744             :                                         "rpc_lsa_encrypt_trustdom_info failed");
    4745           0 :                                 ret = false;
    4746             :                         }
    4747             : 
    4748          36 :                         r2.in.policy_handle = handle;
    4749          36 :                         r2.in.info = &trustinfo;
    4750          36 :                         r2.in.auth_info_internal = authinfo_internal;
    4751          36 :                         r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    4752          36 :                         r2.out.trustdom_handle = &trustdom_handle[i];
    4753             : 
    4754          36 :                         torture_assert_ntstatus_ok(tctx,
    4755             :                                 dcerpc_lsa_CreateTrustedDomainEx2_r(b, tctx, &r2),
    4756             :                                 "CreateTrustedDomainEx2 failed");
    4757             : 
    4758          36 :                         status = r2.out.result;
    4759          36 :                         break;
    4760          36 :                 case CREATE_TRUSTED_DOMAIN_EX1:
    4761          36 :                         ok = gen_authinfo(tctx,
    4762             :                                           incoming_v00,
    4763             :                                           incoming_v0,
    4764             :                                           outgoing_v00,
    4765             :                                           outgoing_v0,
    4766             :                                           &authinfo);
    4767          36 :                         if (!ok) {
    4768           0 :                                 torture_comment(tctx, "gen_authinfonfo failed");
    4769           0 :                                 ret = false;
    4770             :                         }
    4771             : 
    4772          36 :                         r.in.policy_handle = handle;
    4773          36 :                         r.in.info = &trustinfo;
    4774          36 :                         r.in.auth_info = authinfo;
    4775          36 :                         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    4776          36 :                         r.out.trustdom_handle = &trustdom_handle[i];
    4777             : 
    4778          36 :                         torture_assert_ntstatus_ok(tctx,
    4779             :                                 dcerpc_lsa_CreateTrustedDomainEx_r(b, tctx, &r),
    4780             :                                 "CreateTrustedDomainEx failed");
    4781             : 
    4782          36 :                         status = r.out.result;
    4783          36 :                         break;
    4784             :                 }
    4785             : 
    4786         108 :                 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
    4787           0 :                         test_DeleteTrustedDomain(b, tctx, handle, trustinfo.netbios_name);
    4788             : 
    4789           0 :                         switch (ex_call) {
    4790           0 :                         case CREATE_TRUSTED_DOMAIN_EX3:
    4791           0 :                                 torture_assert_ntstatus_ok(
    4792             :                                         tctx,
    4793             :                                         dcerpc_lsa_CreateTrustedDomainEx3_r(
    4794             :                                                 b, tctx, &r3),
    4795             :                                         "CreateTrustedDomainEx3 failed");
    4796           0 :                                 status = r3.out.result;
    4797           0 :                                 break;
    4798           0 :                         case CREATE_TRUSTED_DOMAIN_EX2:
    4799           0 :                                 torture_assert_ntstatus_ok(
    4800             :                                         tctx,
    4801             :                                         dcerpc_lsa_CreateTrustedDomainEx2_r(
    4802             :                                                 b, tctx, &r2),
    4803             :                                         "CreateTrustedDomainEx2 failed");
    4804           0 :                                 status = r2.out.result;
    4805           0 :                                 break;
    4806           0 :                         case CREATE_TRUSTED_DOMAIN_EX1:
    4807           0 :                                 torture_assert_ntstatus_ok(
    4808             :                                         tctx,
    4809             :                                         dcerpc_lsa_CreateTrustedDomainEx_r(b,
    4810             :                                                                            tctx,
    4811             :                                                                            &r),
    4812             :                                         "CreateTrustedDomainEx failed");
    4813           0 :                                 status = r.out.result;
    4814           0 :                                 break;
    4815             :                         }
    4816             :                 }
    4817         108 :                 if (!NT_STATUS_IS_OK(status)) {
    4818           0 :                         torture_comment(tctx,
    4819             :                                         "CreateTrustedDomainEx(2|3) failed "
    4820             :                                         "with status: %s\n",
    4821             :                                         nt_errstr(status));
    4822           0 :                         ret = false;
    4823             :                 } else { /* For outbound and MIT trusts there is no trust account */
    4824         108 :                         if (trustinfo.trust_direction != 2 &&
    4825          72 :                             trustinfo.trust_type != 3) {
    4826             : 
    4827          54 :                                 if (torture_setting_bool(tctx, "samba3", false)) {
    4828           0 :                                         torture_comment(tctx, "skipping trusted domain auth tests against samba3\n");
    4829          72 :                                 } else if (ex_call == CREATE_TRUSTED_DOMAIN_EX1 &&
    4830          18 :                                            torture_setting_bool(tctx, "samba4", false)) {
    4831          18 :                                         torture_comment(tctx, "skipping CreateTrustedDomainEx trusted domain auth tests against samba4\n");
    4832             : 
    4833             :                                 } else {
    4834          36 :                                         ok = check_dom_trust_pw(p, tctx,
    4835          36 :                                                                 our_info->dns.name.string,
    4836          36 :                                                                 our_info->dns.dns_domain.string,
    4837             :                                                                 SEC_CHAN_DOMAIN,
    4838             :                                                                 &trustinfo,
    4839             :                                                                 NULL,
    4840             :                                                                 "x" TRUSTPW "x", 0,
    4841             :                                                                 NULL, 0,
    4842             :                                                                 false);
    4843          36 :                                         if (!ok) {
    4844           0 :                                                 torture_comment(tctx, "Password check passed unexpectedly\n");
    4845           0 :                                                 ret = false;
    4846             :                                         }
    4847          36 :                                         ok = check_dom_trust_pw(p, tctx,
    4848          36 :                                                                 our_info->dns.name.string,
    4849          36 :                                                                 our_info->dns.dns_domain.string,
    4850             :                                                                 SEC_CHAN_DOMAIN,
    4851             :                                                                 &trustinfo,
    4852             :                                                                 incoming_v00,
    4853             :                                                                 incoming_v0, 0,
    4854             :                                                                 incoming_v1, 1,
    4855             :                                                                 true);
    4856          36 :                                         if (!ok) {
    4857           0 :                                                 torture_comment(tctx, "Password check failed (SEC_CHAN_DOMAIN)\n");
    4858           0 :                                                 ret = false;
    4859             :                                         }
    4860          36 :                                         ok = check_dom_trust_pw(p, tctx,
    4861          36 :                                                                 our_info->dns.name.string,
    4862          36 :                                                                 our_info->dns.dns_domain.string,
    4863             :                                                                 SEC_CHAN_DNS_DOMAIN,
    4864             :                                                                 &trustinfo,
    4865             :                                                                 incoming_v0,
    4866             :                                                                 incoming_v1, 1,
    4867             :                                                                 incoming_v2, 2,
    4868             :                                                                 true);
    4869          36 :                                         if (!ok) {
    4870           0 :                                                 torture_comment(tctx, "Password check failed v2 (SEC_CHAN_DNS_DOMAIN)\n");
    4871           0 :                                                 ret = false;
    4872             :                                         }
    4873          36 :                                         ok = check_dom_trust_pw(p, tctx,
    4874          36 :                                                                 our_info->dns.name.string,
    4875          36 :                                                                 our_info->dns.dns_domain.string,
    4876             :                                                                 SEC_CHAN_DNS_DOMAIN,
    4877             :                                                                 &trustinfo,
    4878             :                                                                 incoming_v1,
    4879             :                                                                 incoming_v2, 2,
    4880             :                                                                 incoming_v40, 40,
    4881             :                                                                 true);
    4882          36 :                                         if (!ok) {
    4883           0 :                                                 torture_comment(tctx, "Password check failed v4 (SEC_CHAN_DNS_DOMAIN)\n");
    4884           0 :                                                 ret = false;
    4885             :                                         }
    4886             :                                 }
    4887             :                         }
    4888             : 
    4889         108 :                         q.in.trustdom_handle = &trustdom_handle[i];
    4890         108 :                         q.in.level = LSA_TRUSTED_DOMAIN_INFO_INFO_EX;
    4891         108 :                         q.out.info = &info;
    4892         108 :                         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryTrustedDomainInfo_r(b, tctx, &q),
    4893             :                                 "QueryTrustedDomainInfo failed");
    4894         108 :                         if (!NT_STATUS_IS_OK(q.out.result)) {
    4895           0 :                                 torture_comment(tctx, "QueryTrustedDomainInfo level 1 failed - %s\n", nt_errstr(q.out.result));
    4896           0 :                                 ret = false;
    4897         108 :                         } else if (!q.out.info) {
    4898           0 :                                 torture_comment(tctx, "QueryTrustedDomainInfo level 1 failed to return an info pointer\n");
    4899           0 :                                 ret = false;
    4900             :                         } else {
    4901         108 :                                 if (strcmp(info->info_ex.domain_name.string, trustinfo.domain_name.string) != 0) {
    4902           0 :                                         torture_comment(tctx, "QueryTrustedDomainInfo returned inconsistent long name: %s != %s\n",
    4903           0 :                                                info->info_ex.domain_name.string, trustinfo.domain_name.string);
    4904           0 :                                         ret = false;
    4905             :                                 }
    4906         108 :                                 if (strcmp(info->info_ex.netbios_name.string, trustinfo.netbios_name.string) != 0) {
    4907           0 :                                         torture_comment(tctx, "QueryTrustedDomainInfo returned inconsistent short name: %s != %s\n",
    4908           0 :                                                info->info_ex.netbios_name.string, trustinfo.netbios_name.string);
    4909           0 :                                         ret = false;
    4910             :                                 }
    4911         108 :                                 if (info->info_ex.trust_type != trustinfo.trust_type) {
    4912           0 :                                         torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust type %d != %d\n",
    4913           0 :                                                trust_name, info->info_ex.trust_type, trustinfo.trust_type);
    4914           0 :                                         ret = false;
    4915             :                                 }
    4916         108 :                                 if (info->info_ex.trust_attributes != LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION) {
    4917           0 :                                         torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust attributes %d != %d\n",
    4918           0 :                                                trust_name, info->info_ex.trust_attributes, LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION);
    4919           0 :                                         ret = false;
    4920             :                                 }
    4921         108 :                                 if (info->info_ex.trust_direction != trustinfo.trust_direction) {
    4922           0 :                                         torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust direction %d != %d\n",
    4923           0 :                                                trust_name, info->info_ex.trust_direction, trustinfo.trust_direction);
    4924           0 :                                         ret = false;
    4925             :                                 }
    4926             :                         }
    4927             :                 }
    4928             :         }
    4929             : 
    4930             :         /* now that we have some domains to look over, we can test the enum calls */
    4931           9 :         if (!test_EnumTrustDom(b, tctx, handle)) {
    4932           0 :                 torture_comment(tctx, "test_EnumTrustDom failed\n");
    4933           0 :                 ret = false;
    4934             :         }
    4935             : 
    4936           9 :         if (!test_EnumTrustDomEx(b, tctx, handle)) {
    4937           0 :                 torture_comment(tctx, "test_EnumTrustDomEx failed\n");
    4938           0 :                 ret = false;
    4939             :         }
    4940             : 
    4941         117 :         for (i=0; i<num_trusts; i++) {
    4942         108 :                 if (!test_DeleteTrustedDomainBySid(b, tctx, handle, domsid[i])) {
    4943           0 :                         torture_comment(tctx, "test_DeleteTrustedDomainBySid failed\n");
    4944           0 :                         ret = false;
    4945             :                 }
    4946             :         }
    4947             : 
    4948           9 :         return ret;
    4949             : }
    4950             : 
    4951           3 : static bool test_CreateTrustedDomainEx3(struct dcerpc_pipe *p,
    4952             :                                         struct torture_context *tctx,
    4953             :                                         struct policy_handle *handle,
    4954             :                                         uint32_t num_trusts)
    4955             : {
    4956           3 :         return test_CreateTrustedDomainEx_common(
    4957             :                 p,
    4958             :                 tctx,
    4959             :                 handle,
    4960             :                 num_trusts,
    4961             :                 CREATE_TRUSTED_DOMAIN_EX3
    4962             :         );
    4963             : }
    4964             : 
    4965           3 : static bool test_CreateTrustedDomainEx2(struct dcerpc_pipe *p,
    4966             :                                         struct torture_context *tctx,
    4967             :                                         struct policy_handle *handle,
    4968             :                                         uint32_t num_trusts)
    4969             : {
    4970           3 :         return test_CreateTrustedDomainEx_common(
    4971             :                 p,
    4972             :                 tctx,
    4973             :                 handle,
    4974             :                 num_trusts,
    4975             :                 CREATE_TRUSTED_DOMAIN_EX2
    4976             :         );
    4977             : }
    4978             : 
    4979           3 : static bool test_CreateTrustedDomainEx(struct dcerpc_pipe *p,
    4980             :                                        struct torture_context *tctx,
    4981             :                                        struct policy_handle *handle,
    4982             :                                        uint32_t num_trusts)
    4983             : {
    4984           3 :         return test_CreateTrustedDomainEx_common(
    4985             :                 p,
    4986             :                 tctx,
    4987             :                 handle,
    4988             :                 num_trusts,
    4989             :                 CREATE_TRUSTED_DOMAIN_EX1
    4990             :         );
    4991             : }
    4992             : 
    4993          14 : static bool test_QueryDomainInfoPolicy(struct dcerpc_binding_handle *b,
    4994             :                                  struct torture_context *tctx,
    4995             :                                  struct policy_handle *handle)
    4996             : {
    4997           0 :         struct lsa_QueryDomainInformationPolicy r;
    4998          14 :         union lsa_DomainInformationPolicy *info = NULL;
    4999           0 :         int i;
    5000          14 :         bool ret = true;
    5001             : 
    5002          14 :         if (torture_setting_bool(tctx, "samba3", false)) {
    5003           2 :                 torture_skip(tctx, "skipping QueryDomainInformationPolicy test\n");
    5004             :         }
    5005             : 
    5006          12 :         torture_comment(tctx, "\nTesting QueryDomainInformationPolicy\n");
    5007             : 
    5008          36 :         for (i=2;i<4;i++) {
    5009          24 :                 r.in.handle = handle;
    5010          24 :                 r.in.level = i;
    5011          24 :                 r.out.info = &info;
    5012             : 
    5013          24 :                 torture_comment(tctx, "\nTrying QueryDomainInformationPolicy level %d\n", i);
    5014             : 
    5015          24 :                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryDomainInformationPolicy_r(b, tctx, &r),
    5016             :                         "QueryDomainInformationPolicy failed");
    5017             : 
    5018             :                 /* If the server does not support EFS, then this is the correct return */
    5019          24 :                 if (i == LSA_DOMAIN_INFO_POLICY_EFS && NT_STATUS_EQUAL(r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
    5020          12 :                         continue;
    5021          12 :                 } else if (!NT_STATUS_IS_OK(r.out.result)) {
    5022           0 :                         torture_comment(tctx, "QueryDomainInformationPolicy failed - %s\n", nt_errstr(r.out.result));
    5023           0 :                         ret = false;
    5024           0 :                         continue;
    5025             :                 }
    5026             :         }
    5027             : 
    5028          12 :         return ret;
    5029             : }
    5030             : 
    5031             : 
    5032          28 : static bool test_QueryInfoPolicyCalls(  bool version2,
    5033             :                                         struct dcerpc_binding_handle *b,
    5034             :                                         struct torture_context *tctx,
    5035             :                                         struct policy_handle *handle)
    5036             : {
    5037           0 :         struct lsa_QueryInfoPolicy r;
    5038          28 :         union lsa_PolicyInformation *info = NULL;
    5039           0 :         int i;
    5040          28 :         bool ret = true;
    5041          28 :         const char *call = talloc_asprintf(tctx, "QueryInfoPolicy%s", version2 ? "2":"");
    5042             : 
    5043          28 :         torture_comment(tctx, "\nTesting %s\n", call);
    5044             : 
    5045          28 :         if (version2 && torture_setting_bool(tctx, "samba3", false)) {
    5046           2 :                 torture_skip(tctx, "skipping QueryInfoPolicy2 tests\n");
    5047             :         }
    5048             : 
    5049         390 :         for (i=1;i<=14;i++) {
    5050         364 :                 r.in.handle = handle;
    5051         364 :                 r.in.level = i;
    5052         364 :                 r.out.info = &info;
    5053             : 
    5054         364 :                 torture_comment(tctx, "\nTrying %s level %d\n", call, i);
    5055             : 
    5056         364 :                 if (version2)
    5057             :                         /* We can perform the cast, because both types are
    5058             :                            structurally equal */
    5059         168 :                         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryInfoPolicy2_r(b, tctx,
    5060             :                                  (struct lsa_QueryInfoPolicy2*) &r),
    5061             :                                  "QueryInfoPolicy2 failed");
    5062             :                 else
    5063         196 :                         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryInfoPolicy_r(b, tctx, &r),
    5064             :                                 "QueryInfoPolicy2 failed");
    5065             : 
    5066         364 :                 switch (i) {
    5067          78 :                 case LSA_POLICY_INFO_MOD:
    5068             :                 case LSA_POLICY_INFO_AUDIT_FULL_SET:
    5069             :                 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
    5070          78 :                         if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
    5071           0 :                                 torture_comment(tctx, "Server should have failed level %u: %s\n", i, nt_errstr(r.out.result));
    5072           0 :                                 ret = false;
    5073             :                         }
    5074          78 :                         break;
    5075         208 :                 case LSA_POLICY_INFO_DOMAIN:
    5076             :                 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
    5077             :                 case LSA_POLICY_INFO_REPLICA:
    5078             :                 case LSA_POLICY_INFO_QUOTA:
    5079             :                 case LSA_POLICY_INFO_ROLE:
    5080             :                 case LSA_POLICY_INFO_AUDIT_LOG:
    5081             :                 case LSA_POLICY_INFO_AUDIT_EVENTS:
    5082             :                 case LSA_POLICY_INFO_PD:
    5083         208 :                         if (!NT_STATUS_IS_OK(r.out.result)) {
    5084           0 :                                 torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(r.out.result));
    5085           0 :                                 ret = false;
    5086             :                         }
    5087         208 :                         break;
    5088          78 :                 case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
    5089             :                 case LSA_POLICY_INFO_DNS_INT:
    5090             :                 case LSA_POLICY_INFO_DNS:
    5091          78 :                         if (torture_setting_bool(tctx, "samba3", false)) {
    5092             :                                 /* Other levels not implemented yet */
    5093           6 :                                 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_INFO_CLASS)) {
    5094           0 :                                         torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(r.out.result));
    5095           0 :                                         ret = false;
    5096             :                                 }
    5097          72 :                         } else if (!NT_STATUS_IS_OK(r.out.result)) {
    5098           0 :                                 torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(r.out.result));
    5099           0 :                                 ret = false;
    5100             :                         }
    5101          78 :                         break;
    5102           0 :                 default:
    5103           0 :                         if (torture_setting_bool(tctx, "samba4", false)) {
    5104             :                                 /* Other levels not implemented yet */
    5105           0 :                                 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_INFO_CLASS)) {
    5106           0 :                                         torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(r.out.result));
    5107           0 :                                         ret = false;
    5108             :                                 }
    5109           0 :                         } else if (!NT_STATUS_IS_OK(r.out.result)) {
    5110           0 :                                 torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(r.out.result));
    5111           0 :                                 ret = false;
    5112             :                         }
    5113           0 :                         break;
    5114             :                 }
    5115             : 
    5116         364 :                 if (NT_STATUS_IS_OK(r.out.result) && (i == LSA_POLICY_INFO_DNS
    5117         256 :                         || i == LSA_POLICY_INFO_DNS_INT)) {
    5118             :                         /* Let's look up some of these names */
    5119             : 
    5120           0 :                         struct lsa_TransNameArray tnames, dnames;
    5121          48 :                         tnames.count = 14;
    5122          48 :                         tnames.names = talloc_zero_array(tctx, struct lsa_TranslatedName, tnames.count);
    5123          48 :                         tnames.names[0].name.string = info->dns.name.string;
    5124          48 :                         tnames.names[0].sid_type = SID_NAME_DOMAIN;
    5125          48 :                         tnames.names[1].name.string = info->dns.dns_domain.string;
    5126          48 :                         tnames.names[1].sid_type = SID_NAME_DOMAIN;
    5127          48 :                         tnames.names[2].name.string = talloc_asprintf(tctx, "%s\\", info->dns.name.string);
    5128          48 :                         tnames.names[2].sid_type = SID_NAME_DOMAIN;
    5129          48 :                         tnames.names[3].name.string = talloc_asprintf(tctx, "%s\\", info->dns.dns_domain.string);
    5130          48 :                         tnames.names[3].sid_type = SID_NAME_DOMAIN;
    5131          48 :                         tnames.names[4].name.string = talloc_asprintf(tctx, "%s\\guest", info->dns.name.string);
    5132          48 :                         tnames.names[4].sid_type = SID_NAME_USER;
    5133          48 :                         tnames.names[5].name.string = talloc_asprintf(tctx, "%s\\krbtgt", info->dns.name.string);
    5134          48 :                         tnames.names[5].sid_type = SID_NAME_USER;
    5135          48 :                         tnames.names[6].name.string = talloc_asprintf(tctx, "%s\\guest", info->dns.dns_domain.string);
    5136          48 :                         tnames.names[6].sid_type = SID_NAME_USER;
    5137          48 :                         tnames.names[7].name.string = talloc_asprintf(tctx, "%s\\krbtgt", info->dns.dns_domain.string);
    5138          48 :                         tnames.names[7].sid_type = SID_NAME_USER;
    5139          48 :                         tnames.names[8].name.string = talloc_asprintf(tctx, "krbtgt@%s", info->dns.name.string);
    5140          48 :                         tnames.names[8].sid_type = SID_NAME_USER;
    5141          48 :                         tnames.names[9].name.string = talloc_asprintf(tctx, "krbtgt@%s", info->dns.dns_domain.string);
    5142          48 :                         tnames.names[9].sid_type = SID_NAME_USER;
    5143          48 :                         tnames.names[10].name.string = talloc_asprintf(tctx, "%s\\"TEST_MACHINENAME "$", info->dns.name.string);
    5144          48 :                         tnames.names[10].sid_type = SID_NAME_USER;
    5145          48 :                         tnames.names[11].name.string = talloc_asprintf(tctx, "%s\\"TEST_MACHINENAME "$", info->dns.dns_domain.string);
    5146          48 :                         tnames.names[11].sid_type = SID_NAME_USER;
    5147          48 :                         tnames.names[12].name.string = talloc_asprintf(tctx, TEST_MACHINENAME "$@%s", info->dns.name.string);
    5148          48 :                         tnames.names[12].sid_type = SID_NAME_USER;
    5149          48 :                         tnames.names[13].name.string = talloc_asprintf(tctx, TEST_MACHINENAME "$@%s", info->dns.dns_domain.string);
    5150          48 :                         tnames.names[13].sid_type = SID_NAME_USER;
    5151          48 :                         ret &= test_LookupNames(b, tctx, handle, LSA_LOOKUP_NAMES_ALL, &tnames);
    5152             : 
    5153             :                         /* Try to use in-forest search for the test machine */
    5154          48 :                         dnames.count = 1;
    5155          48 :                         dnames.names = talloc_zero_array(tctx, struct lsa_TranslatedName, dnames.count);
    5156          48 :                         dnames.names[0].name.string = talloc_asprintf(tctx, "%s\\"TEST_MACHINENAME "$", info->dns.name.string);
    5157          48 :                         dnames.names[0].sid_type = SID_NAME_USER;
    5158          48 :                         ret &= test_LookupNames(b, tctx, handle, LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2, &dnames);
    5159             :                 }
    5160             :         }
    5161             : 
    5162          26 :         return ret;
    5163             : }
    5164             : 
    5165          14 : static bool test_QueryInfoPolicy(struct dcerpc_binding_handle *b,
    5166             :                                  struct torture_context *tctx,
    5167             :                                  struct policy_handle *handle)
    5168             : {
    5169          14 :         return test_QueryInfoPolicyCalls(false, b, tctx, handle);
    5170             : }
    5171             : 
    5172          14 : static bool test_QueryInfoPolicy2(struct dcerpc_binding_handle *b,
    5173             :                                   struct torture_context *tctx,
    5174             :                                   struct policy_handle *handle)
    5175             : {
    5176          14 :         return test_QueryInfoPolicyCalls(true, b, tctx, handle);
    5177             : }
    5178             : 
    5179          46 : static bool test_GetUserName(struct dcerpc_binding_handle *b,
    5180             :                              struct torture_context *tctx)
    5181             : {
    5182           0 :         struct lsa_GetUserName r;
    5183          46 :         struct lsa_String *authority_name_p = NULL;
    5184          46 :         struct lsa_String *account_name_p = NULL;
    5185             : 
    5186          46 :         torture_comment(tctx, "\nTesting GetUserName\n");
    5187             : 
    5188          46 :         r.in.system_name        = "\\";
    5189          46 :         r.in.account_name       = &account_name_p;
    5190          46 :         r.in.authority_name     = NULL;
    5191          46 :         r.out.account_name      = &account_name_p;
    5192             : 
    5193          46 :         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetUserName_r(b, tctx, &r),
    5194             :                 "GetUserName failed");
    5195          46 :         torture_assert_ntstatus_ok(tctx, r.out.result,
    5196             :                 "GetUserName result failed");
    5197          46 :         torture_assert_not_null(tctx, r.out.account_name, "r.out.account_name");
    5198          46 :         torture_assert_not_null(tctx, *r.out.account_name, "*r.out.account_name");
    5199          46 :         torture_assert(tctx, r.out.authority_name == NULL, "r.out.authority_name");
    5200             : 
    5201          46 :         account_name_p = NULL;
    5202          46 :         r.in.account_name       = &account_name_p;
    5203          46 :         r.in.authority_name     = &authority_name_p;
    5204          46 :         r.out.account_name      = &account_name_p;
    5205             : 
    5206          46 :         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetUserName_r(b, tctx, &r),
    5207             :                 "GetUserName failed");
    5208          46 :         torture_assert_ntstatus_ok(tctx, r.out.result,
    5209             :                 "GetUserName result failed");
    5210          46 :         torture_assert_not_null(tctx, r.out.account_name, "r.out.account_name");
    5211          46 :         torture_assert_not_null(tctx, *r.out.account_name, "*r.out.account_name");
    5212          46 :         torture_assert_not_null(tctx, r.out.authority_name, "r.out.authority_name");
    5213          46 :         torture_assert_not_null(tctx, *r.out.authority_name, "*r.out.authority_name");
    5214             : 
    5215          46 :         torture_comment(tctx,
    5216             :                         "Account Name: %s, Authority Name: %s\n",
    5217          46 :                         (*r.out.account_name)->string,
    5218          46 :                         (*r.out.authority_name)->string);
    5219             : 
    5220          46 :         return true;
    5221             : }
    5222             : 
    5223           3 : static bool test_GetUserName_fail(struct dcerpc_binding_handle *b,
    5224             :                                   struct torture_context *tctx)
    5225             : {
    5226           0 :         struct lsa_GetUserName r;
    5227           3 :         struct lsa_String *account_name_p = NULL;
    5228           0 :         NTSTATUS status;
    5229             : 
    5230           3 :         torture_comment(tctx, "\nTesting GetUserName_fail\n");
    5231             : 
    5232           3 :         r.in.system_name        = "\\";
    5233           3 :         r.in.account_name       = &account_name_p;
    5234           3 :         r.in.authority_name     = NULL;
    5235           3 :         r.out.account_name      = &account_name_p;
    5236             : 
    5237           3 :         status = dcerpc_lsa_GetUserName_r(b, tctx, &r);
    5238           3 :         if (!NT_STATUS_IS_OK(status)) {
    5239           3 :                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
    5240           3 :                         torture_comment(tctx,
    5241             :                                         "GetUserName correctly returned with "
    5242             :                                         "status: %s\n",
    5243             :                                         nt_errstr(status));
    5244           3 :                         return true;
    5245             :                 }
    5246             : 
    5247           0 :                 torture_assert_ntstatus_equal(tctx,
    5248             :                                               status,
    5249             :                                               NT_STATUS_ACCESS_DENIED,
    5250             :                                               "GetUserName return value should "
    5251             :                                               "be ACCESS_DENIED");
    5252           0 :                 return true;
    5253             :         }
    5254             : 
    5255           0 :         if (!NT_STATUS_IS_OK(r.out.result)) {
    5256           0 :                 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) ||
    5257           0 :                     NT_STATUS_EQUAL(r.out.result, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
    5258           0 :                         torture_comment(tctx,
    5259             :                                         "GetUserName correctly returned with "
    5260             :                                         "result: %s\n",
    5261             :                                         nt_errstr(r.out.result));
    5262           0 :                         return true;
    5263             :                 }
    5264             :         }
    5265             : 
    5266           0 :         torture_assert_ntstatus_equal(tctx,
    5267             :                                       r.out.result,
    5268             :                                       NT_STATUS_OK,
    5269             :                                       "GetUserName return value should be "
    5270             :                                       "ACCESS_DENIED");
    5271             : 
    5272           0 :         return false;
    5273             : }
    5274             : 
    5275         123 : bool test_lsa_Close(struct dcerpc_binding_handle *b,
    5276             :                     struct torture_context *tctx,
    5277             :                     struct policy_handle *handle)
    5278             : {
    5279           6 :         struct lsa_Close r;
    5280           6 :         struct policy_handle handle2;
    5281             : 
    5282         123 :         torture_comment(tctx, "\nTesting Close\n");
    5283             : 
    5284         123 :         r.in.handle = handle;
    5285         123 :         r.out.handle = &handle2;
    5286             : 
    5287         123 :         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_Close_r(b, tctx, &r),
    5288             :                 "Close failed");
    5289         123 :         torture_assert_ntstatus_ok(tctx, r.out.result,
    5290             :                 "Close failed");
    5291             : 
    5292         123 :         torture_assert_ntstatus_equal(tctx, dcerpc_lsa_Close_r(b, tctx, &r),
    5293             :                 NT_STATUS_RPC_SS_CONTEXT_MISMATCH, "Close should failed");
    5294             : 
    5295         123 :         torture_comment(tctx, "\n");
    5296             : 
    5297         123 :         return true;
    5298             : }
    5299             : 
    5300          19 : bool torture_rpc_lsa(struct torture_context *tctx)
    5301             : {
    5302           0 :         NTSTATUS status;
    5303           0 :         struct dcerpc_pipe *p;
    5304          19 :         bool ret = true;
    5305          19 :         struct policy_handle *handle = NULL;
    5306          19 :         struct test_join *join = NULL;
    5307           0 :         struct cli_credentials *machine_creds;
    5308           0 :         struct dcerpc_binding_handle *b;
    5309           0 :         enum dcerpc_transport_t transport;
    5310             : 
    5311          19 :         status = torture_rpc_connection(tctx, &p, &ndr_table_lsarpc);
    5312          19 :         torture_assert_ntstatus_ok(tctx, status, "Error connecting to server");
    5313             : 
    5314          19 :         b = p->binding_handle;
    5315          19 :         transport = dcerpc_binding_get_transport(p->binding);
    5316             : 
    5317             :         /* Test lsaLookupSids3 and lsaLookupNames4 over tcpip */
    5318          19 :         if (transport == NCACN_IP_TCP) {
    5319           5 :                 if (!test_OpenPolicy_fail(b, tctx)) {
    5320           0 :                         ret = false;
    5321             :                 }
    5322             : 
    5323           5 :                 if (!test_OpenPolicy2_fail(b, tctx)) {
    5324           0 :                         ret = false;
    5325             :                 }
    5326             : 
    5327           5 :                 if (!test_OpenPolicy3_fail(b, tctx)) {
    5328           0 :                         ret = false;
    5329             :                 }
    5330             : 
    5331           5 :                 if (!test_many_LookupSids(p, tctx, handle, LSA_LOOKUP_NAMES_ALL)) {
    5332           0 :                         ret = false;
    5333             :                 }
    5334             : 
    5335           5 :                 return ret;
    5336             :         }
    5337             : 
    5338          14 :         if (!test_OpenPolicy(b, tctx)) {
    5339           0 :                 ret = false;
    5340             :         }
    5341             : 
    5342          14 :         if (!test_lsa_OpenPolicy2(b, tctx, &handle)) {
    5343           0 :                 ret = false;
    5344             :         }
    5345             : 
    5346          14 :         if (!test_lsa_OpenPolicy3(b, tctx, &handle)) {
    5347           0 :                 ret = false;
    5348             :         }
    5349             : 
    5350          14 :         if (handle) {
    5351          14 :                 join = torture_join_domain(tctx, TEST_MACHINENAME, ACB_WSTRUST, &machine_creds);
    5352          14 :                 if (!join) {
    5353           0 :                         ret = false;
    5354             :                 }
    5355             : 
    5356          14 :                 if (!test_LookupSids_async(b, tctx, handle, LSA_LOOKUP_NAMES_ALL)) {
    5357           0 :                         ret = false;
    5358             :                 }
    5359             : 
    5360          14 :                 if (!test_QueryDomainInfoPolicy(b, tctx, handle)) {
    5361           0 :                         ret = false;
    5362             :                 }
    5363             : 
    5364          14 :                 if (!test_CreateSecret(p, tctx, handle)) {
    5365           3 :                         ret = false;
    5366             :                 }
    5367             : 
    5368          14 :                 if (!test_QueryInfoPolicy(b, tctx, handle)) {
    5369           0 :                         ret = false;
    5370             :                 }
    5371             : 
    5372          14 :                 if (!test_QueryInfoPolicy2(b, tctx, handle)) {
    5373           0 :                         ret = false;
    5374             :                 }
    5375             : 
    5376          14 :                 if (!test_Delete(b, tctx, handle)) {
    5377           0 :                         ret = false;
    5378             :                 }
    5379             : 
    5380          14 :                 if (!test_many_LookupSids(p, tctx, handle, LSA_LOOKUP_NAMES_ALL)) {
    5381           0 :                         ret = false;
    5382             :                 }
    5383             : 
    5384          14 :                 if (!test_lsa_Close(b, tctx, handle)) {
    5385           0 :                         ret = false;
    5386             :                 }
    5387             : 
    5388          14 :                 torture_leave_domain(tctx, join);
    5389             : 
    5390             :         } else {
    5391           0 :                 if (!test_many_LookupSids(p, tctx, handle, LSA_LOOKUP_NAMES_ALL)) {
    5392           0 :                         ret = false;
    5393             :                 }
    5394             :         }
    5395             : 
    5396          14 :         if (!test_GetUserName(b, tctx)) {
    5397           0 :                 ret = false;
    5398             :         }
    5399             : 
    5400          14 :         return ret;
    5401             : }
    5402             : 
    5403          37 : bool torture_rpc_lsa_get_user(struct torture_context *tctx)
    5404             : {
    5405           0 :         NTSTATUS status;
    5406           0 :         struct dcerpc_pipe *p;
    5407          37 :         bool ret = true;
    5408           0 :         struct dcerpc_binding_handle *b;
    5409           0 :         enum dcerpc_transport_t transport;
    5410             : 
    5411          37 :         status = torture_rpc_connection(tctx, &p, &ndr_table_lsarpc);
    5412          37 :         torture_assert_ntstatus_ok(tctx, status, "Error connecting to server");
    5413             : 
    5414          35 :         b = p->binding_handle;
    5415          35 :         transport = dcerpc_binding_get_transport(p->binding);
    5416             : 
    5417          35 :         if (transport == NCACN_IP_TCP) {
    5418           3 :                 if (!test_GetUserName_fail(b, tctx)) {
    5419           0 :                         ret = false;
    5420             :                 }
    5421           3 :                 return ret;
    5422             :         }
    5423             : 
    5424          32 :         if (!test_GetUserName(b, tctx)) {
    5425           0 :                 ret = false;
    5426             :         }
    5427             : 
    5428          32 :         return ret;
    5429             : }
    5430             : 
    5431           5 : static bool testcase_LookupNames(struct torture_context *tctx,
    5432             :                                  struct dcerpc_pipe *p)
    5433             : {
    5434           5 :         bool ret = true;
    5435           0 :         struct policy_handle *handle;
    5436           0 :         struct lsa_TransNameArray tnames;
    5437           0 :         struct lsa_TransNameArray2 tnames2;
    5438           5 :         struct dcerpc_binding_handle *b = p->binding_handle;
    5439           5 :         enum dcerpc_transport_t transport = dcerpc_binding_get_transport(p->binding);
    5440             : 
    5441           5 :         if (transport != NCACN_NP && transport != NCALRPC) {
    5442           0 :                 torture_comment(tctx, "testcase_LookupNames is only available "
    5443             :                                 "over NCACN_NP or NCALRPC");
    5444           0 :                 return true;
    5445             :         }
    5446             : 
    5447           5 :         if (!test_OpenPolicy(b, tctx)) {
    5448           0 :                 ret = false;
    5449             :         }
    5450             : 
    5451           5 :         if (!test_lsa_OpenPolicy2(b, tctx, &handle)) {
    5452           0 :                 ret = false;
    5453             :         }
    5454             : 
    5455           5 :         if (!handle) {
    5456           0 :                 ret = false;
    5457             :         }
    5458             : 
    5459           5 :         tnames.count = 1;
    5460           5 :         tnames.names = talloc_array(tctx, struct lsa_TranslatedName, tnames.count);
    5461           5 :         ZERO_STRUCT(tnames.names[0]);
    5462           5 :         tnames.names[0].name.string = "BUILTIN";
    5463           5 :         tnames.names[0].sid_type = SID_NAME_DOMAIN;
    5464             : 
    5465           5 :         if (!test_LookupNames(b, tctx, handle, LSA_LOOKUP_NAMES_ALL, &tnames)) {
    5466           0 :                 ret = false;
    5467             :         }
    5468             : 
    5469           5 :         tnames2.count = 1;
    5470           5 :         tnames2.names = talloc_array(tctx, struct lsa_TranslatedName2, tnames2.count);
    5471           5 :         ZERO_STRUCT(tnames2.names[0]);
    5472           5 :         tnames2.names[0].name.string = "BUILTIN";
    5473           5 :         tnames2.names[0].sid_type = SID_NAME_DOMAIN;
    5474             : 
    5475           5 :         if (!test_LookupNames2(b, tctx, handle, LSA_LOOKUP_NAMES_ALL, &tnames2, true)) {
    5476           0 :                 ret = false;
    5477             :         }
    5478             : 
    5479           5 :         if (!test_LookupNames3(b, tctx, handle, LSA_LOOKUP_NAMES_ALL, &tnames2, true)) {
    5480           0 :                 ret = false;
    5481             :         }
    5482             : 
    5483           5 :         if (!test_LookupNames_wellknown(b, tctx, handle, LSA_LOOKUP_NAMES_ALL)) {
    5484           0 :                 ret = false;
    5485             :         }
    5486             : 
    5487           5 :         if (!test_LookupNames_NULL(b, tctx, handle, LSA_LOOKUP_NAMES_ALL)) {
    5488           0 :                 ret = false;
    5489             :         }
    5490             : 
    5491           5 :         if (!test_LookupNames_bogus(b, tctx, handle, LSA_LOOKUP_NAMES_ALL)) {
    5492           0 :                 ret = false;
    5493             :         }
    5494             : 
    5495           5 :         if (!test_lsa_Close(b, tctx, handle)) {
    5496           0 :                 ret = false;
    5497             :         }
    5498             : 
    5499           5 :         return ret;
    5500             : }
    5501             : 
    5502        2354 : struct torture_suite *torture_rpc_lsa_lookup_names(TALLOC_CTX *mem_ctx)
    5503             : {
    5504         125 :         struct torture_suite *suite;
    5505         125 :         struct torture_rpc_tcase *tcase;
    5506             : 
    5507        2354 :         suite = torture_suite_create(mem_ctx, "lsa.lookupnames");
    5508             : 
    5509        2354 :         tcase = torture_suite_add_rpc_iface_tcase(suite, "lsa",
    5510             :                                                   &ndr_table_lsarpc);
    5511        2354 :         torture_rpc_tcase_add_test(tcase, "LookupNames",
    5512             :                                    testcase_LookupNames);
    5513             : 
    5514        2354 :         return suite;
    5515             : }
    5516             : 
    5517             : struct lsa_trustdom_state {
    5518             :         uint32_t num_trusts;
    5519             : };
    5520             : 
    5521           3 : static bool testcase_TrustedDomains(struct torture_context *tctx,
    5522             :                                     struct dcerpc_pipe *p,
    5523             :                                     void *data)
    5524             : {
    5525           3 :         bool ret = true;
    5526           0 :         struct policy_handle *handle;
    5527           0 :         struct lsa_trustdom_state *state =
    5528           3 :                 talloc_get_type_abort(data, struct lsa_trustdom_state);
    5529           3 :         struct dcerpc_binding_handle *b = p->binding_handle;
    5530           3 :         enum dcerpc_transport_t transport = dcerpc_binding_get_transport(p->binding);
    5531             : 
    5532           3 :         if (transport != NCACN_NP && transport != NCALRPC) {
    5533           0 :                 torture_comment(tctx, "testcase_TrustedDomains is only available "
    5534             :                                 "over NCACN_NP or NCALRPC");
    5535           0 :                 return true;
    5536             :         }
    5537             : 
    5538           3 :         torture_comment(tctx, "Testing %d domains\n", state->num_trusts);
    5539             : 
    5540           3 :         if (!test_OpenPolicy(b, tctx)) {
    5541           0 :                 ret = false;
    5542             :         }
    5543             : 
    5544           3 :         if (!test_lsa_OpenPolicy2(b, tctx, &handle)) {
    5545           0 :                 ret = false;
    5546             :         }
    5547             : 
    5548           3 :         if (!test_lsa_OpenPolicy3(b, tctx, &handle)) {
    5549           0 :                 ret = false;
    5550             :         }
    5551             : 
    5552           3 :         if (!handle) {
    5553           0 :                 ret = false;
    5554             :         }
    5555             : 
    5556           3 :         if (!test_CreateTrustedDomain(b, tctx, handle, state->num_trusts)) {
    5557           0 :                 ret = false;
    5558             :         }
    5559             : 
    5560           3 :         if (!test_CreateTrustedDomainEx(p, tctx, handle, state->num_trusts)) {
    5561           0 :                 ret = false;
    5562             :         }
    5563             : 
    5564           3 :         if (!test_CreateTrustedDomainEx2(p, tctx, handle, state->num_trusts)) {
    5565           0 :                 ret = false;
    5566             :         }
    5567             : 
    5568           3 :         if (!test_CreateTrustedDomainEx3(p, tctx, handle, state->num_trusts)) {
    5569           0 :                 ret = false;
    5570             :         }
    5571             : 
    5572           3 :         if (!test_lsa_Close(b, tctx, handle)) {
    5573           0 :                 ret = false;
    5574             :         }
    5575             : 
    5576           3 :         return ret;
    5577             : }
    5578             : 
    5579        2354 : struct torture_suite *torture_rpc_lsa_trusted_domains(TALLOC_CTX *mem_ctx)
    5580             : {
    5581         125 :         struct torture_suite *suite;
    5582         125 :         struct torture_rpc_tcase *tcase;
    5583         125 :         struct lsa_trustdom_state *state;
    5584             : 
    5585        2354 :         state = talloc(mem_ctx, struct lsa_trustdom_state);
    5586             : 
    5587        2354 :         state->num_trusts = 12;
    5588             : 
    5589        2354 :         suite = torture_suite_create(mem_ctx, "lsa.trusted.domains");
    5590             : 
    5591        2354 :         tcase = torture_suite_add_rpc_iface_tcase(suite, "lsa",
    5592             :                                                   &ndr_table_lsarpc);
    5593        2354 :         torture_rpc_tcase_add_test_ex(tcase, "TrustedDomains",
    5594             :                                       testcase_TrustedDomains,
    5595             :                                       state);
    5596             : 
    5597        2354 :         return suite;
    5598             : }
    5599             : 
    5600           5 : static bool testcase_Privileges(struct torture_context *tctx,
    5601             :                                 struct dcerpc_pipe *p)
    5602             : {
    5603           0 :         struct policy_handle *handle;
    5604           5 :         struct dcerpc_binding_handle *b = p->binding_handle;
    5605           5 :         enum dcerpc_transport_t transport = dcerpc_binding_get_transport(p->binding);
    5606             : 
    5607           5 :         if (transport != NCACN_NP && transport != NCALRPC) {
    5608           0 :                 torture_skip(tctx, "testcase_Privileges is only available "
    5609             :                                 "over NCACN_NP or NCALRPC");
    5610             :         }
    5611             : 
    5612           5 :         if (!test_OpenPolicy(b, tctx)) {
    5613           0 :                 return false;
    5614             :         }
    5615             : 
    5616           5 :         if (!test_lsa_OpenPolicy2(b, tctx, &handle)) {
    5617           0 :                 return false;
    5618             :         }
    5619             : 
    5620           5 :         if (!handle) {
    5621           0 :                 return false;
    5622             :         }
    5623             : 
    5624           5 :         if (!test_CreateAccount(b, tctx, handle)) {
    5625           0 :                 return false;
    5626             :         }
    5627             : 
    5628           5 :         if (!test_EnumAccounts(b, tctx, handle)) {
    5629           0 :                 return false;
    5630             :         }
    5631             : 
    5632           5 :         if (!test_EnumPrivs(b, tctx, handle)) {
    5633           0 :                 return false;
    5634             :         }
    5635             : 
    5636           5 :         if (!test_lsa_Close(b, tctx, handle)) {
    5637           0 :                 return false;
    5638             :         }
    5639             : 
    5640           5 :         return true;
    5641             : }
    5642             : 
    5643             : 
    5644        2354 : struct torture_suite *torture_rpc_lsa_privileges(TALLOC_CTX *mem_ctx)
    5645             : {
    5646         125 :         struct torture_suite *suite;
    5647         125 :         struct torture_rpc_tcase *tcase;
    5648             : 
    5649        2354 :         suite = torture_suite_create(mem_ctx, "lsa.privileges");
    5650             : 
    5651        2354 :         tcase = torture_suite_add_rpc_iface_tcase(suite, "lsa",
    5652             :                                                   &ndr_table_lsarpc);
    5653        2354 :         torture_rpc_tcase_add_test(tcase, "Privileges",
    5654             :                                    testcase_Privileges);
    5655             : 
    5656        2354 :         return suite;
    5657             : }

Generated by: LCOV version 1.14