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

Generated by: LCOV version 1.14