From 80f0ebbd0be8bff9b396ab63b702e193027d1b02 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 18 Sep 2024 22:36:26 +0200 Subject: [PATCH 01/80] librpc/rpc: map DCERPC_NCA_S_SERVER_TOO_BUSY to NT_STATUS_RPC_SERVER_TOO_BUSY Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 722e93e4d9ace010e44cc041e6614ce5b71265d8) --- librpc/rpc/dcerpc_error.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/librpc/rpc/dcerpc_error.c b/librpc/rpc/dcerpc_error.c index d5b5b66ab6ae..1c6ca2bbd34a 100644 --- a/librpc/rpc/dcerpc_error.c +++ b/librpc/rpc/dcerpc_error.c @@ -40,7 +40,7 @@ static const struct dcerpc_fault_table dcerpc_faults[] = _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_YOU_CRASHED), _FAULT_STR(DCERPC_NCA_S_PROTO_ERROR, NT_STATUS_RPC_PROTOCOL_ERROR), _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_OUT_ARGS_TOO_BIG), - _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_SERVER_TOO_BUSY), + _FAULT_STR(DCERPC_NCA_S_SERVER_TOO_BUSY, NT_STATUS_RPC_SERVER_TOO_BUSY), _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_STRING_TOO_LARGE), _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_UNSUPPORTED_TYPE), _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_ADDR_ERROR), -- 2.49.0 From 11755e1def72d12b444a2dbff201f46f5203bfe5 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 18 Sep 2024 22:37:14 +0200 Subject: [PATCH 02/80] librpc/rpc: map DCERPC_NCA_S_UNSUPPORTED_TYPE to NT_STATUS_RPC_UNSUPPORTED_TYPE Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 492f6a0eef7e7c64806ac9137c18a76fd116766d) --- librpc/rpc/dcerpc_error.c | 2 +- source4/torture/rpc/iremotewinspool.c | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/librpc/rpc/dcerpc_error.c b/librpc/rpc/dcerpc_error.c index 1c6ca2bbd34a..26c963366154 100644 --- a/librpc/rpc/dcerpc_error.c +++ b/librpc/rpc/dcerpc_error.c @@ -42,7 +42,7 @@ static const struct dcerpc_fault_table dcerpc_faults[] = _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_OUT_ARGS_TOO_BIG), _FAULT_STR(DCERPC_NCA_S_SERVER_TOO_BUSY, NT_STATUS_RPC_SERVER_TOO_BUSY), _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_STRING_TOO_LARGE), - _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_UNSUPPORTED_TYPE), + _FAULT_STR(DCERPC_NCA_S_UNSUPPORTED_TYPE, NT_STATUS_RPC_UNSUPPORTED_TYPE), _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_ADDR_ERROR), _FAULT_STR(DCERPC_NCA_S_FAULT_FP_DIV_BY_ZERO, NT_STATUS_RPC_FP_DIV_ZERO), _FAULT_STR(DCERPC_NCA_S_FAULT_FP_UNDERFLOW, NT_STATUS_RPC_FP_UNDERFLOW), diff --git a/source4/torture/rpc/iremotewinspool.c b/source4/torture/rpc/iremotewinspool.c index 3a7ee6482786..d43f4ff36a4c 100644 --- a/source4/torture/rpc/iremotewinspool.c +++ b/source4/torture/rpc/iremotewinspool.c @@ -884,21 +884,21 @@ static bool test_object_uuid(struct torture_context *tctx, torture_assert(tctx, test_object_one_uuid(tctx, NULL, - NT_STATUS_RPC_NOT_RPC_ERROR, + NT_STATUS_RPC_UNSUPPORTED_TYPE, DCERPC_NCA_S_UNSUPPORTED_TYPE), "failed to test NULL object uuid"); object_uuid = GUID_zero(); torture_assert(tctx, test_object_one_uuid(tctx, &object_uuid, - NT_STATUS_RPC_NOT_RPC_ERROR, + NT_STATUS_RPC_UNSUPPORTED_TYPE, DCERPC_NCA_S_UNSUPPORTED_TYPE), "failed to test zeroed object uuid"); object_uuid = GUID_random(); torture_assert(tctx, test_object_one_uuid(tctx, &object_uuid, - NT_STATUS_RPC_NOT_RPC_ERROR, + NT_STATUS_RPC_UNSUPPORTED_TYPE, DCERPC_NCA_S_UNSUPPORTED_TYPE), "failed to test random object uuid"); @@ -911,13 +911,13 @@ static bool test_object_uuid(struct torture_context *tctx, torture_assert(tctx, test_object_one_uuid(tctx, &ndr_table_spoolss.syntax_id.uuid, - NT_STATUS_RPC_NOT_RPC_ERROR, + NT_STATUS_RPC_UNSUPPORTED_TYPE, DCERPC_NCA_S_UNSUPPORTED_TYPE), "failed to test spoolss interface uuid"); torture_assert(tctx, test_object_one_uuid(tctx, &ndr_table_iremotewinspool.syntax_id.uuid, - NT_STATUS_RPC_NOT_RPC_ERROR, + NT_STATUS_RPC_UNSUPPORTED_TYPE, DCERPC_NCA_S_UNSUPPORTED_TYPE), "failed to test iremotewinspool interface uuid"); -- 2.49.0 From 83b61cea99be050fa89f17861a05293d13a78071 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 18 Sep 2024 22:42:17 +0200 Subject: [PATCH 03/80] s4:torture/rpc: avoid checking p->last_fault_code in iremotewinspool* Now that we check for NT_STATUS_RPC_UNSUPPORTED_TYPE, there's no need to check for DCERPC_NCA_S_UNSUPPORTED_TYPE. Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit b0be3c8af8240cfb7bc0b63fb7bf73f0f1655e4e) --- source4/torture/rpc/iremotewinspool.c | 22 +++++++------------- source4/torture/rpc/iremotewinspool_common.c | 4 ---- source4/torture/rpc/iremotewinspool_common.h | 1 - 3 files changed, 7 insertions(+), 20 deletions(-) diff --git a/source4/torture/rpc/iremotewinspool.c b/source4/torture/rpc/iremotewinspool.c index d43f4ff36a4c..537af938b5a1 100644 --- a/source4/torture/rpc/iremotewinspool.c +++ b/source4/torture/rpc/iremotewinspool.c @@ -824,8 +824,7 @@ static bool test_OpenPrinter(struct torture_context *tctx, static bool test_object_one_uuid(struct torture_context *tctx, const struct GUID *object_uuid, - NTSTATUS expected_status, - uint32_t expected_fault_code) + NTSTATUS expected_status) { const char *printer_name; struct spoolss_UserLevel1 client_info; @@ -865,7 +864,6 @@ static bool test_object_one_uuid(struct torture_context *tctx, client_info, expected_status, WERR_OK, - expected_fault_code, &server_handle), "failed to open printserver"); if (NT_STATUS_IS_OK(expected_status)) { @@ -884,41 +882,35 @@ static bool test_object_uuid(struct torture_context *tctx, torture_assert(tctx, test_object_one_uuid(tctx, NULL, - NT_STATUS_RPC_UNSUPPORTED_TYPE, - DCERPC_NCA_S_UNSUPPORTED_TYPE), + NT_STATUS_RPC_UNSUPPORTED_TYPE), "failed to test NULL object uuid"); object_uuid = GUID_zero(); torture_assert(tctx, test_object_one_uuid(tctx, &object_uuid, - NT_STATUS_RPC_UNSUPPORTED_TYPE, - DCERPC_NCA_S_UNSUPPORTED_TYPE), + NT_STATUS_RPC_UNSUPPORTED_TYPE), "failed to test zeroed object uuid"); object_uuid = GUID_random(); torture_assert(tctx, test_object_one_uuid(tctx, &object_uuid, - NT_STATUS_RPC_UNSUPPORTED_TYPE, - DCERPC_NCA_S_UNSUPPORTED_TYPE), + NT_STATUS_RPC_UNSUPPORTED_TYPE), "failed to test random object uuid"); GUID_from_string(IREMOTEWINSPOOL_OBJECT_GUID, &object_uuid); torture_assert(tctx, test_object_one_uuid(tctx, &object_uuid, - NT_STATUS_OK, - 0), + NT_STATUS_OK), "failed to test IREMOTEWINSPOOL_OBJECT_GUID"); torture_assert(tctx, test_object_one_uuid(tctx, &ndr_table_spoolss.syntax_id.uuid, - NT_STATUS_RPC_UNSUPPORTED_TYPE, - DCERPC_NCA_S_UNSUPPORTED_TYPE), + NT_STATUS_RPC_UNSUPPORTED_TYPE), "failed to test spoolss interface uuid"); torture_assert(tctx, test_object_one_uuid(tctx, &ndr_table_iremotewinspool.syntax_id.uuid, - NT_STATUS_RPC_UNSUPPORTED_TYPE, - DCERPC_NCA_S_UNSUPPORTED_TYPE), + NT_STATUS_RPC_UNSUPPORTED_TYPE), "failed to test iremotewinspool interface uuid"); return true; diff --git a/source4/torture/rpc/iremotewinspool_common.c b/source4/torture/rpc/iremotewinspool_common.c index d4dd19ac3edb..9a75af4ff3ff 100644 --- a/source4/torture/rpc/iremotewinspool_common.c +++ b/source4/torture/rpc/iremotewinspool_common.c @@ -59,7 +59,6 @@ bool test_AsyncOpenPrinter_byprinter_expect(struct torture_context *tctx, struct spoolss_UserLevel1 cinfo, NTSTATUS expected_status, WERROR expected_result, - uint32_t expected_fault_code, struct policy_handle *handle) { struct dcerpc_binding_handle *b = p->binding_handle; @@ -86,8 +85,6 @@ bool test_AsyncOpenPrinter_byprinter_expect(struct torture_context *tctx, torture_assert_ntstatus_equal(tctx, status, expected_status, "AsyncOpenPrinter failed"); torture_assert_werr_equal(tctx, r.out.result, expected_result, "AsyncOpenPrinter failed"); - torture_assert_u32_equal(tctx, p->last_fault_code, expected_fault_code, - "unexpected DCERPC fault code"); return ok; } @@ -107,7 +104,6 @@ bool test_AsyncOpenPrinter_byprinter(struct torture_context *tctx, cinfo, NT_STATUS_OK, WERR_OK, - 0, handle); } diff --git a/source4/torture/rpc/iremotewinspool_common.h b/source4/torture/rpc/iremotewinspool_common.h index 5887416d014d..4a94653fe4bf 100644 --- a/source4/torture/rpc/iremotewinspool_common.h +++ b/source4/torture/rpc/iremotewinspool_common.h @@ -82,7 +82,6 @@ bool test_AsyncOpenPrinter_byprinter_expect(struct torture_context *tctx, struct spoolss_UserLevel1 cinfo, NTSTATUS exected_status, WERROR exected_result, - uint32_t expected_fault_code, struct policy_handle *handle); bool test_get_environment(struct torture_context *tctx, struct dcerpc_binding_handle *b, -- 2.49.0 From b0e9eae6f7ce9e7dd37df083c0010d96748ff8bb Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 18 Sep 2024 04:31:04 +0200 Subject: [PATCH 04/80] s4:torture/rpc: remove useless usage of DCERPC_SIGN, DCERPC_SEAL We already used DCERPC_AUTH_LEVEL_PRIVACY for the connection. Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 136ee756fe3a41f863c2d1d538ad029bfe54e1d1) --- source4/torture/rpc/samba3rpc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/source4/torture/rpc/samba3rpc.c b/source4/torture/rpc/samba3rpc.c index 0ce948895bc7..0e96a3088810 100644 --- a/source4/torture/rpc/samba3rpc.c +++ b/source4/torture/rpc/samba3rpc.c @@ -1153,7 +1153,6 @@ static bool schan(struct torture_context *tctx, "\\netlogon", &ndr_table_netlogon, &net_pipe); torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "pipe_bind_smb_auth failed"); - net_pipe->conn->flags |= (DCERPC_SIGN | DCERPC_SEAL); #else status = pipe_bind_smb(tctx, mem_ctx, cli->tree, "\\netlogon", &ndr_table_netlogon, &net_pipe); -- 2.49.0 From 0c6e9c71c98f694961bbb524d9a00e857ce32070 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 18 Sep 2024 06:27:30 +0200 Subject: [PATCH 05/80] s4:torture/rpc: avoid using DCERPC_NDR_REF_ALLOC in fsrvp.c Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 061267e0e4de5c6379205a09376ec21374a87a3d) --- source4/torture/rpc/fsrvp.c | 72 +++++++++++++++++++++++-------------- 1 file changed, 45 insertions(+), 27 deletions(-) diff --git a/source4/torture/rpc/fsrvp.c b/source4/torture/rpc/fsrvp.c index 1b389477a8c5..c859bf4bbffb 100644 --- a/source4/torture/rpc/fsrvp.c +++ b/source4/torture/rpc/fsrvp.c @@ -52,6 +52,8 @@ static bool test_fsrvp_is_path_supported(struct torture_context *tctx, struct dcerpc_pipe *p) { + uint32_t SupportedByThisProvider; + const char *OwnerMachineName = NULL; struct fss_IsPathSupported r; struct dcerpc_binding_handle *b = p->binding_handle; NTSTATUS status; @@ -60,6 +62,8 @@ static bool test_fsrvp_is_path_supported(struct torture_context *tctx, r.in.ShareName = talloc_asprintf(tctx,"\\\\%s\\%s\\", dcerpc_server_name(p), FSHARE); + r.out.SupportedByThisProvider = &SupportedByThisProvider; + r.out.OwnerMachineName = &OwnerMachineName; status = dcerpc_fss_IsPathSupported_r(b, tctx, &r); torture_assert_ntstatus_ok(tctx, status, "IsPathSupported failed"); @@ -76,11 +80,15 @@ static bool test_fsrvp_is_path_supported(struct torture_context *tctx, static bool test_fsrvp_get_version(struct torture_context *tctx, struct dcerpc_pipe *p) { + uint32_t MinVersion = 0; + uint32_t MaxVersion = 0; struct fss_GetSupportedVersion r; struct dcerpc_binding_handle *b = p->binding_handle; NTSTATUS status; ZERO_STRUCT(r); + r.out.MinVersion = &MinVersion; + r.out.MaxVersion = &MaxVersion; status = dcerpc_fss_GetSupportedVersion_r(b, tctx, &r); torture_assert_ntstatus_ok(tctx, status, "GetSupportedVersion failed"); @@ -123,15 +131,23 @@ static bool test_fsrvp_sc_create(struct torture_context *tctx, enum test_fsrvp_inject inject, struct fssagent_share_mapping_1 **sc_map) { + uint32_t SupportedByThisProvider = 0; + const char *OwnerMachineName = NULL; struct fss_IsPathSupported r_pathsupport_get; + uint32_t MinVersion = 0; + uint32_t MaxVersion = 0; struct fss_GetSupportedVersion r_version_get; struct fss_SetContext r_context_set; + struct GUID pShadowCopySetId = GUID_zero(); struct fss_StartShadowCopySet r_scset_start; + struct GUID pShadowCopyId1 = GUID_zero(); struct fss_AddToShadowCopySet r_scset_add1; + struct GUID pShadowCopyId2 = GUID_zero(); struct fss_AddToShadowCopySet r_scset_add2; struct fss_PrepareShadowCopySet r_scset_prep; struct fss_CommitShadowCopySet r_scset_commit; struct fss_ExposeShadowCopySet r_scset_expose; + union fssagent_share_mapping ShareMapping = { .ShareMapping1 = NULL, }; struct fss_GetShareMapping r_sharemap_get; struct dcerpc_binding_handle *b = p->binding_handle; NTSTATUS status; @@ -148,6 +164,8 @@ static bool test_fsrvp_sc_create(struct torture_context *tctx, ZERO_STRUCT(r_pathsupport_get); r_pathsupport_get.in.ShareName = share; + r_pathsupport_get.out.SupportedByThisProvider = &SupportedByThisProvider; + r_pathsupport_get.out.OwnerMachineName = &OwnerMachineName; status = dcerpc_fss_IsPathSupported_r(b, tmp_ctx, &r_pathsupport_get); torture_assert_ntstatus_ok(tctx, status, "IsPathSupported failed"); @@ -157,6 +175,8 @@ static bool test_fsrvp_sc_create(struct torture_context *tctx, "path not supported"); ZERO_STRUCT(r_version_get); + r_version_get.out.MinVersion = &MinVersion; + r_version_get.out.MaxVersion = &MaxVersion; status = dcerpc_fss_GetSupportedVersion_r(b, tmp_ctx, &r_version_get); torture_assert_ntstatus_ok(tctx, status, "GetSupportedVersion failed"); @@ -179,6 +199,7 @@ static bool test_fsrvp_sc_create(struct torture_context *tctx, ZERO_STRUCT(r_scset_start); r_scset_start.in.ClientShadowCopySetId = GUID_random(); + r_scset_start.out.pShadowCopySetId = &pShadowCopySetId; status = dcerpc_fss_StartShadowCopySet_r(b, tmp_ctx, &r_scset_start); torture_assert_ntstatus_ok(tctx, status, "StartShadowCopySet failed"); @@ -205,6 +226,7 @@ static bool test_fsrvp_sc_create(struct torture_context *tctx, r_scset_add1.in.ClientShadowCopyId = GUID_random(); r_scset_add1.in.ShadowCopySetId = *r_scset_start.out.pShadowCopySetId; r_scset_add1.in.ShareName = share; + r_scset_add1.out.pShadowCopyId = &pShadowCopyId1; status = dcerpc_fss_AddToShadowCopySet_r(b, tmp_ctx, &r_scset_add1); torture_assert_ntstatus_ok(tctx, status, "AddToShadowCopySet failed"); @@ -226,6 +248,7 @@ static bool test_fsrvp_sc_create(struct torture_context *tctx, r_scset_add2.in.ClientShadowCopyId = GUID_random(); r_scset_add2.in.ShadowCopySetId = *r_scset_start.out.pShadowCopySetId; r_scset_add2.in.ShareName = share; + r_scset_add2.out.pShadowCopyId = &pShadowCopyId2; status = dcerpc_fss_AddToShadowCopySet_r(b, tmp_ctx, &r_scset_add2); torture_assert_ntstatus_ok(tctx, status, "AddToShadowCopySet failed"); @@ -323,6 +346,7 @@ static bool test_fsrvp_sc_create(struct torture_context *tctx, r_sharemap_get.in.ShadowCopySetId = *r_scset_start.out.pShadowCopySetId; r_sharemap_get.in.ShareName = r_scset_add1.in.ShareName; r_sharemap_get.in.Level = 1; + r_sharemap_get.out.ShareMapping = &ShareMapping; status = dcerpc_fss_GetShareMapping_r(b, tmp_ctx, &r_sharemap_get); torture_assert_ntstatus_ok(tctx, status, "GetShareMapping failed"); torture_assert_int_equal(tctx, r_sharemap_get.out.result, 0, @@ -399,17 +423,25 @@ static bool test_fsrvp_sc_set_abort(struct torture_context *tctx, char *share_unc = talloc_asprintf(tctx, "\\\\%s\\%s\\", dcerpc_server_name(p), FSHARE); struct dcerpc_binding_handle *b = p->binding_handle; + uint32_t SupportedByThisProvider = 0; + const char *OwnerMachineName = NULL; struct fss_IsPathSupported r_pathsupport_get; + uint32_t MinVersion = 0; + uint32_t MaxVersion = 0; struct fss_GetSupportedVersion r_version_get; struct fss_SetContext r_context_set; + struct GUID pShadowCopySetId = GUID_zero(); struct fss_StartShadowCopySet r_scset_start; struct fss_AbortShadowCopySet r_scset_abort; + struct GUID pShadowCopyId = GUID_zero(); struct fss_AddToShadowCopySet r_scset_add; NTSTATUS status; TALLOC_CTX *tmp_ctx = talloc_new(tctx); ZERO_STRUCT(r_pathsupport_get); r_pathsupport_get.in.ShareName = share_unc; + r_pathsupport_get.out.SupportedByThisProvider = &SupportedByThisProvider; + r_pathsupport_get.out.OwnerMachineName = &OwnerMachineName; status = dcerpc_fss_IsPathSupported_r(b, tmp_ctx, &r_pathsupport_get); torture_assert_ntstatus_ok(tctx, status, "IsPathSupported failed"); @@ -417,6 +449,8 @@ static bool test_fsrvp_sc_set_abort(struct torture_context *tctx, "path not supported"); ZERO_STRUCT(r_version_get); + r_version_get.out.MinVersion = &MinVersion; + r_version_get.out.MaxVersion = &MaxVersion; status = dcerpc_fss_GetSupportedVersion_r(b, tmp_ctx, &r_version_get); torture_assert_ntstatus_ok(tctx, status, "GetSupportedVersion failed"); @@ -428,6 +462,7 @@ static bool test_fsrvp_sc_set_abort(struct torture_context *tctx, ZERO_STRUCT(r_scset_start); r_scset_start.in.ClientShadowCopySetId = GUID_random(); + r_scset_start.out.pShadowCopySetId = &pShadowCopySetId; status = dcerpc_fss_StartShadowCopySet_r(b, tmp_ctx, &r_scset_start); torture_assert_ntstatus_ok(tctx, status, "StartShadowCopySet failed"); @@ -442,6 +477,7 @@ static bool test_fsrvp_sc_set_abort(struct torture_context *tctx, r_scset_add.in.ClientShadowCopyId = GUID_random(); r_scset_add.in.ShadowCopySetId = *r_scset_start.out.pShadowCopySetId; r_scset_add.in.ShareName = share_unc; + r_scset_add.out.pShadowCopyId = & pShadowCopyId; status = dcerpc_fss_AddToShadowCopySet_r(b, tmp_ctx, &r_scset_add); torture_assert_ntstatus_ok(tctx, status, "AddToShadowCopySet failed " "following abort"); @@ -730,11 +766,15 @@ static bool test_fsrvp_share_sd(struct torture_context *tctx, { NTSTATUS status; struct dcerpc_pipe *srvsvc_p; + union srvsvc_NetShareInfo q_info = { .info0 = NULL, }; struct srvsvc_NetShareGetInfo q; + uint32_t s_parm_error = 0; struct srvsvc_NetShareSetInfo s; struct srvsvc_NetShareInfo502 *info502; struct fssagent_share_mapping_1 *sc_map; struct fss_ExposeShadowCopySet r_scset_expose; + union fssagent_share_mapping r_sharemap_get_ShareMapping = + { .ShareMapping1 = NULL, }; struct fss_GetShareMapping r_sharemap_get; struct security_descriptor *sd_old; struct security_descriptor *sd_base; @@ -748,13 +788,11 @@ static bool test_fsrvp_share_sd(struct torture_context *tctx, q.in.server_unc = dcerpc_server_name(p); q.in.share_name = FSHARE; q.in.level = 502; + q.out.info = &q_info; status = torture_rpc_connection(tctx, &srvsvc_p, &ndr_table_srvsvc); torture_assert_ntstatus_ok(tctx, status, "srvsvc rpc conn failed"); - /* ensure srvsvc out pointers are allocated during unmarshalling */ - srvsvc_p->conn->flags |= DCERPC_NDR_REF_ALLOC; - /* obtain the existing DACL for the base share */ status = dcerpc_srvsvc_NetShareGetInfo_r(srvsvc_p->binding_handle, tctx, &q); @@ -798,6 +836,7 @@ static bool test_fsrvp_share_sd(struct torture_context *tctx, s.in.share_name = FSHARE; s.in.level = 502; s.in.info = q.out.info; + s.out.parm_error = &s_parm_error; status = dcerpc_srvsvc_NetShareSetInfo_r(srvsvc_p->binding_handle, tctx, &s); @@ -832,6 +871,7 @@ static bool test_fsrvp_share_sd(struct torture_context *tctx, s.in.share_name = FSHARE; s.in.level = 502; s.in.info = q.out.info; + s.out.parm_error = &s_parm_error; status = dcerpc_srvsvc_NetShareSetInfo_r(srvsvc_p->binding_handle, tctx, &s); @@ -854,6 +894,7 @@ static bool test_fsrvp_share_sd(struct torture_context *tctx, r_sharemap_get.in.ShadowCopySetId = sc_map->ShadowCopySetId; r_sharemap_get.in.ShareName = share_unc; r_sharemap_get.in.Level = 1; + r_sharemap_get.out.ShareMapping = &r_sharemap_get_ShareMapping; status = dcerpc_fss_GetShareMapping_r(p->binding_handle, tctx, &r_sharemap_get); torture_assert_ntstatus_ok(tctx, status, "GetShareMapping failed"); @@ -875,6 +916,7 @@ static bool test_fsrvp_share_sd(struct torture_context *tctx, q.in.server_unc = dcerpc_server_name(p); q.in.share_name = sc_map->ShadowCopyShareName; q.in.level = 502; + q.out.info = &q_info; status = dcerpc_srvsvc_NetShareGetInfo_r(srvsvc_p->binding_handle, tctx, &q); torture_assert_ntstatus_ok(tctx, status, "NetShareGetInfo failed"); @@ -913,28 +955,6 @@ static bool test_fsrvp_share_sd(struct torture_context *tctx, return true; } -static bool fsrvp_rpc_setup(struct torture_context *tctx, void **data) -{ - NTSTATUS status; - struct torture_rpc_tcase *tcase = talloc_get_type( - tctx->active_tcase, struct torture_rpc_tcase); - struct torture_rpc_tcase_data *tcase_data; - - *data = tcase_data = talloc_zero(tctx, struct torture_rpc_tcase_data); - tcase_data->credentials = samba_cmdline_get_creds(); - - status = torture_rpc_connection(tctx, - &(tcase_data->pipe), - tcase->table); - - torture_assert_ntstatus_ok(tctx, status, "Error connecting to server"); - - /* XXX required, otherwise ndr out ptrs are not allocated */ - tcase_data->pipe->conn->flags |= DCERPC_NDR_REF_ALLOC; - - return true; -} - /* testing of FSRVP (FSS agent) */ @@ -945,8 +965,6 @@ struct torture_suite *torture_rpc_fsrvp(TALLOC_CTX *mem_ctx) struct torture_rpc_tcase *tcase = torture_suite_add_rpc_iface_tcase(suite, "fsrvp", &ndr_table_FileServerVssAgent); - /* override torture_rpc_setup() to set DCERPC_NDR_REF_ALLOC */ - tcase->tcase.setup = fsrvp_rpc_setup; torture_rpc_tcase_add_test(tcase, "share_sd", test_fsrvp_share_sd); -- 2.49.0 From b4d009084ded61f74281e51d8b08fb062493ece1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 14 Sep 2024 09:55:20 +0200 Subject: [PATCH 06/80] librpc/rpc: add dcerpc_binding_handle_transport_{encrypted,session_key}() Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 3dc3f9cf1b6fc47baea329863e31ff140cf89550) --- librpc/rpc/binding_handle.c | 21 +++++++++++++++++++++ librpc/rpc/rpc_common.h | 12 ++++++++++++ 2 files changed, 33 insertions(+) diff --git a/librpc/rpc/binding_handle.c b/librpc/rpc/binding_handle.c index 41675e103607..f165b47451d6 100644 --- a/librpc/rpc/binding_handle.c +++ b/librpc/rpc/binding_handle.c @@ -98,6 +98,27 @@ uint32_t dcerpc_binding_handle_set_timeout(struct dcerpc_binding_handle *h, return h->ops->set_timeout(h, timeout); } +bool dcerpc_binding_handle_transport_encrypted(struct dcerpc_binding_handle *h) +{ + if (h->ops->transport_encrypted == NULL) { + return false; + } + + return h->ops->transport_encrypted(h); +} + +NTSTATUS dcerpc_binding_handle_transport_session_key( + struct dcerpc_binding_handle *h, + TALLOC_CTX *mem_ctx, + DATA_BLOB *session_key) +{ + if (h->ops->transport_session_key == NULL) { + return NT_STATUS_NO_USER_SESSION_KEY; + } + + return h->ops->transport_session_key(h, mem_ctx, session_key); +} + void dcerpc_binding_handle_auth_info(struct dcerpc_binding_handle *h, enum dcerpc_AuthType *auth_type, enum dcerpc_AuthLevel *auth_level) diff --git a/librpc/rpc/rpc_common.h b/librpc/rpc/rpc_common.h index 76557101dcda..7faeb5f00b3d 100644 --- a/librpc/rpc/rpc_common.h +++ b/librpc/rpc/rpc_common.h @@ -176,6 +176,11 @@ struct dcerpc_binding_handle_ops { uint32_t (*set_timeout)(struct dcerpc_binding_handle *h, uint32_t timeout); + bool (*transport_encrypted)(struct dcerpc_binding_handle *h); + NTSTATUS (*transport_session_key)(struct dcerpc_binding_handle *h, + TALLOC_CTX *mem_ctx, + DATA_BLOB *session_key); + void (*auth_info)(struct dcerpc_binding_handle *h, enum dcerpc_AuthType *auth_type, enum dcerpc_AuthLevel *auth_level); @@ -250,6 +255,13 @@ bool dcerpc_binding_handle_is_connected(struct dcerpc_binding_handle *h); uint32_t dcerpc_binding_handle_set_timeout(struct dcerpc_binding_handle *h, uint32_t timeout); +bool dcerpc_binding_handle_transport_encrypted(struct dcerpc_binding_handle *h); + +NTSTATUS dcerpc_binding_handle_transport_session_key( + struct dcerpc_binding_handle *h, + TALLOC_CTX *mem_ctx, + DATA_BLOB *session_key); + void dcerpc_binding_handle_auth_info(struct dcerpc_binding_handle *h, enum dcerpc_AuthType *auth_type, enum dcerpc_AuthLevel *auth_level); -- 2.49.0 From ef9a3b4c598ad1b13153ae58932bf0997bdf8379 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 14 Sep 2024 09:55:20 +0200 Subject: [PATCH 07/80] s4:librpc/rpc: add dcerpc_bh_transport_{encrypted,session_key}() Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 9b50ab08c16c197291835c8e66cd064ca0bb6579) --- source4/librpc/rpc/dcerpc.c | 57 +++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index 58f00b7f9d2c..015b71b2da7a 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -213,6 +213,61 @@ static uint32_t dcerpc_bh_set_timeout(struct dcerpc_binding_handle *h, return old; } +static bool dcerpc_bh_transport_encrypted(struct dcerpc_binding_handle *h) +{ + struct dcerpc_bh_state *hs = dcerpc_binding_handle_data(h, + struct dcerpc_bh_state); + + if (hs->p == NULL) { + return false; + } + + if (hs->p->conn == NULL) { + return false; + } + + return hs->p->conn->transport.encrypted; +} + +static NTSTATUS dcerpc_bh_transport_session_key(struct dcerpc_binding_handle *h, + TALLOC_CTX *mem_ctx, + DATA_BLOB *session_key) +{ + struct dcerpc_bh_state *hs = dcerpc_binding_handle_data(h, + struct dcerpc_bh_state); + struct dcecli_security *sec = NULL; + DATA_BLOB sk = { .length = 0, }; + NTSTATUS status; + + if (hs->p == NULL) { + return NT_STATUS_NO_USER_SESSION_KEY; + } + + if (hs->p->conn == NULL) { + return NT_STATUS_NO_USER_SESSION_KEY; + } + + sec = &hs->p->conn->security_state; + + if (sec->session_key == NULL) { + return NT_STATUS_NO_USER_SESSION_KEY; + } + + status = sec->session_key(hs->p->conn, &sk); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + sk.length = MIN(sk.length, 16); + + *session_key = data_blob_dup_talloc(mem_ctx, sk); + if (session_key->length != sk.length) { + return NT_STATUS_NO_MEMORY; + } + talloc_keep_secret(session_key->data); + return NT_STATUS_OK; +} + static void dcerpc_bh_auth_info(struct dcerpc_binding_handle *h, enum dcerpc_AuthType *auth_type, enum dcerpc_AuthLevel *auth_level) @@ -601,6 +656,8 @@ static const struct dcerpc_binding_handle_ops dcerpc_bh_ops = { .name = "dcerpc", .is_connected = dcerpc_bh_is_connected, .set_timeout = dcerpc_bh_set_timeout, + .transport_encrypted = dcerpc_bh_transport_encrypted, + .transport_session_key = dcerpc_bh_transport_session_key, .auth_info = dcerpc_bh_auth_info, .raw_call_send = dcerpc_bh_raw_call_send, .raw_call_recv = dcerpc_bh_raw_call_recv, -- 2.49.0 From 40b6fac7531c0f05e9ef81ba7f7e5d264590d564 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 14 Sep 2024 09:55:20 +0200 Subject: [PATCH 08/80] s3:rpc_client: add rpccli_bh_transport_session_key() Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 5bb35cc7cca101390e58256e9b38e31113211e4f) --- source3/rpc_client/cli_pipe.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index cf551f6f548f..5f7cc33e20cc 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2162,6 +2162,40 @@ static uint32_t rpccli_bh_set_timeout(struct dcerpc_binding_handle *h, return old; } +static NTSTATUS rpccli_bh_transport_session_key(struct dcerpc_binding_handle *h, + TALLOC_CTX *mem_ctx, + DATA_BLOB *session_key) +{ + struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h, + struct rpccli_bh_state); + struct pipe_auth_data *auth = NULL; + DATA_BLOB sk = { .length = 0, }; + + if (hs->rpc_cli == NULL) { + return NT_STATUS_NO_USER_SESSION_KEY; + } + + if (hs->rpc_cli->auth == NULL) { + return NT_STATUS_NO_USER_SESSION_KEY; + } + + auth = hs->rpc_cli->auth; + + if (auth->transport_session_key.length == 0) { + return NT_STATUS_NO_USER_SESSION_KEY; + } + + sk = auth->transport_session_key; + sk.length = MIN(sk.length, 16); + + *session_key = data_blob_dup_talloc(mem_ctx, sk); + if (session_key->length != sk.length) { + return NT_STATUS_NO_MEMORY; + } + talloc_keep_secret(session_key->data); + return NT_STATUS_OK; +} + static void rpccli_bh_auth_info(struct dcerpc_binding_handle *h, enum dcerpc_AuthType *auth_type, enum dcerpc_AuthLevel *auth_level) @@ -2352,6 +2386,7 @@ static const struct dcerpc_binding_handle_ops rpccli_bh_ops = { .name = "rpccli", .is_connected = rpccli_bh_is_connected, .set_timeout = rpccli_bh_set_timeout, + .transport_session_key = rpccli_bh_transport_session_key, .auth_info = rpccli_bh_auth_info, .raw_call_send = rpccli_bh_raw_call_send, .raw_call_recv = rpccli_bh_raw_call_recv, -- 2.49.0 From 1329ef6ce9fb11717b01e04be19717c3cee29168 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 14 Sep 2024 13:35:47 +0200 Subject: [PATCH 09/80] s4:pyrpc: let py_iface_transport_encrypted() use dcerpc_binding_handle_transport_encrypted() Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 9567d753ac0fcffb50f3710f3329334afb7595cd) --- source4/librpc/rpc/pyrpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/librpc/rpc/pyrpc.c b/source4/librpc/rpc/pyrpc.c index 3f1a8679d3e9..28ffdc71d653 100644 --- a/source4/librpc/rpc/pyrpc.c +++ b/source4/librpc/rpc/pyrpc.c @@ -296,7 +296,7 @@ static PyObject *py_iface_transport_encrypted(PyObject *self) { dcerpc_InterfaceObject *iface = (dcerpc_InterfaceObject *)self; - if (dcerpc_transport_encrypted(iface->pipe)) { + if (dcerpc_binding_handle_transport_encrypted(iface->binding_handle)) { Py_RETURN_TRUE; } -- 2.49.0 From ce21301d739d8ad0038ce5312bc6a50c299d4da5 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 14 Sep 2024 13:37:34 +0200 Subject: [PATCH 10/80] s4:librpc/rpc: remove unused dcerpc_transport_encrypted() Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 3cc6ddeb589f0357c436d1caa70130f053ddcba0) --- source4/librpc/rpc/dcerpc.h | 1 - source4/librpc/rpc/dcerpc_util.c | 13 ------------- 2 files changed, 14 deletions(-) diff --git a/source4/librpc/rpc/dcerpc.h b/source4/librpc/rpc/dcerpc.h index a9cfc32c462d..857c67ddc8ea 100644 --- a/source4/librpc/rpc/dcerpc.h +++ b/source4/librpc/rpc/dcerpc.h @@ -182,7 +182,6 @@ NTSTATUS dcerpc_bind_auth_none(struct dcerpc_pipe *p, const struct ndr_interface_table *table); NTSTATUS dcerpc_fetch_session_key(struct dcerpc_pipe *p, DATA_BLOB *session_key); -bool dcerpc_transport_encrypted(struct dcerpc_pipe *p); struct composite_context; NTSTATUS dcerpc_secondary_connection_recv(struct composite_context *c, struct dcerpc_pipe **p2); diff --git a/source4/librpc/rpc/dcerpc_util.c b/source4/librpc/rpc/dcerpc_util.c index 0ebc52ab3ab5..e1178cffad21 100644 --- a/source4/librpc/rpc/dcerpc_util.c +++ b/source4/librpc/rpc/dcerpc_util.c @@ -743,19 +743,6 @@ _PUBLIC_ NTSTATUS dcerpc_fetch_session_key(struct dcerpc_pipe *p, return NT_STATUS_OK; } -_PUBLIC_ bool dcerpc_transport_encrypted(struct dcerpc_pipe *p) -{ - if (p == NULL) { - return false; - } - - if (p->conn == NULL) { - return false; - } - - return p->conn->transport.encrypted; -} - /* create a secondary context from a primary connection -- 2.49.0 From 40b8e0b4149c99d61a4953422c353198953423e7 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 14 Sep 2024 14:16:42 +0200 Subject: [PATCH 11/80] s4:libnet: add struct dcerpc_binding_handle helper variables in libnet_passwd.c Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 2d1c182bf512666606b8192b2021d571a47d2f58) --- source4/libnet/libnet_passwd.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/source4/libnet/libnet_passwd.c b/source4/libnet/libnet_passwd.c index e24ebe2757e4..10f618a744fe 100644 --- a/source4/libnet/libnet_passwd.c +++ b/source4/libnet/libnet_passwd.c @@ -500,6 +500,8 @@ NTSTATUS libnet_ChangePassword(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, static NTSTATUS libnet_SetPassword_samr_handle_26(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_SetPassword *r) { + struct dcerpc_binding_handle *b = + r->samr_handle.in.dcerpc_pipe->binding_handle; NTSTATUS status; struct samr_SetUserInfo2 sui; union samr_UserInfo u_info; @@ -537,7 +539,7 @@ static NTSTATUS libnet_SetPassword_samr_handle_26(struct libnet_context *ctx, TA sui.in.level = 26; /* 7. try samr_SetUserInfo2 level 26 to set the password */ - status = dcerpc_samr_SetUserInfo2_r(r->samr_handle.in.dcerpc_pipe->binding_handle, mem_ctx, &sui); + status = dcerpc_samr_SetUserInfo2_r(b, mem_ctx, &sui); /* check result of samr_SetUserInfo2 level 26 */ if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(sui.out.result)) { status = sui.out.result; @@ -554,6 +556,8 @@ static NTSTATUS libnet_SetPassword_samr_handle_26(struct libnet_context *ctx, TA static NTSTATUS libnet_SetPassword_samr_handle_25(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_SetPassword *r) { + struct dcerpc_binding_handle *b = + r->samr_handle.in.dcerpc_pipe->binding_handle; NTSTATUS status; struct samr_SetUserInfo2 sui; union samr_UserInfo u_info; @@ -593,7 +597,7 @@ static NTSTATUS libnet_SetPassword_samr_handle_25(struct libnet_context *ctx, TA sui.in.level = 25; /* 8. try samr_SetUserInfo2 level 25 to set the password */ - status = dcerpc_samr_SetUserInfo2_r(r->samr_handle.in.dcerpc_pipe->binding_handle, mem_ctx, &sui); + status = dcerpc_samr_SetUserInfo2_r(b, mem_ctx, &sui); if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(sui.out.result)) { status = sui.out.result; } @@ -609,6 +613,8 @@ static NTSTATUS libnet_SetPassword_samr_handle_25(struct libnet_context *ctx, TA static NTSTATUS libnet_SetPassword_samr_handle_24(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_SetPassword *r) { + struct dcerpc_binding_handle *b = + r->samr_handle.in.dcerpc_pipe->binding_handle; NTSTATUS status; struct samr_SetUserInfo2 sui; union samr_UserInfo u_info; @@ -662,7 +668,7 @@ static NTSTATUS libnet_SetPassword_samr_handle_24(struct libnet_context *ctx, TA sui.in.level = 24; /* 9. try samr_SetUserInfo2 level 24 to set the password */ - status = dcerpc_samr_SetUserInfo2_r(r->samr_handle.in.dcerpc_pipe->binding_handle, mem_ctx, &sui); + status = dcerpc_samr_SetUserInfo2_r(b, mem_ctx, &sui); if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(sui.out.result)) { status = sui.out.result; } @@ -680,6 +686,8 @@ static NTSTATUS libnet_SetPassword_samr_handle_24(struct libnet_context *ctx, TA static NTSTATUS libnet_SetPassword_samr_handle_23(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_SetPassword *r) { + struct dcerpc_binding_handle *b = + r->samr_handle.in.dcerpc_pipe->binding_handle; NTSTATUS status; struct samr_SetUserInfo2 sui; union samr_UserInfo u_info; @@ -736,7 +744,7 @@ static NTSTATUS libnet_SetPassword_samr_handle_23(struct libnet_context *ctx, TA sui.in.level = 23; /* 10. try samr_SetUserInfo2 level 23 to set the password */ - status = dcerpc_samr_SetUserInfo2_r(r->samr_handle.in.dcerpc_pipe->binding_handle, mem_ctx, &sui); + status = dcerpc_samr_SetUserInfo2_r(b, mem_ctx, &sui); if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(sui.out.result)) { status = sui.out.result; } @@ -753,6 +761,8 @@ static NTSTATUS libnet_SetPassword_samr_handle_23(struct libnet_context *ctx, TA static NTSTATUS libnet_SetPassword_samr_handle_18(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_SetPassword *r) { + struct dcerpc_binding_handle *b = + r->samr_handle.in.dcerpc_pipe->binding_handle; NTSTATUS status; struct samr_SetUserInfo2 sui; union samr_UserInfo u_info; @@ -795,7 +805,7 @@ static NTSTATUS libnet_SetPassword_samr_handle_18(struct libnet_context *ctx, TA sui.in.level = 18; /* 9. try samr_SetUserInfo2 level 18 to set the password */ - status = dcerpc_samr_SetUserInfo2_r(r->samr_handle.in.dcerpc_pipe->binding_handle, mem_ctx, &sui); + status = dcerpc_samr_SetUserInfo2_r(b, mem_ctx, &sui); if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(sui.out.result)) { status = sui.out.result; } -- 2.49.0 From 8b24a70dddc0b457076104185ca603a3f4dbd4ea Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 14 Sep 2024 14:16:42 +0200 Subject: [PATCH 12/80] s4:libnet: make use of dcerpc_binding_handle_transport_session_key() in libnet_passwd.c Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 93e8d58736e53d8d360ef2ee40f1619bd917c054) --- source4/libnet/libnet_passwd.c | 35 ++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/source4/libnet/libnet_passwd.c b/source4/libnet/libnet_passwd.c index 10f618a744fe..ae41752b3d64 100644 --- a/source4/libnet/libnet_passwd.c +++ b/source4/libnet/libnet_passwd.c @@ -515,10 +515,12 @@ static NTSTATUS libnet_SetPassword_samr_handle_26(struct libnet_context *ctx, TA ZERO_STRUCT(u_info); u_info.info26.password_expired = 0; - status = dcerpc_fetch_session_key(r->samr_handle.in.dcerpc_pipe, &session_key); + status = dcerpc_binding_handle_transport_session_key(b, + mem_ctx, + &session_key); if (!NT_STATUS_IS_OK(status)) { r->samr_handle.out.error_string = talloc_asprintf(mem_ctx, - "dcerpc_fetch_session_key failed: %s", + "transport_session_key failed: %s", nt_errstr(status)); return status; } @@ -526,6 +528,7 @@ static NTSTATUS libnet_SetPassword_samr_handle_26(struct libnet_context *ctx, TA status = encode_rc4_passwd_buffer(r->samr_handle.in.newpassword, &session_key, &u_info.info26.password); + data_blob_clear_free(&session_key); if (!NT_STATUS_IS_OK(status)) { r->samr_handle.out.error_string = talloc_asprintf(mem_ctx, @@ -572,10 +575,12 @@ static NTSTATUS libnet_SetPassword_samr_handle_25(struct libnet_context *ctx, TA u_info.info25.info = *r->samr_handle.in.info21; u_info.info25.info.fields_present |= SAMR_FIELD_NT_PASSWORD_PRESENT; - status = dcerpc_fetch_session_key(r->samr_handle.in.dcerpc_pipe, &session_key); + status = dcerpc_binding_handle_transport_session_key(b, + mem_ctx, + &session_key); if (!NT_STATUS_IS_OK(status)) { r->samr_handle.out.error_string = talloc_asprintf(mem_ctx, - "dcerpc_fetch_session_key failed: %s", + "transport_session_key failed: %s", nt_errstr(status)); return status; } @@ -583,6 +588,7 @@ static NTSTATUS libnet_SetPassword_samr_handle_25(struct libnet_context *ctx, TA status = encode_rc4_passwd_buffer(r->samr_handle.in.newpassword, &session_key, &u_info.info25.password); + data_blob_clear_free(&session_key); if (!NT_STATUS_IS_OK(status)) { r->samr_handle.out.error_string = talloc_asprintf(mem_ctx, @@ -632,10 +638,12 @@ static NTSTATUS libnet_SetPassword_samr_handle_24(struct libnet_context *ctx, TA encode_pw_buffer(u_info.info24.password.data, r->samr_handle.in.newpassword, STR_UNICODE); u_info.info24.password_expired = 0; - status = dcerpc_fetch_session_key(r->samr_handle.in.dcerpc_pipe, &session_key); + status = dcerpc_binding_handle_transport_session_key(b, + mem_ctx, + &session_key); if (!NT_STATUS_IS_OK(status)) { r->samr_handle.out.error_string = talloc_asprintf(mem_ctx, - "dcerpc_fetch_session_key failed: %s", + "transport_session_key failed: %s", nt_errstr(status)); return status; } @@ -649,6 +657,7 @@ static NTSTATUS libnet_SetPassword_samr_handle_24(struct libnet_context *ctx, TA GNUTLS_CIPHER_ARCFOUR_128, &enc_session_key, NULL); + data_blob_clear_free(&session_key); if (rc < 0) { status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID); goto out; @@ -706,11 +715,13 @@ static NTSTATUS libnet_SetPassword_samr_handle_23(struct libnet_context *ctx, TA u_info.info23.info.fields_present |= SAMR_FIELD_NT_PASSWORD_PRESENT; encode_pw_buffer(u_info.info23.password.data, r->samr_handle.in.newpassword, STR_UNICODE); - status = dcerpc_fetch_session_key(r->samr_handle.in.dcerpc_pipe, &session_key); + status = dcerpc_binding_handle_transport_session_key(b, + mem_ctx, + &session_key); if (!NT_STATUS_IS_OK(status)) { r->samr_handle.out.error_string = talloc_asprintf(mem_ctx, - "dcerpc_fetch_session_key failed: %s", + "transport_session_key failed: %s", nt_errstr(status)); return status; } @@ -724,6 +735,7 @@ static NTSTATUS libnet_SetPassword_samr_handle_23(struct libnet_context *ctx, TA GNUTLS_CIPHER_ARCFOUR_128, &_session_key, NULL); + data_blob_clear_free(&session_key); if (rc < 0) { status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID); goto out; @@ -785,16 +797,19 @@ static NTSTATUS libnet_SetPassword_samr_handle_18(struct libnet_context *ctx, TA u_info.info18.nt_pwd_active = 1; u_info.info18.password_expired = 0; - status = dcerpc_fetch_session_key(r->samr_handle.in.dcerpc_pipe, &session_key); + status = dcerpc_binding_handle_transport_session_key(b, + mem_ctx, + &session_key); if (!NT_STATUS_IS_OK(status)) { r->samr_handle.out.error_string = talloc_asprintf(mem_ctx, - "dcerpc_fetch_session_key failed: %s", + "transport_session_key failed: %s", nt_errstr(status)); return status; } rc = sess_crypt_blob(&ntpwd_out, &ntpwd_in, &session_key, SAMBA_GNUTLS_ENCRYPT); + data_blob_clear_free(&session_key); if (rc < 0) { status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID); goto out; -- 2.49.0 From 91de6611bd42bd4cf0509bccd5910d4cd297a42b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 14 Sep 2024 14:20:46 +0200 Subject: [PATCH 13/80] xss4:pyrpc: make use of dcerpc_binding_handle_transport_session_key() Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 57905603e066e2d1ca60268b1b1e8166868d60e5) --- source4/librpc/rpc/pyrpc.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/source4/librpc/rpc/pyrpc.c b/source4/librpc/rpc/pyrpc.c index 28ffdc71d653..b8e1ac0c35e0 100644 --- a/source4/librpc/rpc/pyrpc.c +++ b/source4/librpc/rpc/pyrpc.c @@ -130,12 +130,30 @@ static PyObject *py_iface_transfer_syntax(PyObject *obj, void *closure) static PyObject *py_iface_session_key(PyObject *obj, void *closure) { dcerpc_InterfaceObject *iface = (dcerpc_InterfaceObject *)obj; - DATA_BLOB session_key; + TALLOC_CTX *frame = talloc_stackframe(); + DATA_BLOB session_key = { .length = 0, }; + static PyObject *session_key_obj = NULL; + NTSTATUS status; - NTSTATUS status = dcerpc_fetch_session_key(iface->pipe, &session_key); - PyErr_NTSTATUS_IS_ERR_RAISE(status); + if (iface->binding_handle == NULL) { + PyErr_SetNTSTATUS(NT_STATUS_NO_USER_SESSION_KEY); + TALLOC_FREE(frame); + return NULL; + } - return PyBytes_FromStringAndSize((const char *)session_key.data, session_key.length); + status = dcerpc_binding_handle_transport_session_key(iface->binding_handle, + frame, + &session_key); + if (!NT_STATUS_IS_OK(status)) { + PyErr_SetNTSTATUS(status); + TALLOC_FREE(frame); + return NULL; + } + + session_key_obj = PyBytes_FromStringAndSize((const char *)session_key.data, + session_key.length); + TALLOC_FREE(frame); + return session_key_obj; } static PyObject *py_iface_user_session_key(PyObject *obj, void *closure) -- 2.49.0 From 1c9edeccfe993def1e3079f623c99ef4957887ce Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 14 Sep 2024 14:31:58 +0200 Subject: [PATCH 14/80] s4:torture/rpc: make use of dcerpc_binding_handle_transport_session_key() Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 4ccd2dd8a2f78bcd53c047889b8043e8d95a6d55) --- source4/torture/rpc/backupkey.c | 5 +++-- source4/torture/rpc/forest_trust.c | 5 +++-- source4/torture/rpc/lsa.c | 9 +++++---- source4/torture/rpc/samba3rpc.c | 18 ++++++++++++------ source4/torture/rpc/samr.c | 22 +++++++++++----------- source4/torture/rpc/samsync.c | 6 ++++-- source4/torture/rpc/session_key.c | 4 ++-- source4/torture/rpc/testjoin.c | 2 +- source4/torture/rpc/wkssvc.c | 4 ++-- 9 files changed, 43 insertions(+), 32 deletions(-) diff --git a/source4/torture/rpc/backupkey.c b/source4/torture/rpc/backupkey.c index d03e31b77041..82bd4a02000f 100644 --- a/source4/torture/rpc/backupkey.c +++ b/source4/torture/rpc/backupkey.c @@ -1887,8 +1887,9 @@ static bool test_ServerWrap_encrypt_decrypt_manual(struct torture_context *tctx, preferred_key.data = r_query_secret.out.new_val->buf->data; preferred_key.length = r_query_secret.out.new_val->buf->size; - torture_assert_ntstatus_ok(tctx, dcerpc_fetch_session_key(lsa_p, &session_key), - "dcerpc_fetch_session_key failed"); + torture_assert_ntstatus_ok(tctx, + dcerpc_binding_handle_transport_session_key(lsa_b, tctx, &session_key), + "transport_session_key failed"); torture_assert_ntstatus_ok(tctx, sess_decrypt_blob(tctx, diff --git a/source4/torture/rpc/forest_trust.c b/source4/torture/rpc/forest_trust.c index c4ca02da58ee..6a82b44ec0f7 100644 --- a/source4/torture/rpc/forest_trust.c +++ b/source4/torture/rpc/forest_trust.c @@ -826,6 +826,7 @@ static bool test_setup_trust(struct torture_context *tctx, DATA_BLOB *auth_blob) { + struct dcerpc_binding_handle *b = p->binding_handle; DATA_BLOB session_key; struct lsa_TrustDomainInfoAuthInfoInternal authinfo; NTSTATUS status; @@ -839,9 +840,9 @@ static bool test_setup_trust(struct torture_context *tctx, return false; } - status = dcerpc_fetch_session_key(p, &session_key); + status = dcerpc_binding_handle_transport_session_key(b, p, &session_key); if (!NT_STATUS_IS_OK(status)) { - torture_comment(tctx, "dcerpc_fetch_session_key failed - %s\n", + torture_comment(tctx, "transport_session_key failed - %s\n", nt_errstr(status)); return false; } diff --git a/source4/torture/rpc/lsa.c b/source4/torture/rpc/lsa.c index 4d729f3e7fea..13d542569449 100644 --- a/source4/torture/rpc/lsa.c +++ b/source4/torture/rpc/lsa.c @@ -1730,8 +1730,9 @@ static bool test_CreateSecret(struct dcerpc_pipe *p, torture_assert_ntstatus_ok(tctx, r2.out.result, "OpenSecret failed"); - torture_assert_ntstatus_ok(tctx, dcerpc_fetch_session_key(p, &session_key), - "dcerpc_fetch_session_key failed"); + torture_assert_ntstatus_ok(tctx, + dcerpc_binding_handle_transport_session_key(b, tctx, &session_key), + "transport_session_key failed"); enc_key = sess_encrypt_string(secret1, &session_key); @@ -4658,9 +4659,9 @@ static bool test_CreateTrustedDomainEx_common(struct dcerpc_pipe *p, domsid = talloc_array(tctx, struct dom_sid *, num_trusts); trustdom_handle = talloc_array(tctx, struct policy_handle, num_trusts); - status = dcerpc_fetch_session_key(p, &session_key); + status = dcerpc_binding_handle_transport_session_key(b, tctx, &session_key); if (!NT_STATUS_IS_OK(status)) { - torture_comment(tctx, "dcerpc_fetch_session_key failed - %s\n", nt_errstr(status)); + torture_comment(tctx, "transport_session_key failed - %s\n", nt_errstr(status)); return false; } diff --git a/source4/torture/rpc/samba3rpc.c b/source4/torture/rpc/samba3rpc.c index 0e96a3088810..2141b6a78b06 100644 --- a/source4/torture/rpc/samba3rpc.c +++ b/source4/torture/rpc/samba3rpc.c @@ -668,9 +668,11 @@ static bool create_user(struct torture_context *tctx, encode_pw_buffer(u_info.info23.password.data, password, STR_UNICODE); - status = dcerpc_fetch_session_key(samr_pipe, &session_key); + status = dcerpc_binding_handle_transport_session_key(samr_handle, + tctx, + &session_key); if (!NT_STATUS_IS_OK(status)) { - torture_comment(tctx, "dcerpc_fetch_session_key failed\n"); + torture_comment(tctx, "transport_session_key failed\n"); goto done; } @@ -890,9 +892,11 @@ static bool join3(struct torture_context *tctx, i21->password_expired = 1; */ - status = dcerpc_fetch_session_key(samr_pipe, &session_key); + status = dcerpc_binding_handle_transport_session_key(samr_handle, + tctx, + &session_key); if (!NT_STATUS_IS_OK(status)) { - torture_comment(tctx, "dcerpc_fetch_session_key failed: %s\n", + torture_comment(tctx, "transport_session_key failed: %s\n", nt_errstr(status)); goto done; } @@ -928,9 +932,11 @@ static bool join3(struct torture_context *tctx, /* just to make this test pass */ u_info.info24.password_expired = 1; - status = dcerpc_fetch_session_key(samr_pipe, &session_key); + status = dcerpc_binding_handle_transport_session_key(samr_handle, + tctx, + &session_key); if (!NT_STATUS_IS_OK(status)) { - torture_comment(tctx, "dcerpc_fetch_session_key failed\n"); + torture_comment(tctx, "transport_session_key failed\n"); goto done; } diff --git a/source4/torture/rpc/samr.c b/source4/torture/rpc/samr.c index 806936e9055f..2d3788e05b5c 100644 --- a/source4/torture/rpc/samr.c +++ b/source4/torture/rpc/samr.c @@ -645,7 +645,7 @@ static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx u.info24.password_expired = 0; - status = dcerpc_fetch_session_key(p, &session_key); + status = dcerpc_binding_handle_transport_session_key(b, tctx, &session_key); if (!NT_STATUS_IS_OK(status)) { torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u - no session key - %s\n", s.in.level, nt_errstr(status)); @@ -710,7 +710,7 @@ static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *t u.info23.info.fields_present = fields_present; - status = dcerpc_fetch_session_key(p, &session_key); + status = dcerpc_binding_handle_transport_session_key(b, tctx, &session_key); if (!NT_STATUS_IS_OK(status)) { torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u - no session key - %s\n", s.in.level, nt_errstr(status)); @@ -739,7 +739,7 @@ static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *t *password = newpass; } - status = dcerpc_fetch_session_key(p, &session_key); + status = dcerpc_binding_handle_transport_session_key(b, tctx, &session_key); if (!NT_STATUS_IS_OK(status)) { torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u - no session key - %s\n", s.in.level, nt_errstr(status)); @@ -813,7 +813,7 @@ static bool test_SetUserPass_32(struct dcerpc_pipe *p, struct torture_context *t u.info32.info.fields_present = fields_present; - status = dcerpc_fetch_session_key(p, &session_key); + status = dcerpc_binding_handle_transport_session_key(b, tctx, &session_key); if (!NT_STATUS_IS_OK(status)) { torture_result(tctx, TORTURE_FAIL, @@ -938,7 +938,7 @@ static bool test_SetUserPass_31(struct dcerpc_pipe *p, struct torture_context *t u.info31.password_expired = 0; - status = dcerpc_fetch_session_key(p, &session_key); + status = dcerpc_binding_handle_transport_session_key(b, tctx, &session_key); if (!NT_STATUS_IS_OK(status)) { torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u - no session key - %s\n", s.in.level, nt_errstr(status)); @@ -1040,7 +1040,7 @@ static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tc u.info26.password_expired = 0; - status = dcerpc_fetch_session_key(p, &session_key); + status = dcerpc_binding_handle_transport_session_key(b, tctx, &session_key); if (!NT_STATUS_IS_OK(status)) { torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u - no session key - %s\n", s.in.level, nt_errstr(status)); @@ -1133,7 +1133,7 @@ static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *t u.info25.info.fields_present = fields_present; - status = dcerpc_fetch_session_key(p, &session_key); + status = dcerpc_binding_handle_transport_session_key(b, tctx, &session_key); if (!NT_STATUS_IS_OK(status)) { torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u - no session key - %s\n", s.in.level, nt_errstr(status)); @@ -1228,7 +1228,7 @@ static bool test_SetUserPass_18(struct dcerpc_pipe *p, struct torture_context *t E_md4hash(newpass, nt_hash); E_deshash(newpass, lm_hash); - status = dcerpc_fetch_session_key(p, &session_key); + status = dcerpc_binding_handle_transport_session_key(b, tctx, &session_key); if (!NT_STATUS_IS_OK(status)) { torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u - no session key - %s\n", s.in.level, nt_errstr(status)); @@ -1316,7 +1316,7 @@ static bool test_SetUserPass_21(struct dcerpc_pipe *p, struct torture_context *t u.info21.nt_password_set = true; } - status = dcerpc_fetch_session_key(p, &session_key); + status = dcerpc_binding_handle_transport_session_key(b, tctx, &session_key); if (!NT_STATUS_IS_OK(status)) { torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u - no session key - %s\n", s.in.level, nt_errstr(status)); @@ -1506,7 +1506,7 @@ static bool test_SetUserPass_level_ex(struct dcerpc_pipe *p, break; } - status = dcerpc_fetch_session_key(p, &session_key); + status = dcerpc_binding_handle_transport_session_key(b, tctx, &session_key); if (!NT_STATUS_IS_OK(status)) { torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u - no session key - %s\n", s.in.level, nt_errstr(status)); @@ -3218,7 +3218,7 @@ bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_contex pw_data = data_blob_const(u.info25.password.data, 516); - status = dcerpc_fetch_session_key(p, &session_key); + status = dcerpc_binding_handle_transport_session_key(b, tctx, &session_key); if (!NT_STATUS_IS_OK(status)) { torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u - no session key - %s\n", s.in.level, nt_errstr(status)); diff --git a/source4/torture/rpc/samsync.c b/source4/torture/rpc/samsync.c index 9111df9feed0..40bea6e8e2d2 100644 --- a/source4/torture/rpc/samsync.c +++ b/source4/torture/rpc/samsync.c @@ -933,9 +933,11 @@ static bool samsync_handle_secret(struct torture_context *tctx, We would like to do this, but it is NOT_SUPPORTED on win2k3 TEST_SEC_DESC_EQUAL(secret->sdbuf, lsa, &sec_handle); */ - status = dcerpc_fetch_session_key(samsync_state->p_lsa, &session_key); + status = dcerpc_binding_handle_transport_session_key(samsync_state->b_lsa, + mem_ctx, + &session_key); if (!NT_STATUS_IS_OK(status)) { - torture_comment(tctx, "dcerpc_fetch_session_key failed - %s\n", nt_errstr(status)); + torture_comment(tctx, "transport_session_key failed - %s\n", nt_errstr(status)); return false; } diff --git a/source4/torture/rpc/session_key.c b/source4/torture/rpc/session_key.c index 96f9965a0bd1..26acb0ccfffa 100644 --- a/source4/torture/rpc/session_key.c +++ b/source4/torture/rpc/session_key.c @@ -66,8 +66,8 @@ static bool test_CreateSecret_basic(struct dcerpc_pipe *p, "CreateSecret failed"); torture_assert_ntstatus_ok(tctx, r.out.result, "CreateSecret failed"); - status = dcerpc_fetch_session_key(p, &session_key); - torture_assert_ntstatus_ok(tctx, status, "dcerpc_fetch_session_key failed"); + status = dcerpc_binding_handle_transport_session_key(b, tctx, &session_key); + torture_assert_ntstatus_ok(tctx, status, "transport_session_key failed"); enc_key = sess_encrypt_string(secret1, &session_key); diff --git a/source4/torture/rpc/testjoin.c b/source4/torture/rpc/testjoin.c index 6cf0232d82ef..133b9f09c43c 100644 --- a/source4/torture/rpc/testjoin.c +++ b/source4/torture/rpc/testjoin.c @@ -332,7 +332,7 @@ struct test_join *torture_create_testuser_max_pwlen(struct torture_context *tctx u.info24.password_expired = 0; - status = dcerpc_fetch_session_key(join->p, &session_key); + status = dcerpc_binding_handle_transport_session_key(b, tctx, &session_key); if (!NT_STATUS_IS_OK(status)) { torture_comment(tctx, "SetUserInfo level %u - no session key - %s\n", s.in.level, nt_errstr(status)); diff --git a/source4/torture/rpc/wkssvc.c b/source4/torture/rpc/wkssvc.c index c43e16f2e2de..a77ece44b2b5 100644 --- a/source4/torture/rpc/wkssvc.c +++ b/source4/torture/rpc/wkssvc.c @@ -1236,7 +1236,7 @@ static bool test_NetrJoinDomain2(struct torture_context *tctx, return false; } - status = dcerpc_fetch_session_key(p, &session_key); + status = dcerpc_binding_handle_transport_session_key(b, tctx, &session_key); if (!NT_STATUS_IS_OK(status)) { return false; } @@ -1324,7 +1324,7 @@ static bool test_NetrUnjoinDomain2(struct torture_context *tctx, return false; } - status = dcerpc_fetch_session_key(p, &session_key); + status = dcerpc_binding_handle_transport_session_key(b, tctx, &session_key); if (!NT_STATUS_IS_OK(status)) { return false; } -- 2.49.0 From f45ddcc5204491de59097acf16281a5acbd54ed7 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 14 Sep 2024 14:32:22 +0200 Subject: [PATCH 15/80] s4:librpc/rpc: remove unused dcerpc_fetch_session_key() Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit d9bf23f971dd8f426424f05076e76be587d42087) --- source4/librpc/rpc/dcerpc.h | 2 -- source4/librpc/rpc/dcerpc_util.c | 19 ------------------- 2 files changed, 21 deletions(-) diff --git a/source4/librpc/rpc/dcerpc.h b/source4/librpc/rpc/dcerpc.h index 857c67ddc8ea..dab66501b924 100644 --- a/source4/librpc/rpc/dcerpc.h +++ b/source4/librpc/rpc/dcerpc.h @@ -180,8 +180,6 @@ NTSTATUS dcerpc_pipe_open_smb2(struct dcerpc_pipe *p, const char *pipe_name); NTSTATUS dcerpc_bind_auth_none(struct dcerpc_pipe *p, const struct ndr_interface_table *table); -NTSTATUS dcerpc_fetch_session_key(struct dcerpc_pipe *p, - DATA_BLOB *session_key); struct composite_context; NTSTATUS dcerpc_secondary_connection_recv(struct composite_context *c, struct dcerpc_pipe **p2); diff --git a/source4/librpc/rpc/dcerpc_util.c b/source4/librpc/rpc/dcerpc_util.c index e1178cffad21..f40b872ab407 100644 --- a/source4/librpc/rpc/dcerpc_util.c +++ b/source4/librpc/rpc/dcerpc_util.c @@ -724,25 +724,6 @@ NTSTATUS dcecli_generic_session_key(struct dcecli_connection *c, return dcerpc_generic_session_key(session_key); } -/* - fetch the user session key - may be default (above) or the SMB session key - - The key is always truncated to 16 bytes -*/ -_PUBLIC_ NTSTATUS dcerpc_fetch_session_key(struct dcerpc_pipe *p, - DATA_BLOB *session_key) -{ - NTSTATUS status; - status = p->conn->security_state.session_key(p->conn, session_key); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - session_key->length = MIN(session_key->length, 16); - - return NT_STATUS_OK; -} - /* create a secondary context from a primary connection -- 2.49.0 From 40ca6c66c5d552b80fea839f6e8e9e32789dc2a0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 14 Sep 2024 09:55:20 +0200 Subject: [PATCH 16/80] librpc/rpc: add dcerpc_binding_handle_auth_session_key() Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 5e34173041eb04e30f3f6f81a3269d621220b09c) --- librpc/rpc/binding_handle.c | 12 ++++++++++++ librpc/rpc/rpc_common.h | 8 ++++++++ 2 files changed, 20 insertions(+) diff --git a/librpc/rpc/binding_handle.c b/librpc/rpc/binding_handle.c index f165b47451d6..f8c7add27eaa 100644 --- a/librpc/rpc/binding_handle.c +++ b/librpc/rpc/binding_handle.c @@ -144,6 +144,18 @@ void dcerpc_binding_handle_auth_info(struct dcerpc_binding_handle *h, h->ops->auth_info(h, auth_type, auth_level); } +NTSTATUS dcerpc_binding_handle_auth_session_key( + struct dcerpc_binding_handle *h, + TALLOC_CTX *mem_ctx, + DATA_BLOB *session_key) +{ + if (h->ops->auth_session_key == NULL) { + return NT_STATUS_NO_USER_SESSION_KEY; + } + + return h->ops->auth_session_key(h, mem_ctx, session_key); +} + struct dcerpc_binding_handle_raw_call_state { const struct dcerpc_binding_handle_ops *ops; uint8_t *out_data; diff --git a/librpc/rpc/rpc_common.h b/librpc/rpc/rpc_common.h index 7faeb5f00b3d..565c68c2ecfe 100644 --- a/librpc/rpc/rpc_common.h +++ b/librpc/rpc/rpc_common.h @@ -184,6 +184,9 @@ struct dcerpc_binding_handle_ops { void (*auth_info)(struct dcerpc_binding_handle *h, enum dcerpc_AuthType *auth_type, enum dcerpc_AuthLevel *auth_level); + NTSTATUS (*auth_session_key)(struct dcerpc_binding_handle *h, + TALLOC_CTX *mem_ctx, + DATA_BLOB *session_key); struct tevent_req *(*raw_call_send)(TALLOC_CTX *mem_ctx, struct tevent_context *ev, @@ -266,6 +269,11 @@ void dcerpc_binding_handle_auth_info(struct dcerpc_binding_handle *h, enum dcerpc_AuthType *auth_type, enum dcerpc_AuthLevel *auth_level); +NTSTATUS dcerpc_binding_handle_auth_session_key( + struct dcerpc_binding_handle *h, + TALLOC_CTX *mem_ctx, + DATA_BLOB *session_key); + struct tevent_req *dcerpc_binding_handle_raw_call_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct dcerpc_binding_handle *h, -- 2.49.0 From d57c011fc575e69bd56adaec92010e5aa557a7b3 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 14 Sep 2024 09:55:20 +0200 Subject: [PATCH 17/80] s4:librpc/rpc: add dcerpc_bh_auth_session_key() Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 64467157479c04cb4bafa6c4ec19213009f0643f) --- source4/librpc/rpc/dcerpc.c | 39 +++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index 015b71b2da7a..dafe1feb9a78 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -287,6 +287,44 @@ static void dcerpc_bh_auth_info(struct dcerpc_binding_handle *h, *auth_level = hs->p->conn->security_state.auth_level; } +static NTSTATUS dcerpc_bh_auth_session_key(struct dcerpc_binding_handle *h, + TALLOC_CTX *mem_ctx, + DATA_BLOB *session_key) +{ + struct dcerpc_bh_state *hs = dcerpc_binding_handle_data(h, + struct dcerpc_bh_state); + struct dcecli_security *sec = NULL; + NTSTATUS status; + + if (hs->p == NULL) { + return NT_STATUS_NO_USER_SESSION_KEY; + } + + if (hs->p->conn == NULL) { + return NT_STATUS_NO_USER_SESSION_KEY; + } + + sec = &hs->p->conn->security_state; + + if (sec->auth_type == DCERPC_AUTH_TYPE_NONE) { + return NT_STATUS_NO_USER_SESSION_KEY; + } + + if (sec->generic_state == NULL) { + return NT_STATUS_NO_USER_SESSION_KEY; + } + + status = gensec_session_key(sec->generic_state, + mem_ctx, + session_key); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + talloc_keep_secret(session_key->data); + return NT_STATUS_OK; +} + struct dcerpc_bh_raw_call_state { struct tevent_context *ev; struct dcerpc_binding_handle *h; @@ -659,6 +697,7 @@ static const struct dcerpc_binding_handle_ops dcerpc_bh_ops = { .transport_encrypted = dcerpc_bh_transport_encrypted, .transport_session_key = dcerpc_bh_transport_session_key, .auth_info = dcerpc_bh_auth_info, + .auth_session_key = dcerpc_bh_auth_session_key, .raw_call_send = dcerpc_bh_raw_call_send, .raw_call_recv = dcerpc_bh_raw_call_recv, .disconnect_send = dcerpc_bh_disconnect_send, -- 2.49.0 From 41aa240002458eba1bb6d3439a2edac3e20c62fa Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 14 Sep 2024 09:55:20 +0200 Subject: [PATCH 18/80] s3:rpc_client: add rpccli_bh_auth_session_key() Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit af16ecece870846323956c37d3e15abe24e336fd) --- source3/rpc_client/cli_pipe.c | 39 +++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 5f7cc33e20cc..83869015d5e2 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2215,6 +2215,44 @@ static void rpccli_bh_auth_info(struct dcerpc_binding_handle *h, *auth_level = hs->rpc_cli->auth->auth_level; } +static NTSTATUS rpccli_bh_auth_session_key(struct dcerpc_binding_handle *h, + TALLOC_CTX *mem_ctx, + DATA_BLOB *session_key) +{ + struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h, + struct rpccli_bh_state); + struct pipe_auth_data *auth = NULL; + NTSTATUS status; + + if (hs->rpc_cli == NULL) { + return NT_STATUS_NO_USER_SESSION_KEY; + } + + if (hs->rpc_cli->auth == NULL) { + return NT_STATUS_NO_USER_SESSION_KEY; + } + + auth = hs->rpc_cli->auth; + + if (auth->auth_type == DCERPC_AUTH_TYPE_NONE) { + return NT_STATUS_NO_USER_SESSION_KEY; + } + + if (auth->auth_ctx == NULL) { + return NT_STATUS_NO_USER_SESSION_KEY; + } + + status = gensec_session_key(auth->auth_ctx, + mem_ctx, + session_key); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + talloc_keep_secret(session_key->data); + return NT_STATUS_OK; +} + struct rpccli_bh_raw_call_state { DATA_BLOB in_data; DATA_BLOB out_data; @@ -2388,6 +2426,7 @@ static const struct dcerpc_binding_handle_ops rpccli_bh_ops = { .set_timeout = rpccli_bh_set_timeout, .transport_session_key = rpccli_bh_transport_session_key, .auth_info = rpccli_bh_auth_info, + .auth_session_key = rpccli_bh_auth_session_key, .raw_call_send = rpccli_bh_raw_call_send, .raw_call_recv = rpccli_bh_raw_call_recv, .disconnect_send = rpccli_bh_disconnect_send, -- 2.49.0 From 9bb60117e52660e6952f4666eb7d18724831dd48 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 14 Sep 2024 14:16:01 +0200 Subject: [PATCH 19/80] s4:drepl: make use of dcerpc_binding_handle_auth_session_key() Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 51f5eefcd119b5981281924a45380d99f9158a88) --- source4/dsdb/repl/drepl_out_helpers.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/source4/dsdb/repl/drepl_out_helpers.c b/source4/dsdb/repl/drepl_out_helpers.c index 7ba5c7972677..bf2017ee9c65 100644 --- a/source4/dsdb/repl/drepl_out_helpers.c +++ b/source4/dsdb/repl/drepl_out_helpers.c @@ -119,9 +119,10 @@ static void dreplsrv_out_drsuapi_connect_done(struct composite_context *creq) state->drsuapi->drsuapi_handle = state->drsuapi->pipe->binding_handle; - status = gensec_session_key(state->drsuapi->pipe->conn->security_state.generic_state, - state->drsuapi, - &state->drsuapi->gensec_skey); + status = dcerpc_binding_handle_auth_session_key( + state->drsuapi->drsuapi_handle, + state->drsuapi, + &state->drsuapi->gensec_skey); if (tevent_req_nterror(req, status)) { return; } -- 2.49.0 From 33e04dde3d965a14677768fb19cc9df84780212b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 14 Sep 2024 14:16:42 +0200 Subject: [PATCH 20/80] s4:libnet: make use of dcerpc_binding_handle_auth_session_key() in libnet_become_dc.c Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit bf888b59e34169e1f6b9fd1d211cb8ff973cf333) --- source4/libnet/libnet_become_dc.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/source4/libnet/libnet_become_dc.c b/source4/libnet/libnet_become_dc.c index 3bd8e184b9d1..876ae6162a30 100644 --- a/source4/libnet/libnet_become_dc.c +++ b/source4/libnet/libnet_become_dc.c @@ -1612,9 +1612,10 @@ static void becomeDC_drsuapi1_connect_recv(struct composite_context *req) s->drsuapi1.drsuapi_handle = s->drsuapi1.pipe->binding_handle; - c->status = gensec_session_key(s->drsuapi1.pipe->conn->security_state.generic_state, - s, - &s->drsuapi1.gensec_skey); + c->status = dcerpc_binding_handle_auth_session_key( + s->drsuapi1.drsuapi_handle, + s, + &s->drsuapi1.gensec_skey); if (!composite_is_ok(c)) return; becomeDC_drsuapi_bind_send(s, &s->drsuapi1, becomeDC_drsuapi1_bind_recv); @@ -2524,9 +2525,10 @@ static void becomeDC_drsuapi2_connect_recv(struct composite_context *req) s->drsuapi2.drsuapi_handle = s->drsuapi2.pipe->binding_handle; - c->status = gensec_session_key(s->drsuapi2.pipe->conn->security_state.generic_state, - s, - &s->drsuapi2.gensec_skey); + c->status = dcerpc_binding_handle_auth_session_key( + s->drsuapi2.drsuapi_handle, + s, + &s->drsuapi2.gensec_skey); if (!composite_is_ok(c)) return; becomeDC_drsuapi_bind_send(s, &s->drsuapi2, becomeDC_drsuapi2_bind_recv); @@ -2594,9 +2596,10 @@ static void becomeDC_drsuapi3_connect_recv(struct composite_context *req) s->drsuapi3.drsuapi_handle = s->drsuapi3.pipe->binding_handle; - c->status = gensec_session_key(s->drsuapi3.pipe->conn->security_state.generic_state, - s, - &s->drsuapi3.gensec_skey); + c->status = dcerpc_binding_handle_auth_session_key( + s->drsuapi3.drsuapi_handle, + s, + &s->drsuapi3.gensec_skey); if (!composite_is_ok(c)) return; becomeDC_drsuapi3_pull_schema_send(s); -- 2.49.0 From e0f5ad981ef3c73ea67400b28290c37468038856 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 14 Sep 2024 14:19:55 +0200 Subject: [PATCH 21/80] s4:py_net: make use of dcerpc_binding_handle_auth_session_key() Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 5d3faa86fd47d6bc887e182f3eb5a51144339549) --- source4/libnet/py_net.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source4/libnet/py_net.c b/source4/libnet/py_net.c index 4544d1d90aa0..257149d22980 100644 --- a/source4/libnet/py_net.c +++ b/source4/libnet/py_net.c @@ -488,9 +488,9 @@ static PyObject *py_net_replicate_init(py_net_Object *self, PyObject *args, PyOb return NULL; } - status = gensec_session_key(s->drs_pipe->pipe->conn->security_state.generic_state, - s, - &s->gensec_skey); + status = dcerpc_binding_handle_auth_session_key(s->drs_pipe->binding_handle, + s, + &s->gensec_skey); if (!NT_STATUS_IS_OK(status)) { char *error_string = talloc_asprintf(s, "Unable to get session key from drspipe: %s", @@ -681,9 +681,9 @@ static PyObject *py_net_replicate_decrypt(py_net_Object *self, PyObject *args, P } drs_pipe = (dcerpc_InterfaceObject *)(py_drspipe); - status = gensec_session_key(drs_pipe->pipe->conn->security_state.generic_state, - frame, - &gensec_skey); + status = dcerpc_binding_handle_auth_session_key(drs_pipe->binding_handle, + frame, + &gensec_skey); if (!NT_STATUS_IS_OK(status)) { char *error_string = talloc_asprintf(frame, -- 2.49.0 From 1caebfb28d178f207e2c6edbda960ff705b75224 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 14 Sep 2024 14:20:46 +0200 Subject: [PATCH 22/80] s4:pyrpc: make use of dcerpc_binding_handle_auth_session_key() Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 38874d28404f49a075bab71fb7357d266173791a) --- source4/librpc/rpc/pyrpc.c | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/source4/librpc/rpc/pyrpc.c b/source4/librpc/rpc/pyrpc.c index b8e1ac0c35e0..4f7f4cd1d964 100644 --- a/source4/librpc/rpc/pyrpc.c +++ b/source4/librpc/rpc/pyrpc.c @@ -161,30 +161,18 @@ static PyObject *py_iface_user_session_key(PyObject *obj, void *closure) dcerpc_InterfaceObject *iface = (dcerpc_InterfaceObject *)obj; TALLOC_CTX *mem_ctx; NTSTATUS status; - struct gensec_security *security = NULL; DATA_BLOB session_key = data_blob_null; static PyObject *session_key_obj = NULL; - if (iface->pipe == NULL) { - PyErr_SetNTSTATUS(NT_STATUS_NO_USER_SESSION_KEY); - return NULL; - } - - if (iface->pipe->conn == NULL) { - PyErr_SetNTSTATUS(NT_STATUS_NO_USER_SESSION_KEY); - return NULL; - } - - if (iface->pipe->conn->security_state.generic_state == NULL) { + if (iface->binding_handle == NULL) { PyErr_SetNTSTATUS(NT_STATUS_NO_USER_SESSION_KEY); return NULL; } - - security = iface->pipe->conn->security_state.generic_state; - mem_ctx = talloc_new(NULL); - status = gensec_session_key(security, mem_ctx, &session_key); + status = dcerpc_binding_handle_auth_session_key(iface->binding_handle, + mem_ctx, + &session_key); if (!NT_STATUS_IS_OK(status)) { talloc_free(mem_ctx); PyErr_SetNTSTATUS(status); -- 2.49.0 From 4680e137aceb7268cdd02d235f81be632661c501 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 14 Sep 2024 15:00:37 +0200 Subject: [PATCH 23/80] s4:torture/drs: make use of dcerpc_binding_handle_auth_session_key() Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit bbe529a2f6090d2b9df0f361aee9b0a28523cefe) --- source4/torture/drs/rpc/dssync.c | 5 +++-- source4/torture/drs/rpc/msds_intid.c | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/source4/torture/drs/rpc/dssync.c b/source4/torture/drs/rpc/dssync.c index 689ebd4faa40..1168639a27f4 100644 --- a/source4/torture/drs/rpc/dssync.c +++ b/source4/torture/drs/rpc/dssync.c @@ -708,8 +708,9 @@ static bool test_GetNCChanges(struct torture_context *tctx, dump_data_pw("CREDENTIALS nthash:", nthash->hash, sizeof(nthash->hash)); } } - status = gensec_session_key(ctx->new_dc.drsuapi.drs_pipe->conn->security_state.generic_state, - ctx, &gensec_skey); + status = dcerpc_binding_handle_auth_session_key(ctx->new_dc.drsuapi.drs_handle, + ctx, + &gensec_skey); if (!NT_STATUS_IS_OK(status)) { printf("failed to get gensec session key: %s\n", nt_errstr(status)); return false; diff --git a/source4/torture/drs/rpc/msds_intid.c b/source4/torture/drs/rpc/msds_intid.c index 1bc5c32c5bbf..330e7877bba1 100644 --- a/source4/torture/drs/rpc/msds_intid.c +++ b/source4/torture/drs/rpc/msds_intid.c @@ -217,8 +217,9 @@ static bool _test_DsaBind(struct torture_context *tctx, bi->drs_handle = bi->drs_pipe->binding_handle; - status = gensec_session_key(bi->drs_pipe->conn->security_state.generic_state, - mem_ctx, &bi->gensec_skey); + status = dcerpc_binding_handle_auth_session_key(bi->drs_handle, + mem_ctx, + &bi->gensec_skey); torture_assert_ntstatus_ok(tctx, status, "failed to get gensec session key"); /* Bind to DRSUAPI interface */ -- 2.49.0 From e3a34a25edab07d7437ffbb8ca33e0d718e11f12 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 14 Sep 2024 15:51:20 +0200 Subject: [PATCH 24/80] s3:lib/netapi: make use of dcerpc_binding_handle_transport_session_key() Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 2cb726e92c819d60509419a33cd8da265e1c99e7) --- source3/lib/netapi/joindomain.c | 12 ++++++++---- source3/lib/netapi/user.c | 6 ++++-- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/source3/lib/netapi/joindomain.c b/source3/lib/netapi/joindomain.c index 2b9d26fbaca4..eca836b8381d 100644 --- a/source3/lib/netapi/joindomain.c +++ b/source3/lib/netapi/joindomain.c @@ -145,7 +145,8 @@ WERROR NetJoinDomain_r(struct libnetapi_ctx *ctx, if (r->in.password) { - status = cli_get_session_key(talloc_tos(), pipe_cli, &session_key); + status = dcerpc_binding_handle_transport_session_key( + b, talloc_tos(), &session_key); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; @@ -300,7 +301,8 @@ WERROR NetUnjoinDomain_r(struct libnetapi_ctx *ctx, if (r->in.password) { - status = cli_get_session_key(talloc_tos(), pipe_cli, &session_key); + status = dcerpc_binding_handle_transport_session_key( + b, talloc_tos(), &session_key); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; @@ -518,7 +520,8 @@ WERROR NetGetJoinableOUs_r(struct libnetapi_ctx *ctx, if (r->in.password) { - status = cli_get_session_key(talloc_tos(), pipe_cli, &session_key); + status = dcerpc_binding_handle_transport_session_key( + b, talloc_tos(), &session_key); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; @@ -574,7 +577,8 @@ WERROR NetRenameMachineInDomain_r(struct libnetapi_ctx *ctx, if (r->in.password) { - status = cli_get_session_key(talloc_tos(), pipe_cli, &session_key); + status = dcerpc_binding_handle_transport_session_key( + b, talloc_tos(), &session_key); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; diff --git a/source3/lib/netapi/user.c b/source3/lib/netapi/user.c index a7f4c9d7c012..d3d87be8c514 100644 --- a/source3/lib/netapi/user.c +++ b/source3/lib/netapi/user.c @@ -477,7 +477,8 @@ WERROR NetUserAdd_r(struct libnetapi_ctx *ctx, goto done; } - status = cli_get_session_key(talloc_tos(), pipe_cli, &session_key); + status = dcerpc_binding_handle_transport_session_key( + b, talloc_tos(), &session_key); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; @@ -1953,7 +1954,8 @@ WERROR NetUserSetInfo_r(struct libnetapi_ctx *ctx, goto done; } - status = cli_get_session_key(talloc_tos(), pipe_cli, &session_key); + status = dcerpc_binding_handle_transport_session_key( + b, talloc_tos(), &session_key); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; -- 2.49.0 From 6a50fb2e393527b225c5c4c777003f1fc3554e85 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 14 Sep 2024 15:52:29 +0200 Subject: [PATCH 25/80] s3:libnet_join: make use of dcerpc_binding_handle_transport_session_key() Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 56175a0947fbb56d151fca057cf9696d55ea5d82) --- source3/libnet/libnet_join.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c index f98d132d50f8..dc924ad199ac 100644 --- a/source3/libnet/libnet_join.c +++ b/source3/libnet/libnet_join.c @@ -1370,7 +1370,8 @@ static NTSTATUS libnet_join_joindomain_rpc(TALLOC_CTX *mem_ctx, b = pipe_hnd->binding_handle; - status = cli_get_session_key(mem_ctx, pipe_hnd, &session_key); + status = dcerpc_binding_handle_transport_session_key( + b, mem_ctx, &session_key); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("Error getting session_key of SAM pipe. Error was %s\n", nt_errstr(status))); -- 2.49.0 From e42f58b1b04ae7569b81811d8916eafee1b2c0c1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 14 Sep 2024 15:54:25 +0200 Subject: [PATCH 26/80] s3:utils/net_rpc: make use of dcerpc_binding_handle_transport_session_key() Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit a14ac349deca11cda4159266cb3119fb3024999c) --- source3/utils/net_rpc.c | 6 ++++-- source3/utils/net_rpc_trust.c | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index b04be2efea70..4e4de84b6e39 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -6118,7 +6118,8 @@ static NTSTATUS rpc_trustdom_add_internals(struct net_context *c, init_lsa_String(&lsa_acct_name, acct_name); - status = cli_get_session_key(frame, pipe_hnd, &session_key); + status = dcerpc_binding_handle_transport_session_key( + b, frame, &session_key); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("Error getting session_key of SAM pipe. Error was %s\n", nt_errstr(status))); @@ -6803,7 +6804,8 @@ static NTSTATUS vampire_trusted_domain(struct rpc_pipe_client *pipe_hnd, data = data_blob(info->password.password->data, info->password.password->length); - nt_status = cli_get_session_key(mem_ctx, pipe_hnd, &session_key); + nt_status = dcerpc_binding_handle_transport_session_key( + b, mem_ctx, &session_key); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(0, ("Could not retrieve session key: %s\n", nt_errstr(nt_status))); goto done; diff --git a/source3/utils/net_rpc_trust.c b/source3/utils/net_rpc_trust.c index a3354ad68d45..4e57d7ce044e 100644 --- a/source3/utils/net_rpc_trust.c +++ b/source3/utils/net_rpc_trust.c @@ -260,7 +260,8 @@ static NTSTATUS connect_and_get_info(TALLOC_CTX *mem_ctx, return status; } - status = cli_get_session_key(mem_ctx, *pipe_hnd, session_key); + status = dcerpc_binding_handle_transport_session_key( + (*pipe_hnd)->binding_handle, mem_ctx, session_key); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("Error getting session_key of LSA pipe. Error was %s\n", nt_errstr(status))); -- 2.49.0 From 822d56fce32e42b8ca66be20e4a32c85a1830f99 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 14 Sep 2024 15:55:30 +0200 Subject: [PATCH 27/80] s3:rpc_client: make use of dcerpc_binding_handle_transport_session_key() Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 77da0914d5cccd7116ca3b6f75cb4d0cd0107239) --- source3/rpcclient/cmd_lsarpc.c | 27 ++++++++++++++++++--------- source3/rpcclient/cmd_samr.c | 3 ++- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/source3/rpcclient/cmd_lsarpc.c b/source3/rpcclient/cmd_lsarpc.c index 0903c043a849..a5693504cddb 100644 --- a/source3/rpcclient/cmd_lsarpc.c +++ b/source3/rpcclient/cmd_lsarpc.c @@ -1489,7 +1489,8 @@ static NTSTATUS cmd_lsa_query_trustdominfobysid(struct rpc_pipe_client *cli, goto done; } - status = cli_get_session_key(mem_ctx, cli, &session_key); + status = dcerpc_binding_handle_transport_session_key( + b, mem_ctx, &session_key); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Could not retrieve session key: %s\n", nt_errstr(status))); goto done; @@ -1559,7 +1560,8 @@ static NTSTATUS cmd_lsa_query_trustdominfobyname(struct rpc_pipe_client *cli, goto done; } - status = cli_get_session_key(mem_ctx, cli, &session_key); + status = dcerpc_binding_handle_transport_session_key( + b, mem_ctx, &session_key); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Could not retrieve session key: %s\n", nt_errstr(status))); goto done; @@ -1727,7 +1729,8 @@ static NTSTATUS cmd_lsa_query_trustdominfo(struct rpc_pipe_client *cli, goto done; } - status = cli_get_session_key(mem_ctx, cli, &session_key); + status = dcerpc_binding_handle_transport_session_key( + b, mem_ctx, &session_key); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Could not retrieve session key: %s\n", nt_errstr(status))); goto done; @@ -2205,7 +2208,8 @@ static NTSTATUS cmd_lsa_query_secret(struct rpc_pipe_client *cli, goto done; } - status = cli_get_session_key(mem_ctx, cli, &session_key); + status = dcerpc_binding_handle_transport_session_key( + b, mem_ctx, &session_key); if (!NT_STATUS_IS_OK(status)) { goto done; } @@ -2293,7 +2297,8 @@ static NTSTATUS cmd_lsa_set_secret(struct rpc_pipe_client *cli, ZERO_STRUCT(new_val); ZERO_STRUCT(old_val); - status = cli_get_session_key(mem_ctx, cli, &session_key); + status = dcerpc_binding_handle_transport_session_key( + b, mem_ctx, &session_key); if (!NT_STATUS_IS_OK(status)) { goto done; } @@ -2382,7 +2387,8 @@ static NTSTATUS cmd_lsa_retrieve_private_data(struct rpc_pipe_client *cli, goto done; } - status = cli_get_session_key(mem_ctx, cli, &session_key); + status = dcerpc_binding_handle_transport_session_key( + b, mem_ctx, &session_key); if (!NT_STATUS_IS_OK(status)) { goto done; } @@ -2444,7 +2450,8 @@ static NTSTATUS cmd_lsa_store_private_data(struct rpc_pipe_client *cli, ZERO_STRUCT(val); - status = cli_get_session_key(mem_ctx, cli, &session_key); + status = dcerpc_binding_handle_transport_session_key( + b, mem_ctx, &session_key); if (!NT_STATUS_IS_OK(status)) { goto done; } @@ -2580,7 +2587,8 @@ static NTSTATUS cmd_lsa_create_trusted_domain_ex3(struct rpc_pipe_client *cli, return NT_STATUS_OK; } - status = cli_get_session_key(mem_ctx, cli, &session_key); + status = dcerpc_binding_handle_transport_session_key( + b, mem_ctx, &session_key); if (!NT_STATUS_IS_OK(status)) { DBG_ERR("Could not retrieve session key: %s\n", nt_errstr(status)); @@ -2694,7 +2702,8 @@ static NTSTATUS cmd_lsa_create_trusted_domain_ex2(struct rpc_pipe_client *cli, return NT_STATUS_OK; } - status = cli_get_session_key(mem_ctx, cli, &session_key); + status = dcerpc_binding_handle_transport_session_key( + b, mem_ctx, &session_key); if (!NT_STATUS_IS_OK(status)) { DBG_ERR("Could not retrieve session key: %s\n", nt_errstr(status)); diff --git a/source3/rpcclient/cmd_samr.c b/source3/rpcclient/cmd_samr.c index 8106ca90cf22..3f2adf52cda4 100644 --- a/source3/rpcclient/cmd_samr.c +++ b/source3/rpcclient/cmd_samr.c @@ -3198,7 +3198,8 @@ static NTSTATUS cmd_samr_setuserinfo_int(struct rpc_pipe_client *cli, password_expired = atoi(argv[4]); } - status = cli_get_session_key(frame, cli, &session_key); + status = dcerpc_binding_handle_transport_session_key( + b, frame, &session_key); if (!NT_STATUS_IS_OK(status)) { goto done; } -- 2.49.0 From e10f66f14134d7f81b04c18ebe2ab64db94c0d8a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 14 Sep 2024 15:57:03 +0200 Subject: [PATCH 28/80] s3:libnet_dssync: make use of dcerpc_binding_handle_auth_session_key() Note we only need to call this once per connection, not after each request... Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 099c8d904ece0edbefecbaa51fa50256fd2ea7c0) --- source3/libnet/libnet_dssync.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/source3/libnet/libnet_dssync.c b/source3/libnet/libnet_dssync.c index 7d5d8366b227..7f10f2dd4b1a 100644 --- a/source3/libnet/libnet_dssync.c +++ b/source3/libnet/libnet_dssync.c @@ -467,6 +467,15 @@ static NTSTATUS libnet_dssync_getncchanges(TALLOC_CTX *mem_ctx, } } + status = dcerpc_binding_handle_auth_session_key( + b, mem_ctx, &ctx->session_key); + if (!NT_STATUS_IS_OK(status)) { + ctx->error_message = talloc_asprintf(ctx, + "Failed to get Session Key: %s", + nt_errstr(status)); + goto out; + } + for (y=0, last_query = false; !last_query; y++) { struct drsuapi_DsReplicaObjectListItemEx *first_object = NULL; struct drsuapi_DsReplicaOIDMapping_Ctr *mapping_ctr = NULL; @@ -577,14 +586,6 @@ static NTSTATUS libnet_dssync_getncchanges(TALLOC_CTX *mem_ctx, } } - status = cli_get_session_key(mem_ctx, ctx->cli, &ctx->session_key); - if (!NT_STATUS_IS_OK(status)) { - ctx->error_message = talloc_asprintf(ctx, - "Failed to get Session Key: %s", - nt_errstr(status)); - goto out; - } - libnet_dssync_decrypt_attributes(mem_ctx, &ctx->session_key, first_object); -- 2.49.0 From 5d83e673624d98e63223fa0dcb01caa161d49acd Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 14 Sep 2024 15:57:03 +0200 Subject: [PATCH 29/80] s3:rpcclient/cli_drsuapi: make use of dcerpc_binding_handle_auth_session_key() Note we only need to call this once per connection, not after each request... Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit f75189dee9db486d393cd17c25f5a84ce2d0b889) --- source3/rpcclient/cmd_drsuapi.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/source3/rpcclient/cmd_drsuapi.c b/source3/rpcclient/cmd_drsuapi.c index bf87a26a8d55..3137bc656d2e 100644 --- a/source3/rpcclient/cmd_drsuapi.c +++ b/source3/rpcclient/cmd_drsuapi.c @@ -573,6 +573,14 @@ static WERROR cmd_drsuapi_getncchanges(struct rpc_pipe_client *cli, } } + status = dcerpc_binding_handle_auth_session_key( + b, mem_ctx, &session_key); + if (!NT_STATUS_IS_OK(status)) { + printf("Failed to get Session Key: %s", + nt_errstr(status)); + return ntstatus_to_werror(status); + } + for (y=0; ;y++) { if (level == 8) { @@ -609,13 +617,6 @@ static WERROR cmd_drsuapi_getncchanges(struct rpc_pipe_client *cli, ctr1 = &ctr.ctr2.mszip1.ts->ctr1; } - status = cli_get_session_key(mem_ctx, cli, &session_key); - if (!NT_STATUS_IS_OK(status)) { - printf("Failed to get Session Key: %s", - nt_errstr(status)); - return ntstatus_to_werror(status); - } - if (out_level == 1) { DEBUG(1,("end[%d] tmp_highest_usn: %llu , highest_usn: %llu\n",y, (long long)ctr1->new_highwatermark.tmp_highest_usn, -- 2.49.0 From 74142f33a7e4b661da6d88a5c12103c48d175cf8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 14 Sep 2024 15:58:44 +0200 Subject: [PATCH 30/80] s3:rpc_client: remove unused cli_get_session_key() Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 3a3338bd184e3c51eab48fb1a03b1b3e749f2dc6) --- source3/rpc_client/cli_pipe.c | 49 ----------------------------------- source3/rpc_client/cli_pipe.h | 4 --- 2 files changed, 53 deletions(-) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 83869015d5e2..5be23b990542 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -3725,52 +3725,3 @@ NTSTATUS cli_rpc_pipe_open_schannel_with_creds(struct cli_state *cli, *_rpccli = rpccli; return NT_STATUS_OK; } - -NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx, - struct rpc_pipe_client *cli, - DATA_BLOB *session_key) -{ - NTSTATUS status; - struct pipe_auth_data *a; - struct gensec_security *gensec_security; - DATA_BLOB sk = { .data = NULL }; - bool make_dup = false; - - if (!session_key || !cli) { - return NT_STATUS_INVALID_PARAMETER; - } - - a = cli->auth; - - if (a == NULL) { - return NT_STATUS_INVALID_PARAMETER; - } - - switch (cli->auth->auth_type) { - case DCERPC_AUTH_TYPE_NONE: - sk = data_blob_const(a->transport_session_key.data, - a->transport_session_key.length); - make_dup = true; - break; - default: - gensec_security = a->auth_ctx; - status = gensec_session_key(gensec_security, mem_ctx, &sk); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - make_dup = false; - break; - } - - if (!sk.data) { - return NT_STATUS_NO_USER_SESSION_KEY; - } - - if (make_dup) { - *session_key = data_blob_dup_talloc(mem_ctx, sk); - } else { - *session_key = sk; - } - - return NT_STATUS_OK; -} diff --git a/source3/rpc_client/cli_pipe.h b/source3/rpc_client/cli_pipe.h index d9826ca8e5cd..e6a66bbbe158 100644 --- a/source3/rpc_client/cli_pipe.h +++ b/source3/rpc_client/cli_pipe.h @@ -134,10 +134,6 @@ NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli, TALLOC_CTX *mem_ctx, struct netlogon_creds_cli_context **pcreds); -NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx, - struct rpc_pipe_client *cli, - DATA_BLOB *session_key); - #endif /* _CLI_PIPE_H */ /* vim: set ts=8 sw=8 noet cindent ft=c.doxygen: */ -- 2.49.0 From cecb333edecde58c470d256923848f83a32b2e1e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 14 Sep 2024 15:59:29 +0200 Subject: [PATCH 31/80] s3:rpc_client: the transport_session_key is per connection! It's not per auth_context_id, currently there's no difference but that will change in future... Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 1a311df3d61d3f3dbb986cc35470df6445802ff6) --- source3/librpc/rpc/dcerpc.h | 3 --- source3/rpc_client/cli_pipe.c | 17 +++++------------ source3/rpc_client/rpc_client.h | 1 + 3 files changed, 6 insertions(+), 15 deletions(-) diff --git a/source3/librpc/rpc/dcerpc.h b/source3/librpc/rpc/dcerpc.h index 4b76c5c6d554..76f2fa05ae07 100644 --- a/source3/librpc/rpc/dcerpc.h +++ b/source3/librpc/rpc/dcerpc.h @@ -44,9 +44,6 @@ struct pipe_auth_data { bool verified_bitmask1; struct gensec_security *auth_ctx; - - /* Only the client code uses this for now */ - DATA_BLOB transport_session_key; }; /* The following definitions come from librpc/rpc/dcerpc_helpers.c */ diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 5be23b990542..1e02f53efe94 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2168,24 +2168,17 @@ static NTSTATUS rpccli_bh_transport_session_key(struct dcerpc_binding_handle *h, { struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h, struct rpccli_bh_state); - struct pipe_auth_data *auth = NULL; DATA_BLOB sk = { .length = 0, }; if (hs->rpc_cli == NULL) { return NT_STATUS_NO_USER_SESSION_KEY; } - if (hs->rpc_cli->auth == NULL) { - return NT_STATUS_NO_USER_SESSION_KEY; - } - - auth = hs->rpc_cli->auth; - - if (auth->transport_session_key.length == 0) { + if (hs->rpc_cli->transport_session_key.length == 0) { return NT_STATUS_NO_USER_SESSION_KEY; } - sk = auth->transport_session_key; + sk = hs->rpc_cli->transport_session_key; sk.length = MIN(sk.length, 16); *session_key = data_blob_dup_talloc(mem_ctx, sk); @@ -3479,10 +3472,10 @@ NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli, session = cli->smb1.session; } - status = smbXcli_session_application_key(session, auth, - &auth->transport_session_key); + status = smbXcli_session_application_key(session, result, + &result->transport_session_key); if (!NT_STATUS_IS_OK(status)) { - auth->transport_session_key = data_blob_null; + result->transport_session_key = data_blob_null; } } diff --git a/source3/rpc_client/rpc_client.h b/source3/rpc_client/rpc_client.h index 55eb4dec90bb..9ba783518516 100644 --- a/source3/rpc_client/rpc_client.h +++ b/source3/rpc_client/rpc_client.h @@ -34,6 +34,7 @@ struct dcerpc_binding_handle; struct rpc_pipe_client { struct rpc_pipe_client *prev, *next; + DATA_BLOB transport_session_key; struct rpc_cli_transport *transport; struct dcerpc_binding_handle *binding_handle; -- 2.49.0 From fe098bf02e3690cca15d8e1d24949199f6927c25 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 14 Sep 2024 16:46:47 +0200 Subject: [PATCH 32/80] s3:rpcclient: make use of dcerpc_binding_handle_auth_info() Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 8dcbbebe56d3dad3650eca79322150e9d397e227) --- source3/rpcclient/rpcclient.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c index eed8e4654f24..6df33e04278c 100644 --- a/source3/rpcclient/rpcclient.c +++ b/source3/rpcclient/rpcclient.c @@ -362,16 +362,23 @@ static NTSTATUS cmd_set_ss_level(struct dcerpc_binding *binding) struct cmd_set *tmp_set; for (tmp_set = tmp->cmd_set; tmp_set->name; tmp_set++) { + struct dcerpc_binding_handle *tmp_b = NULL; + enum dcerpc_AuthType tmp_auth_type; + enum dcerpc_AuthLevel tmp_auth_level; + if (tmp_set->rpc_pipe == NULL) { continue; } - if ((tmp_set->rpc_pipe->auth->auth_type - != auth_type) - || (tmp_set->rpc_pipe->auth->auth_level - != auth_level)) { + tmp_b = tmp_set->rpc_pipe->binding_handle; + dcerpc_binding_handle_auth_info(tmp_b, + &tmp_auth_type, + &tmp_auth_level); + + if (tmp_auth_type != auth_type || + tmp_auth_level != auth_level) + { TALLOC_FREE(tmp_set->rpc_pipe); - tmp_set->rpc_pipe = NULL; } } } -- 2.49.0 From f83e431f30b7c09c2ef0f931b4ef8b2f10fb1ce2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 14 Sep 2024 18:54:43 +0200 Subject: [PATCH 33/80] s3:winbindd: cm_connect_lsa_tcp() doesn't need to check for NCACN_IP_TCP or LEVEL_INTEGRITY We only ever create domain->lsa_pipe_tcp with cli_rpc_pipe_open_schannel_with_creds() and hardcoded NCACN_IP_TCP. And schannel_update_internal returns an error with an auth level lower than DCERPC_AUTH_LEVEL_INTEGRITY. Signed-off-by: Stefan Metzmacher Reviewed-by: Volker Lendecke Reviewed-by: Ralph Boehme (cherry picked from commit 61d38f70be378c59b42a6e20e7d49fea21255c6b) --- source3/winbindd/winbindd_cm.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c index f33e0bcb165c..9d59876970a8 100644 --- a/source3/winbindd/winbindd_cm.c +++ b/source3/winbindd/winbindd_cm.c @@ -2876,9 +2876,7 @@ static NTSTATUS cm_connect_lsa_tcp(struct winbindd_domain *domain, /* * rpccli_is_connected handles more error cases */ - if (rpccli_is_connected(conn->lsa_pipe_tcp) && - conn->lsa_pipe_tcp->transport->transport == NCACN_IP_TCP && - conn->lsa_pipe_tcp->auth->auth_level >= DCERPC_AUTH_LEVEL_INTEGRITY) { + if (rpccli_is_connected(conn->lsa_pipe_tcp)) { goto done; } -- 2.49.0 From 5d766b5e20b0a7fc68e5bf101f2fd39b5f17aa8d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 15 Sep 2024 05:35:30 +0200 Subject: [PATCH 34/80] s3:rpc_client: make use of struct samba_sockaddr in rpc_pipe_open_ncalrpc() Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit d406f9fffede27220f4d589c8ab3c7210ca01b74) --- source3/rpc_client/cli_pipe.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 1e02f53efe94..645820de191c 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -3046,8 +3046,14 @@ NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, { char *socket_name = NULL; struct rpc_pipe_client *result; - struct sockaddr_un addr = { .sun_family = AF_UNIX }; - socklen_t salen = sizeof(addr); + struct samba_sockaddr saddr = { + .sa_socklen = sizeof(struct sockaddr_un), + .u = { + .un = { + .sun_family = AF_UNIX, + }, + }, + }; int pathlen; NTSTATUS status; int fd = -1; @@ -3066,12 +3072,12 @@ NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, } pathlen = snprintf( - addr.sun_path, - sizeof(addr.sun_path), + saddr.u.un.sun_path, + sizeof(saddr.u.un.sun_path), "%s/%s", lp_ncalrpc_dir(), socket_name); - if ((pathlen < 0) || ((size_t)pathlen >= sizeof(addr.sun_path))) { + if ((pathlen < 0) || ((size_t)pathlen >= sizeof(saddr.u.un.sun_path))) { DBG_DEBUG("socket_path for %s too long\n", socket_name); status = NT_STATUS_NAME_TOO_LONG; goto fail; @@ -3102,9 +3108,9 @@ NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, goto fail; } - if (connect(fd, (struct sockaddr *)(void *)&addr, salen) == -1) { + if (connect(fd, &saddr.u.sa, saddr.sa_socklen) == -1) { DBG_WARNING("connect(%s) failed: %s\n", - addr.sun_path, + saddr.u.un.sun_path, strerror(errno)); status = map_nt_error_from_unix(errno); goto fail; -- 2.49.0 From 590f4c8af97bcdd6ecb8a1fc374bb8901c4f58d4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 15 Sep 2024 17:58:53 +0200 Subject: [PATCH 35/80] s3:rpc_client: header signing is negotiated per transport connection All gensec backends support GENSEC_FEATURE_SIGN_PKT_HEADER, so there's no point in negotiating header signing based on the auth context used during the DCERPC Bind. Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 72b79a771fdbf54aa73b4c1b0372b9dffd81bfa6) --- source3/librpc/rpc/dcerpc.h | 1 - source3/rpc_client/cli_pipe.c | 32 +++++++++----------------------- source3/rpc_client/rpc_client.h | 6 ++++++ 3 files changed, 15 insertions(+), 24 deletions(-) diff --git a/source3/librpc/rpc/dcerpc.h b/source3/librpc/rpc/dcerpc.h index 76f2fa05ae07..fdd3beda46d8 100644 --- a/source3/librpc/rpc/dcerpc.h +++ b/source3/librpc/rpc/dcerpc.h @@ -39,7 +39,6 @@ struct pipe_auth_data { enum dcerpc_AuthType auth_type; enum dcerpc_AuthLevel auth_level; uint32_t auth_context_id; - bool client_hdr_signing; bool hdr_signing; bool verified_bitmask1; diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 645820de191c..c1819ad991d0 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1082,8 +1082,7 @@ static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, static NTSTATUS create_generic_auth_rpc_bind_req(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - DATA_BLOB *auth_token, - bool *client_hdr_signing) + DATA_BLOB *auth_token) { struct gensec_security *gensec_security; DATA_BLOB null_blob = { .data = NULL }; @@ -1100,18 +1099,6 @@ static NTSTATUS create_generic_auth_rpc_bind_req(struct rpc_pipe_client *cli, return status; } - if (client_hdr_signing == NULL) { - return status; - } - - if (cli->auth->auth_level < DCERPC_AUTH_LEVEL_PACKET) { - *client_hdr_signing = false; - return status; - } - - *client_hdr_signing = gensec_have_feature(gensec_security, - GENSEC_FEATURE_SIGN_PKT_HEADER); - return status; } @@ -1125,7 +1112,6 @@ static NTSTATUS create_bind_or_alt_ctx_internal(TALLOC_CTX *mem_ctx, const struct ndr_syntax_id *abstract, const struct ndr_syntax_id *transfer, const DATA_BLOB *auth_info, - bool client_hdr_signing, DATA_BLOB *blob) { uint16_t auth_len = auth_info->length; @@ -1160,7 +1146,7 @@ static NTSTATUS create_bind_or_alt_ctx_internal(TALLOC_CTX *mem_ctx, auth_len -= DCERPC_AUTH_TRAILER_LENGTH; } - if (client_hdr_signing) { + if (ptype == DCERPC_PKT_BIND) { pfc_flags |= DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN; } @@ -1196,7 +1182,7 @@ static NTSTATUS create_rpc_bind_req(TALLOC_CTX *mem_ctx, if (auth->auth_type != DCERPC_AUTH_TYPE_NONE) { ret = create_generic_auth_rpc_bind_req( - cli, mem_ctx, &auth_token, &auth->client_hdr_signing); + cli, mem_ctx, &auth_token); if (!NT_STATUS_IS_OK(ret) && !NT_STATUS_EQUAL(ret, NT_STATUS_MORE_PROCESSING_REQUIRED)) { @@ -1224,7 +1210,6 @@ static NTSTATUS create_rpc_bind_req(TALLOC_CTX *mem_ctx, abstract, transfer, &auth_info, - auth->client_hdr_signing, rpc_out); data_blob_free(&auth_info); @@ -1354,7 +1339,7 @@ static NTSTATUS prepare_verification_trailer(struct rpc_api_pipe_req_state *stat } t->commands[t->count.count++] = (struct dcerpc_sec_vt) { .command = DCERPC_SEC_VT_COMMAND_BITMASK1, - .u.bitmask1 = (a->client_hdr_signing) ? + .u.bitmask1 = (state->cli->client_hdr_signing) ? DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0, }; @@ -1790,7 +1775,6 @@ static NTSTATUS create_rpc_alter_context(TALLOC_CTX *mem_ctx, abstract, transfer, &auth_info, - false, /* client_hdr_signing */ rpc_out); data_blob_free(&auth_info); return status; @@ -1839,6 +1823,8 @@ struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx, state->cli = cli; state->rpc_call_id = get_rpc_call_id(); + cli->client_hdr_signing = true; + cli->auth = talloc_move(cli, &auth); /* Marshall the outgoing data. */ @@ -1899,9 +1885,7 @@ static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq) if (pkt->ptype == DCERPC_PKT_BIND_ACK) { if (pkt->pfc_flags & DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN) { - if (pauth->client_hdr_signing) { - pauth->hdr_signing = true; - } + state->cli->hdr_signing = true; } } @@ -1918,6 +1902,8 @@ static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq) return; } + pauth->hdr_signing = state->cli->hdr_signing; + /* get auth credentials */ status = dcerpc_pull_auth_trailer(pkt, talloc_tos(), &pkt->u.bind_ack.auth_info, diff --git a/source3/rpc_client/rpc_client.h b/source3/rpc_client/rpc_client.h index 9ba783518516..b2f02b01b3d4 100644 --- a/source3/rpc_client/rpc_client.h +++ b/source3/rpc_client/rpc_client.h @@ -38,6 +38,12 @@ struct rpc_pipe_client { struct rpc_cli_transport *transport; struct dcerpc_binding_handle *binding_handle; + /* + * This is per connection + */ + bool client_hdr_signing; + bool hdr_signing; + /* * This is per association_group, but * for now we only have one connection -- 2.49.0 From 7dbc96c13386a9ea91d3443858a92261fe790669 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 17 Sep 2024 19:28:55 +0200 Subject: [PATCH 36/80] librpc/rpc: add get_binding() to dcerpc_binding_handle_ops Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 1adf226e74375b2fb0932380f13bf19d8d856ea4) --- librpc/rpc/rpc_common.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/librpc/rpc/rpc_common.h b/librpc/rpc/rpc_common.h index 565c68c2ecfe..33892a685971 100644 --- a/librpc/rpc/rpc_common.h +++ b/librpc/rpc/rpc_common.h @@ -172,6 +172,8 @@ enum dcerpc_transport_t dcerpc_transport_by_tower(const struct epm_tower *tower) struct dcerpc_binding_handle_ops { const char *name; + const struct dcerpc_binding *(*get_binding)(struct dcerpc_binding_handle *h); + bool (*is_connected)(struct dcerpc_binding_handle *h); uint32_t (*set_timeout)(struct dcerpc_binding_handle *h, uint32_t timeout); -- 2.49.0 From e1576956ce587e0d64c4c08ced82d95c259f536f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 17 Sep 2024 20:43:28 +0200 Subject: [PATCH 37/80] libcli/tstream_binding_handle: implement get_binding() We just create an dummy binding handle here as it's not really dcerpc... Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 66411b96b88fbb7b405efa87015e4af1f2988fad) --- .../tstream_binding_handle.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/libcli/tstream_binding_handle/tstream_binding_handle.c b/libcli/tstream_binding_handle/tstream_binding_handle.c index 76f54a7f338a..672fd3b89c68 100644 --- a/libcli/tstream_binding_handle/tstream_binding_handle.c +++ b/libcli/tstream_binding_handle/tstream_binding_handle.c @@ -35,8 +35,17 @@ struct tstream_bh_state { size_t call_initial_read_size; tstream_read_pdu_blob_full_fn_t *complete_pdu_fn; void *complete_pdu_fn_private; + const struct dcerpc_binding *binding; }; +static const struct dcerpc_binding *tstream_bh_get_binding(struct dcerpc_binding_handle *h) +{ + struct tstream_bh_state *hs = dcerpc_binding_handle_data( + h, struct tstream_bh_state); + + return hs->binding; +} + static bool tstream_bh_is_connected(struct dcerpc_binding_handle *h) { struct tstream_bh_state *hs = dcerpc_binding_handle_data( @@ -290,6 +299,7 @@ static NTSTATUS tstream_bh_call_recv(struct tevent_req *req, static const struct dcerpc_binding_handle_ops tstream_bh_ops = { .name = "tstream_binding_handle", + .get_binding = tstream_bh_get_binding, .is_connected = tstream_bh_is_connected, .set_timeout = tstream_bh_set_timeout, .raw_call_send = tstream_bh_call_send, @@ -309,6 +319,8 @@ struct dcerpc_binding_handle *tstream_binding_handle_create( { struct dcerpc_binding_handle *h = NULL; struct tstream_bh_state *hs = NULL; + struct dcerpc_binding *b = NULL; + NTSTATUS status; h = dcerpc_binding_handle_create(mem_ctx, &tstream_bh_ops, @@ -333,6 +345,13 @@ struct dcerpc_binding_handle *tstream_binding_handle_create( return NULL; } + status = dcerpc_parse_binding(hs, "", &b); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(h); + return NULL; + } + hs->binding = b; + if (max_data > 0) { tstream_smbXcli_np_set_max_data(hs->stream, max_data); } -- 2.49.0 From adf2d1af03114fa066fd63932c02dc332f49d35f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 17 Sep 2024 20:43:28 +0200 Subject: [PATCH 38/80] s4:lib/messaging: implement irpc_bh_get_binding() We just use NCACN_INTERNAL here... Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit a6034592faf0676532c97a79b9c542bcd2de9537) --- source4/lib/messaging/messaging.c | 44 +++++++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/source4/lib/messaging/messaging.c b/source4/lib/messaging/messaging.c index aa923165255c..6e9c644b9bb8 100644 --- a/source4/lib/messaging/messaging.c +++ b/source4/lib/messaging/messaging.c @@ -1168,12 +1168,21 @@ struct server_id imessaging_get_server_id(struct imessaging_context *msg_ctx) struct irpc_bh_state { struct imessaging_context *msg_ctx; + const struct dcerpc_binding *binding; struct server_id server_id; const struct ndr_interface_table *table; uint32_t timeout; struct security_token *token; }; +static const struct dcerpc_binding *irpc_bh_get_binding(struct dcerpc_binding_handle *h) +{ + struct irpc_bh_state *hs = dcerpc_binding_handle_data(h, + struct irpc_bh_state); + + return hs->binding; +} + static bool irpc_bh_is_connected(struct dcerpc_binding_handle *h) { struct irpc_bh_state *hs = dcerpc_binding_handle_data(h, @@ -1450,6 +1459,7 @@ static void irpc_bh_do_ndr_print(struct dcerpc_binding_handle *h, static const struct dcerpc_binding_handle_ops irpc_bh_ops = { .name = "wbint", + .get_binding = irpc_bh_get_binding, .is_connected = irpc_bh_is_connected, .set_timeout = irpc_bh_set_timeout, .raw_call_send = irpc_bh_raw_call_send, @@ -1467,8 +1477,10 @@ struct dcerpc_binding_handle *irpc_binding_handle(TALLOC_CTX *mem_ctx, struct server_id server_id, const struct ndr_interface_table *table) { - struct dcerpc_binding_handle *h; - struct irpc_bh_state *hs; + struct dcerpc_binding_handle *h = NULL; + struct irpc_bh_state *hs = NULL; + struct dcerpc_binding *b = NULL; + NTSTATUS status; h = dcerpc_binding_handle_create(mem_ctx, &irpc_bh_ops, @@ -1485,6 +1497,34 @@ struct dcerpc_binding_handle *irpc_binding_handle(TALLOC_CTX *mem_ctx, hs->table = table; hs->timeout = IRPC_CALL_TIMEOUT; + status = dcerpc_parse_binding(hs, "", &b); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(h); + return NULL; + } + status = dcerpc_binding_set_transport(b, NCACN_INTERNAL); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(h); + return NULL; + } + status = dcerpc_binding_set_string_option(b, "host", "localhost"); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(h); + return NULL; + } + status = dcerpc_binding_set_string_option(b, "endpoint", "irpc"); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(h); + return NULL; + } + status = dcerpc_binding_set_abstract_syntax(b, &table->syntax_id); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(h); + return NULL; + } + + hs->binding = b; + return h; } -- 2.49.0 From 714bd5b2bac483b612fe3417a4c693c27b0b0543 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 17 Sep 2024 20:52:41 +0200 Subject: [PATCH 39/80] s3:winbindd: implement wbint_bh_get_binding() in winbindd_dual_ndr.c We use NCACN_INTERNAL here too... Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 8c2aa56c7003e690252dfb05f78fd083c0c13dab) --- source3/winbindd/winbindd_dual_ndr.c | 47 ++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/source3/winbindd/winbindd_dual_ndr.c b/source3/winbindd/winbindd_dual_ndr.c index 7835bd321239..718405cc1370 100644 --- a/source3/winbindd/winbindd_dual_ndr.c +++ b/source3/winbindd/winbindd_dual_ndr.c @@ -40,8 +40,17 @@ struct wbint_bh_state { struct winbindd_domain *domain; struct winbindd_child *child; + const struct dcerpc_binding *binding; }; +static const struct dcerpc_binding *wbint_bh_get_binding(struct dcerpc_binding_handle *h) +{ + struct wbint_bh_state *hs = dcerpc_binding_handle_data(h, + struct wbint_bh_state); + + return hs->binding; +} + static bool wbint_bh_is_connected(struct dcerpc_binding_handle *h) { struct wbint_bh_state *hs = dcerpc_binding_handle_data(h, @@ -313,6 +322,7 @@ static void wbint_bh_do_ndr_print(struct dcerpc_binding_handle *h, static const struct dcerpc_binding_handle_ops wbint_bh_ops = { .name = "wbint", + .get_binding = wbint_bh_get_binding, .is_connected = wbint_bh_is_connected, .set_timeout = wbint_bh_set_timeout, .raw_call_send = wbint_bh_raw_call_send, @@ -504,8 +514,10 @@ struct dcerpc_binding_handle *wbint_binding_handle(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain, struct winbindd_child *child) { - struct dcerpc_binding_handle *h; - struct wbint_bh_state *hs; + struct dcerpc_binding_handle *h = NULL; + struct wbint_bh_state *hs = NULL; + struct dcerpc_binding *b = NULL; + NTSTATUS status; h = dcerpc_binding_handle_create(mem_ctx, &wbint_bh_ops, @@ -520,6 +532,37 @@ struct dcerpc_binding_handle *wbint_binding_handle(TALLOC_CTX *mem_ctx, hs->domain = domain; hs->child = child; + status = dcerpc_parse_binding(hs, "", &b); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(h); + return NULL; + } + status = dcerpc_binding_set_transport(b, NCACN_INTERNAL); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(h); + return NULL; + } + status = dcerpc_binding_set_string_option(b, "host", "localhost"); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(h); + return NULL; + } + status = dcerpc_binding_set_string_option(b, + "endpoint", + "winbindd_dual_ndrcmd"); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(h); + return NULL; + } + status = dcerpc_binding_set_abstract_syntax(b, + &ndr_table_winbind.syntax_id); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(h); + return NULL; + } + + hs->binding = b; + return h; } -- 2.49.0 From 537f5154425d8b50d6f253421113d386218f34b4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 18 Sep 2024 23:25:34 +0200 Subject: [PATCH 40/80] s4:librpc/rpc: call dcerpc_binding_set_abstract_syntax after bind or alter context Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit e8d59ca3361bcdaf4db729eeb4a71f714bd9feda) --- source4/librpc/rpc/dcerpc.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index dafe1feb9a78..6600febf068f 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -1357,6 +1357,10 @@ static void dcerpc_bind_recv_handler(struct rpc_request *subreq, if (tevent_req_nterror(req, status)) { return; } + status = dcerpc_binding_set_abstract_syntax(b, &state->p->syntax); + if (tevent_req_nterror(req, status)) { + return; + } tevent_req_done(req); } @@ -2307,6 +2311,7 @@ static void dcerpc_alter_context_recv_handler(struct rpc_request *subreq, struct dcerpc_alter_context_state); struct dcecli_connection *conn = state->p->conn; struct dcecli_security *sec = &conn->security_state; + struct dcerpc_binding *b = NULL; NTSTATUS status; /* @@ -2384,6 +2389,15 @@ static void dcerpc_alter_context_recv_handler(struct rpc_request *subreq, } } + /* + * We're the owner of the binding, so we're allowed to modify it. + */ + b = discard_const_p(struct dcerpc_binding, state->p->binding); + status = dcerpc_binding_set_abstract_syntax(b, &state->p->syntax); + if (tevent_req_nterror(req, status)) { + return; + } + tevent_req_done(req); } -- 2.49.0 From 4baacb5c40ccd5e16774ef8a3c56d4bc2388571f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 17 Sep 2024 20:55:35 +0200 Subject: [PATCH 41/80] s4:librpc/rpc: implement dcerpc_bh_get_binding() Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 0ef5d79eb6feefa2b7c5821ced98773d6d8fdd3a) --- source4/librpc/rpc/dcerpc.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index 6600febf068f..feacdcb2f591 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -176,6 +176,14 @@ struct dcerpc_bh_state { struct dcerpc_pipe *p; }; +static const struct dcerpc_binding *dcerpc_bh_get_binding(struct dcerpc_binding_handle *h) +{ + struct dcerpc_bh_state *hs = dcerpc_binding_handle_data(h, + struct dcerpc_bh_state); + + return hs->p->binding; +} + static bool dcerpc_bh_is_connected(struct dcerpc_binding_handle *h) { struct dcerpc_bh_state *hs = dcerpc_binding_handle_data(h, @@ -692,6 +700,7 @@ static NTSTATUS dcerpc_bh_ndr_validate_out(struct dcerpc_binding_handle *h, static const struct dcerpc_binding_handle_ops dcerpc_bh_ops = { .name = "dcerpc", + .get_binding = dcerpc_bh_get_binding, .is_connected = dcerpc_bh_is_connected, .set_timeout = dcerpc_bh_set_timeout, .transport_encrypted = dcerpc_bh_transport_encrypted, -- 2.49.0 From 4d850b9dd321974c70d3ec70446b037393faced7 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 17 Sep 2024 22:21:23 +0200 Subject: [PATCH 42/80] s3:rpc_client: implement rpccli_bh_get_binding() Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit fffc6e0f37a2d6a6612e17ad6fa777ae6a8eb3b6) --- source3/rpc_client/cli_pipe.c | 44 +++++++++++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index c1819ad991d0..9e9b9fe38b2c 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2105,8 +2105,17 @@ bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli) struct rpccli_bh_state { struct rpc_pipe_client *rpc_cli; + struct dcerpc_binding *binding; }; +static const struct dcerpc_binding *rpccli_bh_get_binding(struct dcerpc_binding_handle *h) +{ + struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h, + struct rpccli_bh_state); + + return hs->binding; +} + static bool rpccli_bh_is_connected(struct dcerpc_binding_handle *h) { struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h, @@ -2401,6 +2410,7 @@ static void rpccli_bh_do_ndr_print(struct dcerpc_binding_handle *h, static const struct dcerpc_binding_handle_ops rpccli_bh_ops = { .name = "rpccli", + .get_binding = rpccli_bh_get_binding, .is_connected = rpccli_bh_is_connected, .set_timeout = rpccli_bh_set_timeout, .transport_session_key = rpccli_bh_transport_session_key, @@ -2420,8 +2430,10 @@ struct dcerpc_binding_handle *rpccli_bh_create(struct rpc_pipe_client *c, const struct GUID *object, const struct ndr_interface_table *table) { - struct dcerpc_binding_handle *h; - struct rpccli_bh_state *hs; + struct dcerpc_binding_handle *h = NULL; + struct rpccli_bh_state *hs = NULL; + struct dcerpc_binding *b = NULL; + NTSTATUS status; h = dcerpc_binding_handle_create(c, &rpccli_bh_ops, @@ -2435,6 +2447,34 @@ struct dcerpc_binding_handle *rpccli_bh_create(struct rpc_pipe_client *c, } hs->rpc_cli = c; + status = dcerpc_parse_binding(hs, "", &b); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(h); + return NULL; + } + status = dcerpc_binding_set_transport(b, c->transport->transport); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(h); + return NULL; + } + status = dcerpc_binding_set_string_option(b, "host", c->desthost); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(h); + return NULL; + } + status = dcerpc_binding_set_string_option(b, "target_hostname", c->desthost); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(h); + return NULL; + } + status = dcerpc_binding_set_abstract_syntax(b, &table->syntax_id); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(h); + return NULL; + } + + hs->binding = b; + return h; } -- 2.49.0 From e0ab8361b1884ec5309f06251eea245a633bd6ec Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 17 Sep 2024 20:56:07 +0200 Subject: [PATCH 43/80] librpc/rpc: add dcerpc_binding_handle_get_binding() Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit a038e7d8cf7a93ecf9a3e0c906f0d0db81ecee54) --- librpc/rpc/binding_handle.c | 5 +++++ librpc/rpc/rpc_common.h | 2 ++ 2 files changed, 7 insertions(+) diff --git a/librpc/rpc/binding_handle.c b/librpc/rpc/binding_handle.c index f8c7add27eaa..329184b2b8b9 100644 --- a/librpc/rpc/binding_handle.c +++ b/librpc/rpc/binding_handle.c @@ -87,6 +87,11 @@ void dcerpc_binding_handle_set_sync_ev(struct dcerpc_binding_handle *h, h->sync_ev = ev; } +const struct dcerpc_binding *dcerpc_binding_handle_get_binding(struct dcerpc_binding_handle *h) +{ + return h->ops->get_binding(h); +} + bool dcerpc_binding_handle_is_connected(struct dcerpc_binding_handle *h) { return h->ops->is_connected(h); diff --git a/librpc/rpc/rpc_common.h b/librpc/rpc/rpc_common.h index 33892a685971..c72ff062df8c 100644 --- a/librpc/rpc/rpc_common.h +++ b/librpc/rpc/rpc_common.h @@ -255,6 +255,8 @@ void *_dcerpc_binding_handle_data(struct dcerpc_binding_handle *h); _DEPRECATED_ void dcerpc_binding_handle_set_sync_ev(struct dcerpc_binding_handle *h, struct tevent_context *ev); +const struct dcerpc_binding *dcerpc_binding_handle_get_binding(struct dcerpc_binding_handle *h); + bool dcerpc_binding_handle_is_connected(struct dcerpc_binding_handle *h); uint32_t dcerpc_binding_handle_set_timeout(struct dcerpc_binding_handle *h, -- 2.49.0 From 69bb174d7d45ddc68cf189d69c654bbe2701c97b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 17 Sep 2024 22:29:58 +0200 Subject: [PATCH 44/80] librpc/rpc: add dcerpc_binding_handle_get_transport() helper function This will allow callers to avoid the dcerpc_binding_handle_get_binding() dcerpc_binding_get_transport() dance... Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 0e751215b349e10cc796065d6d01de35f52b41fd) --- librpc/rpc/binding_handle.c | 6 ++++++ librpc/rpc/rpc_common.h | 2 ++ 2 files changed, 8 insertions(+) diff --git a/librpc/rpc/binding_handle.c b/librpc/rpc/binding_handle.c index 329184b2b8b9..8ace6722a432 100644 --- a/librpc/rpc/binding_handle.c +++ b/librpc/rpc/binding_handle.c @@ -92,6 +92,12 @@ const struct dcerpc_binding *dcerpc_binding_handle_get_binding(struct dcerpc_bin return h->ops->get_binding(h); } +enum dcerpc_transport_t dcerpc_binding_handle_get_transport(struct dcerpc_binding_handle *h) +{ + const struct dcerpc_binding *b = dcerpc_binding_handle_get_binding(h); + return dcerpc_binding_get_transport(b); +} + bool dcerpc_binding_handle_is_connected(struct dcerpc_binding_handle *h) { return h->ops->is_connected(h); diff --git a/librpc/rpc/rpc_common.h b/librpc/rpc/rpc_common.h index c72ff062df8c..493c31371261 100644 --- a/librpc/rpc/rpc_common.h +++ b/librpc/rpc/rpc_common.h @@ -257,6 +257,8 @@ _DEPRECATED_ void dcerpc_binding_handle_set_sync_ev(struct dcerpc_binding_handle const struct dcerpc_binding *dcerpc_binding_handle_get_binding(struct dcerpc_binding_handle *h); +enum dcerpc_transport_t dcerpc_binding_handle_get_transport(struct dcerpc_binding_handle *h); + bool dcerpc_binding_handle_is_connected(struct dcerpc_binding_handle *h); uint32_t dcerpc_binding_handle_set_timeout(struct dcerpc_binding_handle *h, -- 2.49.0 From a6b69ca117d5f49bff360eca25e9b666395608fa Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 20 Sep 2024 00:00:31 +0200 Subject: [PATCH 45/80] librpc/rpc: un-const dcerpc_default_transport_endpoint() It returns an alloced string so it should not be marked as const... Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 9fe85a93539adb73ae59247d044746073915684a) --- librpc/rpc/dcerpc_util.c | 8 ++++---- librpc/rpc/dcerpc_util.h | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/librpc/rpc/dcerpc_util.c b/librpc/rpc/dcerpc_util.c index 51a8a11ac4a1..e01391e6dcd7 100644 --- a/librpc/rpc/dcerpc_util.c +++ b/librpc/rpc/dcerpc_util.c @@ -647,13 +647,13 @@ NTSTATUS dcerpc_read_ncacn_packet_recv(struct tevent_req *req, return NT_STATUS_OK; } -const char *dcerpc_default_transport_endpoint(TALLOC_CTX *mem_ctx, - enum dcerpc_transport_t transport, - const struct ndr_interface_table *table) +char *dcerpc_default_transport_endpoint(TALLOC_CTX *mem_ctx, + enum dcerpc_transport_t transport, + const struct ndr_interface_table *table) { NTSTATUS status; const char *p = NULL; - const char *endpoint = NULL; + char *endpoint = NULL; uint32_t i; struct dcerpc_binding *default_binding = NULL; TALLOC_CTX *frame = talloc_stackframe(); diff --git a/librpc/rpc/dcerpc_util.h b/librpc/rpc/dcerpc_util.h index 4e49e3e85725..86c254e539c1 100644 --- a/librpc/rpc/dcerpc_util.h +++ b/librpc/rpc/dcerpc_util.h @@ -36,9 +36,9 @@ uint8_t dcerpc_get_endian_flag(DATA_BLOB *blob); uint8_t dcerpc_get_auth_type(const DATA_BLOB *blob); uint8_t dcerpc_get_auth_level(const DATA_BLOB *blob); uint32_t dcerpc_get_auth_context_id(const DATA_BLOB *blob); -const char *dcerpc_default_transport_endpoint(TALLOC_CTX *mem_ctx, - enum dcerpc_transport_t transport, - const struct ndr_interface_table *table); +char *dcerpc_default_transport_endpoint(TALLOC_CTX *mem_ctx, + enum dcerpc_transport_t transport, + const struct ndr_interface_table *table); NTSTATUS dcerpc_pull_ncacn_packet(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, -- 2.49.0 From 1528d02d4c9d658b59166b9604ad56510468687f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 18 Sep 2024 23:33:53 +0200 Subject: [PATCH 46/80] s4:libnet: make use of dcerpc_binding_handle_get_binding() Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit ad20c6656aa6798541b71b172534054c172d3aa5) --- source4/libnet/libnet_become_dc.c | 8 ++++++-- source4/libnet/libnet_join.c | 3 ++- source4/libnet/libnet_rpc.c | 24 +++++++++++++++++++----- 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/source4/libnet/libnet_become_dc.c b/source4/libnet/libnet_become_dc.c index 876ae6162a30..f7da0cc777dc 100644 --- a/source4/libnet/libnet_become_dc.c +++ b/source4/libnet/libnet_become_dc.c @@ -2303,6 +2303,7 @@ static void becomeDC_drsuapi1_add_entry_recv(struct tevent_req *subreq) struct composite_context *c = s->creq; struct drsuapi_DsAddEntry *r = talloc_get_type_abort(s->ndr_struct_ptr, struct drsuapi_DsAddEntry); + const struct dcerpc_binding *bd1 = NULL; char *binding_str; uint32_t assoc_group_id; @@ -2493,7 +2494,8 @@ static void becomeDC_drsuapi1_add_entry_recv(struct tevent_req *subreq) } /* w2k3 uses the same assoc_group_id as on the first connection, so we do */ - assoc_group_id = dcerpc_binding_get_assoc_group_id(s->drsuapi1.pipe->binding); + bd1 = dcerpc_binding_handle_get_binding(s->drsuapi1.pipe->binding_handle); + assoc_group_id = dcerpc_binding_get_assoc_group_id(bd1); c->status = dcerpc_binding_set_assoc_group_id(s->drsuapi2.binding, assoc_group_id); if (!composite_is_ok(c)) return; @@ -2541,6 +2543,7 @@ static void becomeDC_drsuapi2_bind_recv(struct tevent_req *subreq) struct libnet_BecomeDC_state *s = tevent_req_callback_data(subreq, struct libnet_BecomeDC_state); struct composite_context *c = s->creq; + const struct dcerpc_binding *bd1 = NULL; char *binding_str; uint32_t assoc_group_id; WERROR status; @@ -2571,7 +2574,8 @@ static void becomeDC_drsuapi2_bind_recv(struct tevent_req *subreq) } /* w2k3 uses the same assoc_group_id as on the first connection, so we do */ - assoc_group_id = dcerpc_binding_get_assoc_group_id(s->drsuapi1.pipe->binding); + bd1 = dcerpc_binding_handle_get_binding(s->drsuapi1.pipe->binding_handle); + assoc_group_id = dcerpc_binding_get_assoc_group_id(bd1); c->status = dcerpc_binding_set_assoc_group_id(s->drsuapi3.binding, assoc_group_id); if (!composite_is_ok(c)) return; /* w2k3 uses the concurrent multiplex feature on the 3rd connection, so we do */ diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index e3d5e72fea15..cc8a4f0e9d1e 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -903,7 +903,8 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru talloc_steal(mem_ctx, r->out.realm); r->out.samr_pipe = samr_pipe; talloc_reparent(tmp_ctx, mem_ctx, samr_pipe); - r->out.samr_binding = samr_pipe->binding; + r->out.samr_binding = + dcerpc_binding_handle_get_binding(samr_pipe->binding_handle); r->out.user_handle = u_handle; talloc_steal(mem_ctx, u_handle); r->out.error_string = r2.samr_handle.out.error_string; diff --git a/source4/libnet/libnet_rpc.c b/source4/libnet/libnet_rpc.c index 91c538fa58c4..18805172092b 100644 --- a/source4/libnet/libnet_rpc.c +++ b/source4/libnet/libnet_rpc.c @@ -151,7 +151,10 @@ static void continue_pipe_connect(struct composite_context *ctx) if (s->monitor_fn) { struct monitor_msg msg; struct msg_net_rpc_connect data; - const struct dcerpc_binding *b = s->r.out.dcerpc_pipe->binding; + struct dcerpc_binding_handle *bh = + s->r.out.dcerpc_pipe->binding_handle; + const struct dcerpc_binding *b = + dcerpc_binding_handle_get_binding(bh); /* prepare monitor message and post it */ data.host = dcerpc_binding_get_string_option(b, "host"); @@ -367,7 +370,10 @@ static void continue_rpc_connect(struct composite_context *ctx) if (s->monitor_fn) { struct monitor_msg msg; struct msg_net_rpc_connect data; - const struct dcerpc_binding *b = s->r.out.dcerpc_pipe->binding; + struct dcerpc_binding_handle *bh = + s->r.out.dcerpc_pipe->binding_handle; + const struct dcerpc_binding *b = + dcerpc_binding_handle_get_binding(bh); data.host = dcerpc_binding_get_string_option(b, "host"); data.endpoint = dcerpc_binding_get_string_option(b, "endpoint"); @@ -550,7 +556,10 @@ static void continue_dci_rpc_connect(struct composite_context *ctx) if (s->monitor_fn) { struct monitor_msg msg; struct msg_net_rpc_connect data; - const struct dcerpc_binding *b = s->r.out.dcerpc_pipe->binding; + struct dcerpc_binding_handle *bh = + s->r.out.dcerpc_pipe->binding_handle; + const struct dcerpc_binding *b = + dcerpc_binding_handle_get_binding(bh); data.host = dcerpc_binding_get_string_option(b, "host"); data.endpoint = dcerpc_binding_get_string_option(b, "endpoint"); @@ -784,11 +793,13 @@ static void continue_epm_map_binding_send(struct composite_context *c) struct rpc_connect_dci_state *s; struct composite_context *epm_map_req; struct cli_credentials *epm_creds = NULL; + const struct dcerpc_binding *b = NULL; s = talloc_get_type(c->private_data, struct rpc_connect_dci_state); /* prepare to get endpoint mapping for the requested interface */ - s->final_binding = dcerpc_binding_dup(s, s->lsa_pipe->binding); + b = dcerpc_binding_handle_get_binding(s->lsa_pipe->binding_handle); + s->final_binding = dcerpc_binding_dup(s, b); if (composite_nomem(s->final_binding, c)) return; /* @@ -871,7 +882,10 @@ static void continue_secondary_conn(struct composite_context *ctx) if (s->monitor_fn) { struct monitor_msg msg; struct msg_net_rpc_connect data; - const struct dcerpc_binding *b = s->r.out.dcerpc_pipe->binding; + struct dcerpc_binding_handle *bh = + s->r.out.dcerpc_pipe->binding_handle; + const struct dcerpc_binding *b = + dcerpc_binding_handle_get_binding(bh); /* prepare monitor message and post it */ data.host = dcerpc_binding_get_string_option(b, "host"); -- 2.49.0 From f1027f91caa5cd10c7c1a299aebce8d3c2297ff4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 18 Sep 2024 23:34:44 +0200 Subject: [PATCH 47/80] s4:libnet: make use of dcerpc_binding_handle_get_transport() Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit a4b1845f4c5202afedd65b9d0db2866de75420a5) --- source4/libnet/libnet_rpc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source4/libnet/libnet_rpc.c b/source4/libnet/libnet_rpc.c index 18805172092b..3662a928e580 100644 --- a/source4/libnet/libnet_rpc.c +++ b/source4/libnet/libnet_rpc.c @@ -582,7 +582,8 @@ static void continue_dci_rpc_connect(struct composite_context *ctx) s->attr.sec_qos = &s->qos; - transport = dcerpc_binding_get_transport(s->lsa_pipe->binding); + transport = dcerpc_binding_handle_get_transport( + s->lsa_pipe->binding_handle); if (transport == NCACN_IP_TCP) { /* * Skip to creating the actual connection. We can't open a -- 2.49.0 From b03824c94315ec21cde3c063440c7ac28ed0748e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 17 Sep 2024 23:04:23 +0200 Subject: [PATCH 48/80] s4:torture/rpc: make use of dcerpc_binding_handle_get_binding() and dcerpc_binding_get_flags() Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 7ed9867fa82ae61a4522a724580900adce7e2bb5) --- source4/torture/rpc/backupkey.c | 4 +++- source4/torture/rpc/bind.c | 4 +++- source4/torture/rpc/drsuapi.c | 5 ++++- source4/torture/rpc/dsgetinfo.c | 4 +++- source4/torture/rpc/echo.c | 17 ++++++++++++----- source4/torture/rpc/handles.c | 28 +++++++++++++++++++--------- source4/torture/rpc/netlogon.c | 26 +++++++++++++++++--------- source4/torture/rpc/spoolss.c | 2 +- source4/torture/rpc/winreg.c | 8 ++++++-- 9 files changed, 68 insertions(+), 30 deletions(-) diff --git a/source4/torture/rpc/backupkey.c b/source4/torture/rpc/backupkey.c index 82bd4a02000f..1d33302e94dd 100644 --- a/source4/torture/rpc/backupkey.c +++ b/source4/torture/rpc/backupkey.c @@ -605,6 +605,8 @@ static DATA_BLOB *encrypt_blob_pk(struct torture_context *tctx, static struct bkrp_BackupKey *createRetrieveBackupKeyGUIDStruct(struct torture_context *tctx, struct dcerpc_pipe *p, int version, DATA_BLOB *out) { + const struct dcerpc_binding *bd = + dcerpc_binding_handle_get_binding(p->binding_handle); struct dcerpc_binding *binding; struct bkrp_client_side_wrapped data; struct GUID *g = talloc(tctx, struct GUID); @@ -617,7 +619,7 @@ static struct bkrp_BackupKey *createRetrieveBackupKeyGUIDStruct(struct torture_c return NULL; } - binding = dcerpc_binding_dup(tctx, p->binding); + binding = dcerpc_binding_dup(tctx, bd); if (binding == NULL) { return NULL; } diff --git a/source4/torture/rpc/bind.c b/source4/torture/rpc/bind.c index 7c0d5e4e2188..84f44e514c58 100644 --- a/source4/torture/rpc/bind.c +++ b/source4/torture/rpc/bind.c @@ -86,6 +86,7 @@ static bool test_assoc_group_handles_external(struct torture_context *tctx, const void *private_data) { struct dcerpc_binding *binding1 = NULL; + const struct dcerpc_binding *bd1 = NULL; struct dcerpc_binding *binding2 = NULL; struct dcerpc_pipe *p1 = NULL; struct dcerpc_pipe *p2 = NULL; @@ -152,7 +153,8 @@ static bool test_assoc_group_handles_external(struct torture_context *tctx, "Unexpected EPM Lookup success"); /* Open second pipe, same association group. Handle is found */ - assoc_group_id = dcerpc_binding_get_assoc_group_id(p1->binding); + bd1 = dcerpc_binding_handle_get_binding(p1->binding_handle); + assoc_group_id = dcerpc_binding_get_assoc_group_id(bd1); dcerpc_binding_set_assoc_group_id(binding2, assoc_group_id); TALLOC_FREE(p2); diff --git a/source4/torture/rpc/drsuapi.c b/source4/torture/rpc/drsuapi.c index 4c7e2fc39df8..f39a6271ff45 100644 --- a/source4/torture/rpc/drsuapi.c +++ b/source4/torture/rpc/drsuapi.c @@ -863,6 +863,7 @@ static bool __test_DsBind_assoc_group(struct torture_context *tctx, struct dcerpc_pipe *p2 = NULL; TALLOC_CTX *mem_ctx = priv; struct dcerpc_binding *binding = NULL; + const struct dcerpc_binding *binding2 = NULL; struct policy_handle ds_bind_handle = { .handle_type = 0, }; torture_comment(tctx, "%s: starting...\n", testname); @@ -881,10 +882,12 @@ static bool __test_DsBind_assoc_group(struct torture_context *tctx, tctx->lp_ctx), "connect p1"); + binding2 = dcerpc_binding_handle_get_binding(p1->binding_handle); + torture_assert_ntstatus_ok(tctx, dcerpc_pipe_connect_b(tctx, &p2, - p1->binding, + binding2, &ndr_table_drsuapi, creds, tctx->ev, diff --git a/source4/torture/rpc/dsgetinfo.c b/source4/torture/rpc/dsgetinfo.c index b47d6ee9e534..9e12f8dff0b5 100644 --- a/source4/torture/rpc/dsgetinfo.c +++ b/source4/torture/rpc/dsgetinfo.c @@ -68,7 +68,9 @@ struct DsGetinfoTest { */ static const char *torture_get_ldap_base_dn(struct torture_context *tctx, struct dcerpc_pipe *p) { - const char *hostname = dcerpc_binding_get_string_option(p->binding, "host"); + struct dcerpc_binding_handle *b = p->binding_handle; + const struct dcerpc_binding *bd = dcerpc_binding_handle_get_binding(b); + const char *hostname = dcerpc_binding_get_string_option(bd, "host"); struct ldb_context *ldb; const char *ldap_url = talloc_asprintf(p, "ldap://%s", hostname); const char *attrs[] = { "defaultNamingContext", NULL }; diff --git a/source4/torture/rpc/echo.c b/source4/torture/rpc/echo.c index 15ad299535df..17d3f95517b6 100644 --- a/source4/torture/rpc/echo.c +++ b/source4/torture/rpc/echo.c @@ -69,9 +69,11 @@ static bool test_echodata(struct torture_context *tctx, int len; struct echo_EchoData r; struct dcerpc_binding_handle *b = p->binding_handle; + const struct dcerpc_binding *binding = dcerpc_binding_handle_get_binding(b); + uint16_t flags = dcerpc_binding_get_flags(binding); if (torture_setting_bool(tctx, "quick", false) && - (p->conn->flags & DCERPC_DEBUG_VALIDATE_BOTH)) { + (flags & DCERPC_DEBUG_VALIDATE_BOTH)) { len = 1 + (random() % 500); } else { len = 1 + (random() % 5000); @@ -115,9 +117,11 @@ static bool test_sourcedata(struct torture_context *tctx, int len; struct echo_SourceData r; struct dcerpc_binding_handle *b = p->binding_handle; + const struct dcerpc_binding *binding = dcerpc_binding_handle_get_binding(b); + uint16_t flags = dcerpc_binding_get_flags(binding); if (torture_setting_bool(tctx, "quick", false) && - (p->conn->flags & DCERPC_DEBUG_VALIDATE_BOTH)) { + (flags & DCERPC_DEBUG_VALIDATE_BOTH)) { len = 100 + (random() % 500); } else { len = 200000 + (random() % 5000); @@ -148,9 +152,11 @@ static bool test_sinkdata(struct torture_context *tctx, int len; struct echo_SinkData r; struct dcerpc_binding_handle *b = p->binding_handle; + const struct dcerpc_binding *binding = dcerpc_binding_handle_get_binding(b); + uint16_t flags = dcerpc_binding_get_flags(binding); if (torture_setting_bool(tctx, "quick", false) && - (p->conn->flags & DCERPC_DEBUG_VALIDATE_BOTH)) { + (flags & DCERPC_DEBUG_VALIDATE_BOTH)) { len = 100 + (random() % 5000); } else { len = 200000 + (random() % 5000); @@ -238,6 +244,7 @@ static bool test_sleep(struct torture_context *tctx, struct timeval diff[ASYNC_COUNT]; int total_done = 0; struct dcerpc_binding_handle *b = p->binding_handle; + const struct dcerpc_binding *bd = dcerpc_binding_handle_get_binding(b); enum dcerpc_transport_t transport; uint32_t assoc_group_id; struct dcerpc_pipe *p2 = NULL; @@ -248,8 +255,8 @@ static bool test_sleep(struct torture_context *tctx, } torture_comment(tctx, "Testing TestSleep - use \"torture:quick=yes\" to disable\n"); - transport = dcerpc_binding_get_transport(p->binding); - assoc_group_id = dcerpc_binding_get_assoc_group_id(p->binding); + transport = dcerpc_binding_get_transport(bd); + assoc_group_id = dcerpc_binding_get_assoc_group_id(bd); torture_comment(tctx, "connect echo connection 2 with " "DCERPC_CONCURRENT_MULTIPLEX\n"); diff --git a/source4/torture/rpc/handles.c b/source4/torture/rpc/handles.c index 7c108e56e1ae..e6b2e86eb72e 100644 --- a/source4/torture/rpc/handles.c +++ b/source4/torture/rpc/handles.c @@ -103,6 +103,7 @@ static bool test_handles_lsa_shared(struct torture_context *torture) NTSTATUS status; struct dcerpc_pipe *p1, *p2, *p3, *p4, *p5; struct dcerpc_binding_handle *b1, *b2, *b3, *b4; + const struct dcerpc_binding *bd1 = NULL, *bd2 = NULL; struct policy_handle handle; struct policy_handle handle2; struct lsa_ObjectAttribute attr; @@ -122,9 +123,10 @@ static bool test_handles_lsa_shared(struct torture_context *torture) status = torture_rpc_connection(torture, &p1, &ndr_table_lsarpc); torture_assert_ntstatus_ok(torture, status, "opening lsa pipe1"); b1 = p1->binding_handle; + bd1 = dcerpc_binding_handle_get_binding(b1); - transport = p1->conn->transport.transport; - assoc_group_id = dcerpc_binding_get_assoc_group_id(p1->binding); + transport = dcerpc_binding_get_transport(bd1); + assoc_group_id = dcerpc_binding_get_assoc_group_id(bd1); torture_comment(torture, "use assoc_group_id[0x%08X] for new connections\n", assoc_group_id); @@ -135,9 +137,10 @@ static bool test_handles_lsa_shared(struct torture_context *torture) 0); torture_assert_ntstatus_ok(torture, status, "opening lsa pipe2"); b2 = p2->binding_handle; + bd2 = dcerpc_binding_handle_get_binding(b2); torture_comment(torture, "got assoc_group_id[0x%08X] for p2\n", - dcerpc_binding_get_assoc_group_id(p2->binding)); + dcerpc_binding_get_assoc_group_id(bd2)); qos.len = 0; qos.impersonation_level = 2; @@ -403,6 +406,7 @@ static bool test_handles_mixed_shared(struct torture_context *torture) NTSTATUS status; struct dcerpc_pipe *p1, *p2, *p3, *p4, *p5, *p6; struct dcerpc_binding_handle *b1, *b2; + const struct dcerpc_binding *bd1 = NULL, *bd2 = NULL; struct policy_handle handle; struct policy_handle handle2; struct samr_Connect r; @@ -418,9 +422,10 @@ static bool test_handles_mixed_shared(struct torture_context *torture) status = torture_rpc_connection(torture, &p1, &ndr_table_samr); torture_assert_ntstatus_ok(torture, status, "opening samr pipe1"); b1 = p1->binding_handle; + bd1 = dcerpc_binding_handle_get_binding(b1); - transport = p1->conn->transport.transport; - assoc_group_id = dcerpc_binding_get_assoc_group_id(p1->binding); + transport = dcerpc_binding_get_transport(bd1); + assoc_group_id = dcerpc_binding_get_assoc_group_id(bd1); torture_comment(torture, "use assoc_group_id[0x%08X] for new connections\n", assoc_group_id); @@ -431,9 +436,10 @@ static bool test_handles_mixed_shared(struct torture_context *torture) 0); torture_assert_ntstatus_ok(torture, status, "opening lsa pipe2"); b2 = p2->binding_handle; + bd2 = dcerpc_binding_handle_get_binding(b2); torture_comment(torture, "got assoc_group_id[0x%08X] for p2\n", - dcerpc_binding_get_assoc_group_id(p2->binding)); + dcerpc_binding_get_assoc_group_id(bd2)); r.in.system_name = 0; r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; r.out.connect_handle = &handle; @@ -509,6 +515,7 @@ static bool test_handles_random_assoc(struct torture_context *torture) NTSTATUS status; struct dcerpc_pipe *p1, *p2, *p3; TALLOC_CTX *mem_ctx = talloc_new(torture); + const struct dcerpc_binding *bd1 = NULL; enum dcerpc_transport_t transport; uint32_t assoc_group_id; @@ -518,17 +525,20 @@ static bool test_handles_random_assoc(struct torture_context *torture) status = torture_rpc_connection(torture, &p1, &ndr_table_samr); torture_assert_ntstatus_ok(torture, status, "opening samr pipe1"); + bd1 = dcerpc_binding_handle_get_binding(p1->binding_handle); + assoc_group_id = dcerpc_binding_get_assoc_group_id(bd1); + torture_comment(torture, "pipe1 uses assoc_group_id[0x%08X]\n", - dcerpc_binding_get_assoc_group_id(p1->binding)); + assoc_group_id); + + transport = dcerpc_binding_get_transport(bd1); - transport = p1->conn->transport.transport; /* * We use ~p1->assoc_group_id instead of p1->assoc_group_id, because * this way we are less likely to use an id which is already in use. * * And make sure it doesn't wrap. */ - assoc_group_id = dcerpc_binding_get_assoc_group_id(p1->binding); assoc_group_id = ~MIN(assoc_group_id, UINT32_MAX - 3); torture_comment(torture, "connect samr pipe2 with assoc_group_id[0x%08X]- should fail\n", ++assoc_group_id); diff --git a/source4/torture/rpc/netlogon.c b/source4/torture/rpc/netlogon.c index b9f5e66f0d89..20b2b2adb82d 100644 --- a/source4/torture/rpc/netlogon.c +++ b/source4/torture/rpc/netlogon.c @@ -472,10 +472,12 @@ bool test_SetupCredentialsPipe(const struct dcerpc_pipe *p1, struct dcerpc_pipe **_p2) { NTSTATUS status; + const struct dcerpc_binding *b1 = + dcerpc_binding_handle_get_binding(p1->binding_handle); struct dcerpc_binding *b2 = NULL; struct dcerpc_pipe *p2 = NULL; - b2 = dcerpc_binding_dup(tctx, p1->binding); + b2 = dcerpc_binding_dup(tctx, b1); torture_assert(tctx, b2 != NULL, "dcerpc_binding_dup"); dcerpc_binding_set_flags(b2, DCERPC_SCHANNEL | additional_flags, @@ -2303,6 +2305,7 @@ static bool test_ServerReqChallengeGlobal(struct torture_context *tctx, const char *machine_name; const char *plain_pass; struct dcerpc_binding_handle *b1 = p1->binding_handle; + const struct dcerpc_binding *bd1 = dcerpc_binding_handle_get_binding(b1); struct dcerpc_pipe *p2 = NULL; struct dcerpc_binding_handle *b2 = NULL; @@ -2314,7 +2317,7 @@ static bool test_ServerReqChallengeGlobal(struct torture_context *tctx, torture_comment(tctx, "Testing ServerReqChallenge on b1\n"); torture_assert_ntstatus_ok(tctx, - dcerpc_pipe_connect_b(tctx, &p2, p1->binding, + dcerpc_pipe_connect_b(tctx, &p2, bd1, &ndr_table_netlogon, machine_credentials, tctx->ev, tctx->lp_ctx), @@ -2383,6 +2386,7 @@ static bool test_ServerReqChallengeReuseGlobal(struct torture_context *tctx, const char *machine_name; const char *plain_pass; struct dcerpc_binding_handle *b1 = p1->binding_handle; + const struct dcerpc_binding *bd1 = dcerpc_binding_handle_get_binding(b1); struct dcerpc_pipe *p2 = NULL; struct dcerpc_binding_handle *b2 = NULL; struct dcerpc_pipe *p3 = NULL; @@ -2396,7 +2400,7 @@ static bool test_ServerReqChallengeReuseGlobal(struct torture_context *tctx, torture_comment(tctx, "Testing ServerReqChallenge on b1\n"); torture_assert_ntstatus_ok(tctx, - dcerpc_pipe_connect_b(tctx, &p2, p1->binding, + dcerpc_pipe_connect_b(tctx, &p2, bd1, &ndr_table_netlogon, machine_credentials, tctx->ev, tctx->lp_ctx), @@ -2404,7 +2408,7 @@ static bool test_ServerReqChallengeReuseGlobal(struct torture_context *tctx, b2 = p2->binding_handle; torture_assert_ntstatus_ok(tctx, - dcerpc_pipe_connect_b(tctx, &p3, p1->binding, + dcerpc_pipe_connect_b(tctx, &p3, bd1, &ndr_table_netlogon, machine_credentials, tctx->ev, tctx->lp_ctx), @@ -2484,6 +2488,7 @@ static bool test_ServerReqChallengeReuseGlobal2(struct torture_context *tctx, const char *machine_name; const char *plain_pass; struct dcerpc_binding_handle *b1 = p1->binding_handle; + const struct dcerpc_binding *bd1 = dcerpc_binding_handle_get_binding(b1); struct dcerpc_pipe *p2 = NULL; struct dcerpc_binding_handle *b2 = NULL; @@ -2495,7 +2500,7 @@ static bool test_ServerReqChallengeReuseGlobal2(struct torture_context *tctx, torture_comment(tctx, "Testing ServerReqChallenge on b1\n"); torture_assert_ntstatus_ok(tctx, - dcerpc_pipe_connect_b(tctx, &p2, p1->binding, + dcerpc_pipe_connect_b(tctx, &p2, bd1, &ndr_table_netlogon, machine_credentials, tctx->ev, tctx->lp_ctx), @@ -2576,6 +2581,7 @@ static bool test_ServerReqChallengeReuseGlobal3(struct torture_context *tctx, const char *machine_name; const char *plain_pass; struct dcerpc_binding_handle *b1 = p1->binding_handle; + const struct dcerpc_binding *bd1 = dcerpc_binding_handle_get_binding(b1); struct dcerpc_pipe *p2 = NULL; struct dcerpc_binding_handle *b2 = NULL; @@ -2587,7 +2593,7 @@ static bool test_ServerReqChallengeReuseGlobal3(struct torture_context *tctx, torture_comment(tctx, "Testing ServerReqChallenge on b1\n"); torture_assert_ntstatus_ok(tctx, - dcerpc_pipe_connect_b(tctx, &p2, p1->binding, + dcerpc_pipe_connect_b(tctx, &p2, bd1, &ndr_table_netlogon, machine_credentials, tctx->ev, tctx->lp_ctx), @@ -2670,6 +2676,7 @@ static bool test_ServerReqChallengeReuseGlobal4(struct torture_context *tctx, const char *machine_name; const char *plain_pass; struct dcerpc_binding_handle *b1 = p1->binding_handle; + const struct dcerpc_binding *bd1 = dcerpc_binding_handle_get_binding(b1); struct dcerpc_pipe *p2 = NULL; struct dcerpc_binding_handle *b2 = NULL; @@ -2681,7 +2688,7 @@ static bool test_ServerReqChallengeReuseGlobal4(struct torture_context *tctx, torture_comment(tctx, "Testing ServerReqChallenge on b1\n"); torture_assert_ntstatus_ok(tctx, - dcerpc_pipe_connect_b(tctx, &p2, p1->binding, + dcerpc_pipe_connect_b(tctx, &p2, bd1, &ndr_table_netlogon, machine_credentials, tctx->ev, tctx->lp_ctx), @@ -5815,6 +5822,7 @@ static bool test_ManyGetDCName(struct torture_context *tctx, struct netr_GetAnyDCName d; const char *dcname = NULL; struct dcerpc_binding_handle *b = p->binding_handle; + const struct dcerpc_binding *bd = dcerpc_binding_handle_get_binding(b); struct dcerpc_binding_handle *b2; int i; @@ -5828,7 +5836,7 @@ static bool test_ManyGetDCName(struct torture_context *tctx, anon_creds = cli_credentials_init_anon(tctx); torture_assert(tctx, anon_creds != NULL, "cli_credentials_init_anon failed"); - binding2 = dcerpc_binding_dup(tctx, p->binding); + binding2 = dcerpc_binding_dup(tctx, bd); /* Swap the binding details from NETLOGON to LSA */ status = dcerpc_epm_map_binding(tctx, binding2, &ndr_table_lsarpc, tctx->ev, tctx->lp_ctx); dcerpc_binding_set_assoc_group_id(binding2, 0); @@ -5921,7 +5929,7 @@ static bool test_lsa_over_netlogon(struct torture_context *tctx, anon_creds = cli_credentials_init_anon(tctx); torture_assert(tctx, anon_creds != NULL, "cli_credentials_init_anon failed"); - binding2 = p->binding; + binding2 = dcerpc_binding_handle_get_binding(p->binding_handle); status = dcerpc_secondary_auth_connection(p, binding2, &ndr_table_lsarpc, anon_creds, tctx->lp_ctx, diff --git a/source4/torture/rpc/spoolss.c b/source4/torture/rpc/spoolss.c index 54b4e8cfb7d8..d3cec7f7e258 100644 --- a/source4/torture/rpc/spoolss.c +++ b/source4/torture/rpc/spoolss.c @@ -6512,7 +6512,7 @@ static bool test_SecondaryClosePrinter(struct torture_context *tctx, anon_creds = cli_credentials_init_anon(tctx); torture_assert(tctx, anon_creds != NULL, "cli_credentials_init_anon failed"); - binding2 = p->binding; + binding2 = dcerpc_binding_handle_get_binding(p->binding_handle); status = dcerpc_secondary_auth_connection(p, binding2, &ndr_table_spoolss, anon_creds, tctx->lp_ctx, tctx, &p2); diff --git a/source4/torture/rpc/winreg.c b/source4/torture/rpc/winreg.c index b0e153f5285b..369a3bd640f5 100644 --- a/source4/torture/rpc/winreg.c +++ b/source4/torture/rpc/winreg.c @@ -234,6 +234,8 @@ static bool _test_GetKeySecurity(struct dcerpc_pipe *p, uint32_t sec_info; DATA_BLOB sdblob; struct dcerpc_binding_handle *b = p->binding_handle; + const struct dcerpc_binding *binding = dcerpc_binding_handle_get_binding(b); + uint16_t flags = dcerpc_binding_get_flags(binding); if (sec_info_ptr) { sec_info = *sec_info_ptr; @@ -265,7 +267,7 @@ static bool _test_GetKeySecurity(struct dcerpc_pipe *p, (ndr_pull_flags_fn_t)ndr_pull_security_descriptor), "pull_security_descriptor failed"); - if (p->conn->flags & DCERPC_DEBUG_PRINT_OUT) { + if (flags & DCERPC_DEBUG_PRINT_OUT) { NDR_PRINT_DEBUG(security_descriptor, sd); } @@ -298,10 +300,12 @@ static bool _test_SetKeySecurity(struct dcerpc_pipe *p, DATA_BLOB sdblob; uint32_t sec_info; struct dcerpc_binding_handle *b = p->binding_handle; + const struct dcerpc_binding *binding = dcerpc_binding_handle_get_binding(b); + uint16_t flags = dcerpc_binding_get_flags(binding); ZERO_STRUCT(r); - if (sd && (p->conn->flags & DCERPC_DEBUG_PRINT_OUT)) { + if (sd && (flags & DCERPC_DEBUG_PRINT_OUT)) { NDR_PRINT_DEBUG(security_descriptor, sd); } -- 2.49.0 From b2900baf329d61a9cc16015f96c8830d6a14d0b5 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 18 Sep 2024 23:27:17 +0200 Subject: [PATCH 49/80] s4:tortore/rpc: make use of dcerpc_binding_get_abstract_syntax() and dcerpc_binding_get_flags() We should not use p->syntax nor p->transfer_syntax... Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 1713ad96a42e9245697a29d4899924cfbf636fc5) --- source4/torture/rpc/alter_context.c | 36 +++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/source4/torture/rpc/alter_context.c b/source4/torture/rpc/alter_context.c index 9b697279c858..ef2e3efc3348 100644 --- a/source4/torture/rpc/alter_context.c +++ b/source4/torture/rpc/alter_context.c @@ -30,14 +30,31 @@ bool torture_rpc_alter_context(struct torture_context *torture) struct dcerpc_pipe *p, *p2, *p3; struct policy_handle *handle; struct ndr_interface_table tmptbl; + const struct dcerpc_binding *bd = NULL; + const struct dcerpc_binding *bd2 = NULL; + struct ndr_syntax_id syntax = { .if_version = 0, }; + struct ndr_syntax_id syntax2 = { .if_version = 0, }; + const struct ndr_syntax_id *transfer_syntax = NULL; + const struct ndr_syntax_id *transfer_syntax2 = NULL; + uint32_t flags = 0; + uint32_t flags2 = 0; bool ret = true; torture_comment(torture, "opening LSA connection\n"); status = torture_rpc_connection(torture, &p, &ndr_table_lsarpc); torture_assert_ntstatus_ok(torture, status, "connecting"); + bd = dcerpc_binding_handle_get_binding(p->binding_handle); + syntax = dcerpc_binding_get_abstract_syntax(bd); + flags = dcerpc_binding_get_flags(bd); + if (flags & DCERPC_NDR64) { + transfer_syntax = &ndr_transfer_syntax_ndr64; + } else { + transfer_syntax = &ndr_transfer_syntax_ndr; + } + torture_comment(torture, "Testing change of primary context\n"); - status = dcerpc_alter_context(p, torture, &p->syntax, &p->transfer_syntax); + status = dcerpc_alter_context(p, torture, &syntax, transfer_syntax); torture_assert_ntstatus_ok(torture, status, "dcerpc_alter_context failed"); if (!test_lsa_OpenPolicy2(p->binding_handle, torture, &handle)) { @@ -45,15 +62,24 @@ bool torture_rpc_alter_context(struct torture_context *torture) } torture_comment(torture, "Testing change of primary context\n"); - status = dcerpc_alter_context(p, torture, &p->syntax, &p->transfer_syntax); + status = dcerpc_alter_context(p, torture, &syntax, transfer_syntax); torture_assert_ntstatus_ok(torture, status, "dcerpc_alter_context failed"); torture_comment(torture, "Opening secondary DSSETUP context\n"); status = dcerpc_secondary_context(p, &p2, &ndr_table_dssetup); torture_assert_ntstatus_ok(torture, status, "dcerpc_alter_context failed"); + bd2 = dcerpc_binding_handle_get_binding(p2->binding_handle); + syntax2 = dcerpc_binding_get_abstract_syntax(bd2); + flags2 = dcerpc_binding_get_flags(bd2); + if (flags2 & DCERPC_NDR64) { + transfer_syntax2 = &ndr_transfer_syntax_ndr64; + } else { + transfer_syntax2 = &ndr_transfer_syntax_ndr; + } + torture_comment(torture, "Testing change of primary context\n"); - status = dcerpc_alter_context(p2, torture, &p2->syntax, &p2->transfer_syntax); + status = dcerpc_alter_context(p2, torture, &syntax2, transfer_syntax2); torture_assert_ntstatus_ok(torture, status, "dcerpc_alter_context failed"); tmptbl = ndr_table_dssetup; @@ -71,7 +97,7 @@ bool torture_rpc_alter_context(struct torture_context *torture) } torture_comment(torture, "Testing change of primary context\n"); - status = dcerpc_alter_context(p, torture, &p->syntax, &p->transfer_syntax); + status = dcerpc_alter_context(p, torture, &syntax, transfer_syntax); torture_assert_ntstatus_ok(torture, status, "dcerpc_alter_context failed"); ret &= test_lsa_OpenPolicy2(p->binding_handle, torture, &handle); @@ -81,7 +107,7 @@ bool torture_rpc_alter_context(struct torture_context *torture) } torture_comment(torture, "Testing change of primary context\n"); - status = dcerpc_alter_context(p, torture, &p2->syntax, &p2->transfer_syntax); + status = dcerpc_alter_context(p, torture, &syntax2, transfer_syntax2); if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) { ret &= test_lsa_OpenPolicy2_ex(p->binding_handle, torture, &handle, -- 2.49.0 From 71a5534b4292360e3264777a21948e0475e9671a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 17 Sep 2024 22:41:16 +0200 Subject: [PATCH 50/80] s4:torture/rpc: make use of dcerpc_binding_handle_get_transport() Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 382ece66063bd8ef465e989857394e6f412df6d3) --- source4/torture/rpc/lsa.c | 13 +++++++------ source4/torture/rpc/lsa_lookup.c | 5 +++-- source4/torture/rpc/netlogon.c | 4 ++-- source4/torture/rpc/samr.c | 2 +- source4/torture/rpc/spoolss.c | 2 +- 5 files changed, 14 insertions(+), 12 deletions(-) diff --git a/source4/torture/rpc/lsa.c b/source4/torture/rpc/lsa.c index 13d542569449..5bf1d3ea8d42 100644 --- a/source4/torture/rpc/lsa.c +++ b/source4/torture/rpc/lsa.c @@ -1145,7 +1145,8 @@ bool test_many_LookupSids(struct dcerpc_pipe *p, struct lsa_SidArray sids; int i; struct dcerpc_binding_handle *b = p->binding_handle; - enum dcerpc_transport_t transport = dcerpc_binding_get_transport(p->binding); + enum dcerpc_transport_t transport = + dcerpc_binding_handle_get_transport(b); torture_comment(tctx, "\nTesting LookupSids with lots of SIDs\n"); @@ -5316,7 +5317,7 @@ bool torture_rpc_lsa(struct torture_context *tctx) torture_assert_ntstatus_ok(tctx, status, "Error connecting to server"); b = p->binding_handle; - transport = dcerpc_binding_get_transport(p->binding); + transport = dcerpc_binding_handle_get_transport(b); /* Test lsaLookupSids3 and lsaLookupNames4 over tcpip */ if (transport == NCACN_IP_TCP) { @@ -5416,7 +5417,7 @@ bool torture_rpc_lsa_get_user(struct torture_context *tctx) torture_assert_ntstatus_ok(tctx, status, "Error connecting to server"); b = p->binding_handle; - transport = dcerpc_binding_get_transport(p->binding); + transport = dcerpc_binding_handle_get_transport(b); if (transport == NCACN_IP_TCP) { if (!test_GetUserName_fail(b, tctx)) { @@ -5440,7 +5441,7 @@ static bool testcase_LookupNames(struct torture_context *tctx, struct lsa_TransNameArray tnames; struct lsa_TransNameArray2 tnames2; struct dcerpc_binding_handle *b = p->binding_handle; - enum dcerpc_transport_t transport = dcerpc_binding_get_transport(p->binding); + enum dcerpc_transport_t transport = dcerpc_binding_handle_get_transport(b); if (transport != NCACN_NP && transport != NCALRPC) { torture_comment(tctx, "testcase_LookupNames is only available " @@ -5531,7 +5532,7 @@ static bool testcase_TrustedDomains(struct torture_context *tctx, struct lsa_trustdom_state *state = talloc_get_type_abort(data, struct lsa_trustdom_state); struct dcerpc_binding_handle *b = p->binding_handle; - enum dcerpc_transport_t transport = dcerpc_binding_get_transport(p->binding); + enum dcerpc_transport_t transport = dcerpc_binding_handle_get_transport(b); if (transport != NCACN_NP && transport != NCALRPC) { torture_comment(tctx, "testcase_TrustedDomains is only available " @@ -5606,7 +5607,7 @@ static bool testcase_Privileges(struct torture_context *tctx, { struct policy_handle *handle; struct dcerpc_binding_handle *b = p->binding_handle; - enum dcerpc_transport_t transport = dcerpc_binding_get_transport(p->binding); + enum dcerpc_transport_t transport = dcerpc_binding_handle_get_transport(b); if (transport != NCACN_NP && transport != NCALRPC) { torture_skip(tctx, "testcase_Privileges is only available " diff --git a/source4/torture/rpc/lsa_lookup.c b/source4/torture/rpc/lsa_lookup.c index f641827e6dcd..51e032f3fba1 100644 --- a/source4/torture/rpc/lsa_lookup.c +++ b/source4/torture/rpc/lsa_lookup.c @@ -228,7 +228,7 @@ bool torture_rpc_lsa_lookup(struct torture_context *torture) torture_fail(torture, "unable to connect to table"); } b = p->binding_handle; - transport = dcerpc_binding_get_transport(p->binding); + transport = dcerpc_binding_handle_get_transport(b); if (transport != NCACN_NP && transport != NCALRPC) { torture_comment(torture, @@ -344,7 +344,8 @@ static bool test_LookupSidsReply(struct torture_context *tctx, const char *dom_sid = "S-1-5-21-1111111111-2222222222-3333333333"; const char *dom_admin_sid; struct dcerpc_binding_handle *b = p->binding_handle; - enum dcerpc_transport_t transport = dcerpc_binding_get_transport(p->binding); + enum dcerpc_transport_t transport = + dcerpc_binding_handle_get_transport(b); ZERO_STRUCT(r); ZERO_STRUCT(sidarray); diff --git a/source4/torture/rpc/netlogon.c b/source4/torture/rpc/netlogon.c index 20b2b2adb82d..9aa6f2700130 100644 --- a/source4/torture/rpc/netlogon.c +++ b/source4/torture/rpc/netlogon.c @@ -5827,7 +5827,7 @@ static bool test_ManyGetDCName(struct torture_context *tctx, int i; - if (p->conn->transport.transport != NCACN_NP) { + if (dcerpc_binding_handle_get_transport(b) != NCACN_NP) { torture_skip(tctx, "test_ManyGetDCName works only with NCACN_NP"); } @@ -5919,7 +5919,7 @@ static bool test_lsa_over_netlogon(struct torture_context *tctx, struct dcerpc_binding_handle *b2; - if (p->conn->transport.transport != NCACN_NP) { + if (dcerpc_binding_handle_get_transport(p->binding_handle) != NCACN_NP) { torture_skip(tctx, "test_lsa_over_netlogon works only with NCACN_NP"); } diff --git a/source4/torture/rpc/samr.c b/source4/torture/rpc/samr.c index 2d3788e05b5c..981196a81239 100644 --- a/source4/torture/rpc/samr.c +++ b/source4/torture/rpc/samr.c @@ -9034,7 +9034,7 @@ static bool test_samr_ValidatePassword(struct torture_context *tctx, torture_comment(tctx, "Testing samr_ValidatePassword\n"); - if (p->conn->transport.transport != NCACN_IP_TCP) { + if (dcerpc_binding_handle_get_transport(b) != NCACN_IP_TCP) { torture_comment(tctx, "samr_ValidatePassword only should succeed over NCACN_IP_TCP!\n"); } diff --git a/source4/torture/rpc/spoolss.c b/source4/torture/rpc/spoolss.c index d3cec7f7e258..d2b7a244c113 100644 --- a/source4/torture/rpc/spoolss.c +++ b/source4/torture/rpc/spoolss.c @@ -6503,7 +6503,7 @@ static bool test_SecondaryClosePrinter(struct torture_context *tctx, struct spoolss_ClosePrinter cp; /* only makes sense on SMB */ - if (p->conn->transport.transport != NCACN_NP) { + if (dcerpc_binding_handle_get_transport(p->binding_handle) != NCACN_NP) { return true; } -- 2.49.0 From 525ab7473cef63bb9598bb99f1c83cfb4436ae16 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 18 Sep 2024 23:35:20 +0200 Subject: [PATCH 51/80] s4:librpc: make all but dcerpc_pipe->binding_handle internal struct members We could use a dcerpc_internal.h for struct dcecli_security and struct dcecli_connection, but in struct dcerpc_pipe we still expose binding_handle and changing that would require way too much work for now... Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 353af4b70559be1665df345655af43a61177c710) --- source4/librpc/rpc/dcerpc.c | 2 ++ source4/librpc/rpc/dcerpc.h | 19 +++++++++++++++++++ source4/librpc/rpc/dcerpc_auth.c | 2 ++ source4/librpc/rpc/dcerpc_connect.c | 1 + source4/librpc/rpc/dcerpc_roh.c | 2 ++ source4/librpc/rpc/dcerpc_schannel.c | 2 ++ source4/librpc/rpc/dcerpc_secondary.c | 1 + source4/librpc/rpc/dcerpc_smb.c | 2 ++ source4/librpc/rpc/dcerpc_sock.c | 2 ++ source4/librpc/rpc/dcerpc_util.c | 2 ++ source4/librpc/rpc/pyrpc.c | 2 ++ source4/librpc/rpc/pyrpc_util.c | 2 ++ source4/rpc_server/remote/dcesrv_remote.c | 2 ++ 13 files changed, 41 insertions(+) diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index feacdcb2f591..2224186aee23 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -20,6 +20,8 @@ along with this program. If not, see . */ +#define SOURCE4_LIBRPC_INTERNALS 1 + #include "includes.h" #include "lib/util/util_file.h" #include "system/filesys.h" diff --git a/source4/librpc/rpc/dcerpc.h b/source4/librpc/rpc/dcerpc.h index dab66501b924..5b14f7b79ce8 100644 --- a/source4/librpc/rpc/dcerpc.h +++ b/source4/librpc/rpc/dcerpc.h @@ -32,6 +32,14 @@ #include "../librpc/ndr/libndr.h" #include "../librpc/rpc/rpc_common.h" +#ifdef SOURCE4_LIBRPC_INTERNALS +#define SOURCE4_LIBRPC_INTERNALS_BEGIN +#define SOURCE4_LIBRPC_INTERNALS_END +#else /* SOURCE4_LIBRPC_INTERNALS */ +#define SOURCE4_LIBRPC_INTERNALS_BEGIN struct { +#define SOURCE4_LIBRPC_INTERNALS_END } internal; +#endif /* not SOURCE4_LIBRPC_INTERNALS */ + struct tevent_context; struct tevent_req; struct dcerpc_binding_handle; @@ -46,6 +54,8 @@ struct dcecli_connection; struct gensec_settings; struct cli_credentials; struct dcecli_security { + SOURCE4_LIBRPC_INTERNALS_BEGIN + enum dcerpc_AuthType auth_type; enum dcerpc_AuthLevel auth_level; uint32_t auth_context_id; @@ -61,6 +71,7 @@ struct dcecli_security { bool verified_bitmask1; + SOURCE4_LIBRPC_INTERNALS_END }; /* @@ -68,6 +79,8 @@ struct dcecli_security { */ struct rpc_request; struct dcecli_connection { + SOURCE4_LIBRPC_INTERNALS_BEGIN + uint32_t call_id; uint32_t srv_max_xmit_frag; uint32_t srv_max_recv_frag; @@ -114,6 +127,8 @@ struct dcecli_connection { /* the negotiated bind time features */ uint16_t bind_time_features; + + SOURCE4_LIBRPC_INTERNALS_END }; /* @@ -122,6 +137,8 @@ struct dcecli_connection { struct dcerpc_pipe { struct dcerpc_binding_handle *binding_handle; + SOURCE4_LIBRPC_INTERNALS_BEGIN + uint32_t context_id; struct GUID object; @@ -146,6 +163,8 @@ struct dcerpc_pipe { bool timed_out; bool verified_pcontext; + + SOURCE4_LIBRPC_INTERNALS_END }; /* default timeout for all rpc requests, in seconds */ diff --git a/source4/librpc/rpc/dcerpc_auth.c b/source4/librpc/rpc/dcerpc_auth.c index 7f84bdf38a3b..e8e48cef23cf 100644 --- a/source4/librpc/rpc/dcerpc_auth.c +++ b/source4/librpc/rpc/dcerpc_auth.c @@ -21,6 +21,8 @@ along with this program. If not, see . */ +#define SOURCE4_LIBRPC_INTERNALS 1 + #include "includes.h" #include #include "libcli/composite/composite.h" diff --git a/source4/librpc/rpc/dcerpc_connect.c b/source4/librpc/rpc/dcerpc_connect.c index 69183a22875a..7745b699a62a 100644 --- a/source4/librpc/rpc/dcerpc_connect.c +++ b/source4/librpc/rpc/dcerpc_connect.c @@ -22,6 +22,7 @@ along with this program. If not, see . */ +#define SOURCE4_LIBRPC_INTERNALS 1 #include "includes.h" #include "libcli/composite/composite.h" diff --git a/source4/librpc/rpc/dcerpc_roh.c b/source4/librpc/rpc/dcerpc_roh.c index 82ed5315805d..c2fc5293ce7d 100644 --- a/source4/librpc/rpc/dcerpc_roh.c +++ b/source4/librpc/rpc/dcerpc_roh.c @@ -19,6 +19,8 @@ along with this program. If not, see . */ +#define SOURCE4_LIBRPC_INTERNALS 1 + #include "includes.h" #include "lib/events/events.h" #include "lib/util/tevent_ntstatus.h" diff --git a/source4/librpc/rpc/dcerpc_schannel.c b/source4/librpc/rpc/dcerpc_schannel.c index 8622791fe302..033b964233ca 100644 --- a/source4/librpc/rpc/dcerpc_schannel.c +++ b/source4/librpc/rpc/dcerpc_schannel.c @@ -21,6 +21,8 @@ along with this program. If not, see . */ +#define SOURCE4_LIBRPC_INTERNALS 1 + #include "includes.h" #include #include "auth/auth.h" diff --git a/source4/librpc/rpc/dcerpc_secondary.c b/source4/librpc/rpc/dcerpc_secondary.c index 55068dc10724..7a4c254d5894 100644 --- a/source4/librpc/rpc/dcerpc_secondary.c +++ b/source4/librpc/rpc/dcerpc_secondary.c @@ -22,6 +22,7 @@ along with this program. If not, see . */ +#define SOURCE4_LIBRPC_INTERNALS 1 #include "includes.h" #include "libcli/composite/composite.h" diff --git a/source4/librpc/rpc/dcerpc_smb.c b/source4/librpc/rpc/dcerpc_smb.c index 259de719928f..26fd2b0789f0 100644 --- a/source4/librpc/rpc/dcerpc_smb.c +++ b/source4/librpc/rpc/dcerpc_smb.c @@ -20,6 +20,8 @@ along with this program. If not, see . */ +#define SOURCE4_LIBRPC_INTERNALS 1 + #include "includes.h" #include "system/filesys.h" #include diff --git a/source4/librpc/rpc/dcerpc_sock.c b/source4/librpc/rpc/dcerpc_sock.c index ec5a5ca8f8ef..24eb17ed3b31 100644 --- a/source4/librpc/rpc/dcerpc_sock.c +++ b/source4/librpc/rpc/dcerpc_sock.c @@ -21,6 +21,8 @@ along with this program. If not, see . */ +#define SOURCE4_LIBRPC_INTERNALS 1 + #include "includes.h" #include "system/filesys.h" #include "lib/events/events.h" diff --git a/source4/librpc/rpc/dcerpc_util.c b/source4/librpc/rpc/dcerpc_util.c index f40b872ab407..d0a163500fe4 100644 --- a/source4/librpc/rpc/dcerpc_util.c +++ b/source4/librpc/rpc/dcerpc_util.c @@ -22,6 +22,8 @@ along with this program. If not, see . */ +#define SOURCE4_LIBRPC_INTERNALS 1 + #include "includes.h" #include "lib/events/events.h" #include "libcli/composite/composite.h" diff --git a/source4/librpc/rpc/pyrpc.c b/source4/librpc/rpc/pyrpc.c index 4f7f4cd1d964..5ea829b80fb1 100644 --- a/source4/librpc/rpc/pyrpc.c +++ b/source4/librpc/rpc/pyrpc.c @@ -17,6 +17,8 @@ along with this program. If not, see . */ +#define SOURCE4_LIBRPC_INTERNALS 1 + #include "lib/replace/system/python.h" #include "python/py3compat.h" #include "includes.h" diff --git a/source4/librpc/rpc/pyrpc_util.c b/source4/librpc/rpc/pyrpc_util.c index a0910b4f802d..e8de2f39eaeb 100644 --- a/source4/librpc/rpc/pyrpc_util.c +++ b/source4/librpc/rpc/pyrpc_util.c @@ -20,6 +20,8 @@ along with this program. If not, see . */ +#define SOURCE4_LIBRPC_INTERNALS 1 + #include "lib/replace/system/python.h" #include "python/py3compat.h" #include "includes.h" diff --git a/source4/rpc_server/remote/dcesrv_remote.c b/source4/rpc_server/remote/dcesrv_remote.c index 08927521a1ea..2500694f9d59 100644 --- a/source4/rpc_server/remote/dcesrv_remote.c +++ b/source4/rpc_server/remote/dcesrv_remote.c @@ -20,6 +20,8 @@ along with this program. If not, see . */ +#define SOURCE4_LIBRPC_INTERNALS 1 + #include "includes.h" #include #include "rpc_server/dcerpc_server.h" -- 2.49.0 From 0d521371b6e8a62c8ded8b65d741dd96d6f61101 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 19 Sep 2024 06:27:22 +0200 Subject: [PATCH 52/80] s3:rpc_client: remember rpc_pipe_client->print_username This is ugly, but it's less ugly than doing it deep inside of cli_spoolss.c and other code. Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 344e45507e122137c357fc177bb024f09fff8b01) --- source3/rpc_client/cli_pipe.c | 9 +++++++++ source3/rpc_client/cli_spoolss.c | 6 ++---- source3/rpc_client/rpc_client.h | 1 + source3/rpcclient/cmd_iremotewinspool.c | 3 +-- source3/utils/net_rpc_printer.c | 3 +-- 5 files changed, 14 insertions(+), 8 deletions(-) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 9e9b9fe38b2c..44e84dc62307 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1807,6 +1807,8 @@ struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx, { struct tevent_req *req, *subreq; struct rpc_pipe_bind_state *state; + struct cli_credentials *creds = NULL; + const char *username = NULL; NTSTATUS status; req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state); @@ -1827,6 +1829,13 @@ struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx, cli->auth = talloc_move(cli, &auth); + creds = gensec_get_credentials(cli->auth->auth_ctx); + username = cli_credentials_get_username(creds); + cli->printer_username = talloc_strdup(cli, username); + if (tevent_req_nomem(cli->printer_username, req)) { + return tevent_req_post(req, ev); + } + /* Marshall the outgoing data. */ status = create_rpc_bind_req(state, cli, cli->auth, diff --git a/source3/rpc_client/cli_spoolss.c b/source3/rpc_client/cli_spoolss.c index 094381c4fbaa..62747d8c6400 100644 --- a/source3/rpc_client/cli_spoolss.c +++ b/source3/rpc_client/cli_spoolss.c @@ -46,12 +46,11 @@ WERROR rpccli_spoolss_openprinter_ex(struct rpc_pipe_client *cli, struct spoolss_UserLevelCtr userlevel_ctr; struct spoolss_UserLevel1 level1; struct dcerpc_binding_handle *b = cli->binding_handle; - struct cli_credentials *creds = gensec_get_credentials(cli->auth->auth_ctx); ZERO_STRUCT(devmode_ctr); werror = spoolss_init_spoolss_UserLevel1(mem_ctx, - cli_credentials_get_username(creds), + cli->printer_username, &level1); if (!W_ERROR_IS_OK(werror)) { return werror; @@ -223,13 +222,12 @@ WERROR rpccli_spoolss_addprinterex(struct rpc_pipe_client *cli, struct spoolss_UserLevel1 level1; struct policy_handle handle; struct dcerpc_binding_handle *b = cli->binding_handle; - struct cli_credentials *creds = gensec_get_credentials(cli->auth->auth_ctx); ZERO_STRUCT(devmode_ctr); ZERO_STRUCT(secdesc_ctr); result = spoolss_init_spoolss_UserLevel1(mem_ctx, - cli_credentials_get_username(creds), + cli->printer_username, &level1); if (!W_ERROR_IS_OK(result)) { return result; diff --git a/source3/rpc_client/rpc_client.h b/source3/rpc_client/rpc_client.h index b2f02b01b3d4..b1c3db524519 100644 --- a/source3/rpc_client/rpc_client.h +++ b/source3/rpc_client/rpc_client.h @@ -55,6 +55,7 @@ struct rpc_pipe_client { struct ndr_syntax_id transfer_syntax; bool verified_pcontext; + char *printer_username; char *desthost; char *srv_name_slash; diff --git a/source3/rpcclient/cmd_iremotewinspool.c b/source3/rpcclient/cmd_iremotewinspool.c index 5a8096b6d97c..7162605696f0 100644 --- a/source3/rpcclient/cmd_iremotewinspool.c +++ b/source3/rpcclient/cmd_iremotewinspool.c @@ -43,7 +43,6 @@ static WERROR cmd_iremotewinspool_async_open_printer(struct rpc_pipe_client *cli struct dcerpc_binding_handle *b = cli->binding_handle; struct GUID uuid; struct winspool_AsyncOpenPrinter r; - struct cli_credentials *creds = gensec_get_credentials(cli->auth->auth_ctx); if (argc < 2) { printf("Usage: %s [access_mask]\n", argv[0]); @@ -62,7 +61,7 @@ static WERROR cmd_iremotewinspool_async_open_printer(struct rpc_pipe_client *cli ZERO_STRUCT(devmode_ctr); werror = spoolss_init_spoolss_UserLevel1(mem_ctx, - cli_credentials_get_username(creds), + cli->printer_username, &level1); if (!W_ERROR_IS_OK(werror)) { return werror; diff --git a/source3/utils/net_rpc_printer.c b/source3/utils/net_rpc_printer.c index f72203f688f3..5434c5628f5e 100644 --- a/source3/utils/net_rpc_printer.c +++ b/source3/utils/net_rpc_printer.c @@ -704,8 +704,7 @@ static bool net_spoolss_open_printer_ex(struct rpc_pipe_client *pipe_hnd, uint32_t access_required, struct policy_handle *hnd) { - struct cli_credentials *creds = gensec_get_credentials(pipe_hnd->auth->auth_ctx); - const char *username = cli_credentials_get_username(creds); + const char *username = pipe_hnd->printer_username; WERROR result; fstring printername2; -- 2.49.0 From 5db7d2e81141e27bd1ce353cfb50fb8972703dd7 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 19 Sep 2024 09:12:10 +0200 Subject: [PATCH 53/80] s3:rpc_client: remove references to rpc_pipe_client from wsp_cli.c Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit dc6d3c96c33797163ac578675b255872deca9b98) --- source3/rpc_client/wsp_cli.c | 71 +++++++++++++++++++++++------------- 1 file changed, 45 insertions(+), 26 deletions(-) diff --git a/source3/rpc_client/wsp_cli.c b/source3/rpc_client/wsp_cli.c index 15b6e36007ef..992b1a83b2ba 100644 --- a/source3/rpc_client/wsp_cli.c +++ b/source3/rpc_client/wsp_cli.c @@ -1807,8 +1807,6 @@ enum search_kind get_kind(const char* kind_str) struct wsp_client_ctx { - struct rpc_pipe_client *rpccli; - struct cli_state *cli_state; struct dcerpc_binding_handle *h; }; @@ -1832,6 +1830,33 @@ static NTSTATUS wsp_resp_pdu_complete(struct tstream_context *stream, return NT_STATUS_OK; } +static NTSTATUS wsp_rpc_transport_np_connect(struct cli_state *cli, + const struct ndr_interface_table *table, + TALLOC_CTX *mem_ctx, + struct rpc_cli_transport **presult) +{ + struct tevent_context *ev = NULL; + struct tevent_req *req = NULL; + NTSTATUS status = NT_STATUS_NO_MEMORY; + + ev = samba_tevent_context_init(mem_ctx); + if (ev == NULL) { + goto fail; + } + req = rpc_transport_np_init_send(ev, ev, cli, table); + if (req == NULL) { + goto fail; + } + if (!tevent_req_poll_ntstatus(req, ev, &status)) { + goto fail; + } + status = rpc_transport_np_init_recv(req, mem_ctx, presult); +fail: + TALLOC_FREE(req); + TALLOC_FREE(ev); + return status; +} + NTSTATUS wsp_server_connect(TALLOC_CTX *mem_ctx, const char *servername, struct tevent_context *ev_ctx, @@ -1841,7 +1866,7 @@ NTSTATUS wsp_server_connect(TALLOC_CTX *mem_ctx, struct wsp_client_ctx **wsp_ctx) { struct wsp_client_ctx *ctx = NULL; - struct dcerpc_binding_handle *h = NULL; + struct rpc_cli_transport *transport = NULL; struct tstream_context *stream = NULL; NTSTATUS status; @@ -1857,9 +1882,6 @@ NTSTATUS wsp_server_connect(TALLOC_CTX *mem_ctx, return NT_STATUS_NO_MEMORY; } - ctx->cli_state = cli; - - status = smb2cli_ioctl_pipe_wait( cli->conn, cli->timeout, @@ -1867,49 +1889,47 @@ NTSTATUS wsp_server_connect(TALLOC_CTX *mem_ctx, cli->smb2.tcon, "MsFteWds", 1); - - if (!NT_STATUS_IS_OK(status)) { DBG_ERR("wait for pipe failed: %s)\n", nt_errstr(status)); + TALLOC_FREE(ctx); return status; } - status = rpc_pipe_open_np(cli, + status = wsp_rpc_transport_np_connect(cli, &ndr_table_msftewds, - &ctx->rpccli); - + cli, + &transport); if (!NT_STATUS_IS_OK(status)) { DBG_ERR("failed to int the pipe)\n"); + TALLOC_FREE(ctx); return status; } - stream = rpc_transport_get_tstream(ctx->rpccli->transport); - h = tstream_binding_handle_create(ctx->rpccli, - NULL, - &stream, - MSG_HDR_SIZE, - wsp_resp_pdu_complete, - ctx, 42280); - - if (!h) { + stream = rpc_transport_get_tstream(transport); + ctx->h = tstream_binding_handle_create(ctx, + NULL, + &stream, + MSG_HDR_SIZE, + wsp_resp_pdu_complete, + ctx, 42280); + if (ctx->h == NULL) { DBG_ERR("failed to create the pipe handle)\n"); + TALLOC_FREE(ctx); return NT_STATUS_UNSUCCESSFUL; } - ctx->rpccli->binding_handle = h; *wsp_ctx = ctx; return status; } static NTSTATUS write_something(TALLOC_CTX* ctx, - struct rpc_pipe_client *p, + struct dcerpc_binding_handle *handle, DATA_BLOB *blob_in, DATA_BLOB *blob_out) { uint32_t outflags; - struct dcerpc_binding_handle *handle = p->binding_handle; NTSTATUS status; status = dcerpc_binding_handle_raw_call(handle, @@ -2037,7 +2057,6 @@ NTSTATUS wsp_request_response(TALLOC_CTX* ctx, struct wsp_response *response, DATA_BLOB *unread) { - struct rpc_pipe_client *p = wsp_ctx->rpccli; NTSTATUS status = NT_STATUS_OK; ndr_flags_type ndr_flags = NDR_SCALARS | NDR_BUFFERS; @@ -2186,7 +2205,7 @@ NTSTATUS wsp_request_response(TALLOC_CTX* ctx, dump_data(5, req_blob.data, req_blob.length); - status = write_something(ctx, p, &req_blob, &resp_blob); + status = write_something(ctx, wsp_ctx->h, &req_blob, &resp_blob); if (!NT_STATUS_IS_OK(status)) { DBG_ERR("Failed to write message\n"); @@ -2217,5 +2236,5 @@ NTSTATUS wsp_request_response(TALLOC_CTX* ctx, struct dcerpc_binding_handle* get_wsp_pipe(struct wsp_client_ctx *ctx) { - return ctx->rpccli->binding_handle; + return ctx->h; } -- 2.49.0 From 0ce5a2fedda0939fa93db5bbd0eb4c669713c545 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 19 Sep 2024 09:13:03 +0200 Subject: [PATCH 54/80] s3:winbindd: make use of dcerpc_binding_handle_get_transport() Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 504906e60f9a09518202397f0aa0782242dbe3bb) --- source3/winbindd/winbindd_msrpc.c | 4 ++-- source3/winbindd/winbindd_rpc.c | 7 +++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/source3/winbindd/winbindd_msrpc.c b/source3/winbindd/winbindd_msrpc.c index 0c849c04e193..9324633aa144 100644 --- a/source3/winbindd/winbindd_msrpc.c +++ b/source3/winbindd/winbindd_msrpc.c @@ -981,7 +981,7 @@ NTSTATUS winbindd_lookup_sids(TALLOC_CTX *mem_ctx, b = cli->binding_handle; - if (cli->transport->transport == NCACN_IP_TCP) { + if (dcerpc_binding_handle_get_transport(b) == NCACN_IP_TCP) { use_lookupsids3 = true; } @@ -1063,7 +1063,7 @@ static NTSTATUS winbindd_lookup_names(TALLOC_CTX *mem_ctx, b = cli->binding_handle; - if (cli->transport->transport == NCACN_IP_TCP) { + if (dcerpc_binding_handle_get_transport(b) == NCACN_IP_TCP) { use_lookupnames4 = true; } diff --git a/source3/winbindd/winbindd_rpc.c b/source3/winbindd/winbindd_rpc.c index ef015b2fbf25..a609fdd202d6 100644 --- a/source3/winbindd/winbindd_rpc.c +++ b/source3/winbindd/winbindd_rpc.c @@ -809,6 +809,7 @@ NTSTATUS rpc_lookup_sids(TALLOC_CTX *mem_ctx, { struct lsa_TransNameArray *names = *pnames; struct rpc_pipe_client *cli = NULL; + struct dcerpc_binding_handle *b = NULL; struct policy_handle lsa_policy; uint32_t count; uint32_t i; @@ -819,12 +820,14 @@ NTSTATUS rpc_lookup_sids(TALLOC_CTX *mem_ctx, return status; } - if (cli->transport->transport == NCACN_IP_TCP) { + b = cli->binding_handle; + + if (dcerpc_binding_handle_get_transport(b) == NCACN_IP_TCP) { return rpc_try_lookup_sids3(mem_ctx, domain, cli, sids, pdomains, pnames); } - status = dcerpc_lsa_LookupSids(cli->binding_handle, mem_ctx, + status = dcerpc_lsa_LookupSids(b, mem_ctx, &lsa_policy, sids, pdomains, names, LSA_LOOKUP_NAMES_ALL, &count, &result); -- 2.49.0 From 42d8b7641a971a6682108e73846205abf14a2bc7 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 19 Sep 2024 09:20:03 +0200 Subject: [PATCH 55/80] s3:rpcclient: make use of dcerpc_binding_handle_get_transport() Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit e5c09e041d1517649616d0d4b072422802a69f08) --- source3/rpcclient/rpcclient.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c index 6df33e04278c..95b6baf32b03 100644 --- a/source3/rpcclient/rpcclient.c +++ b/source3/rpcclient/rpcclient.c @@ -396,13 +396,17 @@ static NTSTATUS cmd_set_transport(struct dcerpc_binding *b) struct cmd_set *tmp_set; for (tmp_set = tmp->cmd_set; tmp_set->name; tmp_set++) { + struct dcerpc_binding_handle *tmp_b = NULL; + enum dcerpc_transport_t tmp_t; + if (tmp_set->rpc_pipe == NULL) { continue; } - if (tmp_set->rpc_pipe->transport->transport != t) { + tmp_b = tmp_set->rpc_pipe->binding_handle; + tmp_t = dcerpc_binding_handle_get_transport(tmp_b); + if (tmp_t != t) { TALLOC_FREE(tmp_set->rpc_pipe); - tmp_set->rpc_pipe = NULL; } } } -- 2.49.0 From fb61d6b189fe1a7314e627ff8a108bb9ee3608f2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 19 Sep 2024 09:39:44 +0200 Subject: [PATCH 56/80] s3:lib/netapi: make use of dcerpc_binding_get_abstract_syntax() Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit fe94230f7ebedfdcc5f087b442ee91d9c44b734f) --- source3/lib/netapi/cm.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/source3/lib/netapi/cm.c b/source3/lib/netapi/cm.c index c54f955d617d..da63fd921e92 100644 --- a/source3/lib/netapi/cm.c +++ b/source3/lib/netapi/cm.c @@ -163,7 +163,10 @@ static NTSTATUS pipe_cm_find(struct client_ipc_connection *ipc, struct client_pipe_connection *p; for (p = ipc->pipe_connections; p; p = p->next) { + struct dcerpc_binding_handle *bh = NULL; + const struct dcerpc_binding *bd = NULL; const char *ipc_remote_name; + struct ndr_syntax_id syntax; if (!rpccli_is_connected(p->pipe)) { return NT_STATUS_PIPE_EMPTY; @@ -171,9 +174,15 @@ static NTSTATUS pipe_cm_find(struct client_ipc_connection *ipc, ipc_remote_name = smbXcli_conn_remote_name(ipc->cli->conn); - if (strequal(ipc_remote_name, p->pipe->desthost) - && ndr_syntax_id_equal(&p->pipe->abstract_syntax, - &table->syntax_id)) { + if (!strequal(ipc_remote_name, p->pipe->desthost)) { + continue; + } + + bh = p->pipe->binding_handle; + bd = dcerpc_binding_handle_get_binding(bh); + syntax = dcerpc_binding_get_abstract_syntax(bd); + + if (ndr_syntax_id_equal(&syntax, &table->syntax_id)) { *presult = p->pipe; return NT_STATUS_OK; } -- 2.49.0 From 5977f6afa3ff5c7dc6768ce283ef50d74767110d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 19 Sep 2024 10:32:58 +0200 Subject: [PATCH 57/80] s3:libsmb: make use of dcerpc_binding_get_abstract_syntax() Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 8d666e18f8d254124967e7ac56fc5b171963c02f) --- source3/libsmb/libsmb_xattr.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/source3/libsmb/libsmb_xattr.c b/source3/libsmb/libsmb_xattr.c index a90234193765..c91970d778fa 100644 --- a/source3/libsmb/libsmb_xattr.c +++ b/source3/libsmb/libsmb_xattr.c @@ -43,7 +43,15 @@ find_lsa_pipe_hnd(struct cli_state *ipc_cli) for (pipe_hnd = ipc_cli->pipe_list; pipe_hnd; pipe_hnd = pipe_hnd->next) { - if (ndr_syntax_id_equal(&pipe_hnd->abstract_syntax, + struct dcerpc_binding_handle *bh = NULL; + const struct dcerpc_binding *bd = NULL; + struct ndr_syntax_id syntax; + + bh = pipe_hnd->binding_handle; + bd = dcerpc_binding_handle_get_binding(bh); + syntax = dcerpc_binding_get_abstract_syntax(bd); + + if (ndr_syntax_id_equal(&syntax, &ndr_table_lsarpc.syntax_id)) { return pipe_hnd; } -- 2.49.0 From ea83abea3f1f035f2fd6f4728e45359b623a81a0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 19 Sep 2024 06:39:02 +0200 Subject: [PATCH 58/80] s3:librpc/rpc: split out dcerpc_internal.h for struct pipe_auth_data This should be anonymous for callers. Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit b874619b5ed5d29a939f13d8064a47c8aca45b8c) --- source3/librpc/rpc/dcerpc.h | 13 +---------- source3/librpc/rpc/dcerpc_helpers.c | 1 + source3/librpc/rpc/dcerpc_internal.h | 35 ++++++++++++++++++++++++++++ source3/rpc_client/cli_pipe.c | 1 + 4 files changed, 38 insertions(+), 12 deletions(-) create mode 100644 source3/librpc/rpc/dcerpc_internal.h diff --git a/source3/librpc/rpc/dcerpc.h b/source3/librpc/rpc/dcerpc.h index fdd3beda46d8..f3dc3394ff4c 100644 --- a/source3/librpc/rpc/dcerpc.h +++ b/source3/librpc/rpc/dcerpc.h @@ -32,18 +32,7 @@ struct NL_AUTH_MESSAGE; struct gensec_security; - -/* auth state for all bind types. */ - -struct pipe_auth_data { - enum dcerpc_AuthType auth_type; - enum dcerpc_AuthLevel auth_level; - uint32_t auth_context_id; - bool hdr_signing; - bool verified_bitmask1; - - struct gensec_security *auth_ctx; -}; +struct pipe_auth_data; /* The following definitions come from librpc/rpc/dcerpc_helpers.c */ NTSTATUS dcerpc_push_ncacn_packet(TALLOC_CTX *mem_ctx, diff --git a/source3/librpc/rpc/dcerpc_helpers.c b/source3/librpc/rpc/dcerpc_helpers.c index 2b99eb7aff74..5310e4a66129 100644 --- a/source3/librpc/rpc/dcerpc_helpers.c +++ b/source3/librpc/rpc/dcerpc_helpers.c @@ -20,6 +20,7 @@ #include "includes.h" #include "librpc/rpc/dcerpc.h" +#include "librpc/rpc/dcerpc_internal.h" #include "librpc/rpc/dcerpc_util.h" #include "librpc/gen_ndr/ndr_dcerpc.h" #include "librpc/crypto/gse.h" diff --git a/source3/librpc/rpc/dcerpc_internal.h b/source3/librpc/rpc/dcerpc_internal.h new file mode 100644 index 000000000000..3c026fa29473 --- /dev/null +++ b/source3/librpc/rpc/dcerpc_internal.h @@ -0,0 +1,35 @@ +/* + Unix SMB/CIFS implementation. + + DCERPC client side interface structures + + Copyright (C) 2008 Jelmer Vernooij + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef _S3_DCERPC_INTERNAL_H__ +#define _S3_DCERPC_INTERNAL_H__ + +struct pipe_auth_data { + enum dcerpc_AuthType auth_type; + enum dcerpc_AuthLevel auth_level; + uint32_t auth_context_id; + bool hdr_signing; + bool verified_bitmask1; + + struct gensec_security *auth_ctx; +}; + +#endif /* __S3_DCERPC_INTERNAL_H__ */ diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 44e84dc62307..c1b7930fe9e8 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -31,6 +31,7 @@ #include "librpc/gen_ndr/ndr_netlogon_c.h" #include "librpc/gen_ndr/auth.h" #include "librpc/rpc/dcerpc.h" +#include "librpc/rpc/dcerpc_internal.h" #include "librpc/rpc/dcerpc_util.h" #include "rpc_dce.h" #include "cli_pipe.h" -- 2.49.0 From d44966909efc618a4583d30336ba2425cbca862a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 19 Sep 2024 06:43:14 +0200 Subject: [PATCH 59/80] s3:rpc_client: make most of rpc_pipe_client internal struct members Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit ae88941c8a2e4e9c7d0deb9c39dcbb2f9fab0ebb) --- source3/rpc_client/cli_pipe.c | 2 ++ source3/rpc_client/rpc_client.h | 23 ++++++++++++++++++----- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index c1b7930fe9e8..b2588da57caf 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -19,6 +19,8 @@ * along with this program; if not, see . */ +#define SOURCE3_LIBRPC_INTERNALS 1 + #include "includes.h" #include "libsmb/namequery.h" #include "../lib/util/tevent_ntstatus.h" diff --git a/source3/rpc_client/rpc_client.h b/source3/rpc_client/rpc_client.h index b1c3db524519..84422188a498 100644 --- a/source3/rpc_client/rpc_client.h +++ b/source3/rpc_client/rpc_client.h @@ -29,14 +29,29 @@ #include "../librpc/ndr/libndr.h" #include "rpc_client/rpc_transport.h" +#ifdef SOURCE3_LIBRPC_INTERNALS +#define SOURCE3_LIBRPC_INTERNALS_BEGIN +#define SOURCE3_LIBRPC_INTERNALS_END +#else /* SOURCE3_LIBRPC_INTERNALS */ +#define SOURCE3_LIBRPC_INTERNALS_BEGIN struct { +#define SOURCE3_LIBRPC_INTERNALS_END } internal; +#endif /* not SOURCE3_LIBRPC_INTERNALS */ + struct dcerpc_binding_handle; struct rpc_pipe_client { struct rpc_pipe_client *prev, *next; + char *printer_username; + char *desthost; + char *srv_name_slash; + + struct dcerpc_binding_handle *binding_handle; + + SOURCE3_LIBRPC_INTERNALS_BEGIN + DATA_BLOB transport_session_key; struct rpc_cli_transport *transport; - struct dcerpc_binding_handle *binding_handle; /* * This is per connection @@ -55,13 +70,11 @@ struct rpc_pipe_client { struct ndr_syntax_id transfer_syntax; bool verified_pcontext; - char *printer_username; - char *desthost; - char *srv_name_slash; - uint16_t max_xmit_frag; struct pipe_auth_data *auth; + + SOURCE3_LIBRPC_INTERNALS_END; }; #endif /* _RPC_CLIENT_H */ -- 2.49.0 From d61c75ce2f02d779adcde9e2c6ef9bc911d1cb94 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 20 Sep 2024 00:24:05 +0200 Subject: [PATCH 60/80] s3:rpc_client: only pass the pipe_name to rpc_transport_np_init_send() There's no need to have the ndr_interface_table at that stage... Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 5b3573135b222755cd897d4539c0e5a89f7cdf5b) --- source3/rpc_client/cli_pipe.c | 10 +++++++++- source3/rpc_client/rpc_transport.h | 2 +- source3/rpc_client/rpc_transport_np.c | 5 ++--- source3/rpc_client/wsp_cli.c | 4 +--- 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index b2588da57caf..86e437754f9e 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -3325,6 +3325,7 @@ struct tevent_req *rpc_pipe_open_np_send( struct tevent_req *req = NULL, *subreq = NULL; struct rpc_pipe_open_np_state *state = NULL; struct rpc_pipe_client *result = NULL; + const char *pipe_name = NULL; req = tevent_req_create( mem_ctx, &state, struct rpc_pipe_open_np_state); @@ -3357,7 +3358,14 @@ struct tevent_req *rpc_pipe_open_np_send( result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN; - subreq = rpc_transport_np_init_send(state, ev, cli, table); + pipe_name = dcerpc_default_transport_endpoint(state, + NCACN_NP, + table); + if (tevent_req_nomem(pipe_name, req)) { + return tevent_req_post(req, ev); + } + + subreq = rpc_transport_np_init_send(state, ev, cli, pipe_name); if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); } diff --git a/source3/rpc_client/rpc_transport.h b/source3/rpc_client/rpc_transport.h index f352f60cf2a4..6c08860de17b 100644 --- a/source3/rpc_client/rpc_transport.h +++ b/source3/rpc_client/rpc_transport.h @@ -84,7 +84,7 @@ struct cli_state; struct tevent_req *rpc_transport_np_init_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli, - const struct ndr_interface_table *table); + const char *pipe_name); NTSTATUS rpc_transport_np_init_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, struct rpc_cli_transport **presult); diff --git a/source3/rpc_client/rpc_transport_np.c b/source3/rpc_client/rpc_transport_np.c index 21266c371061..48ec425fee85 100644 --- a/source3/rpc_client/rpc_transport_np.c +++ b/source3/rpc_client/rpc_transport_np.c @@ -47,7 +47,7 @@ static void rpc_transport_np_init_pipe_open(struct tevent_req *subreq); struct tevent_req *rpc_transport_np_init_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli, - const struct ndr_interface_table *table) + const char *pipe_name) { struct tevent_req *req; struct rpc_transport_np_init_state *state; @@ -72,8 +72,7 @@ struct tevent_req *rpc_transport_np_init_send(TALLOC_CTX *mem_ctx, state->conn = cli->conn; state->timeout = cli->timeout; state->abs_timeout = timeval_current_ofs_msec(cli->timeout); - state->pipe_name = dcerpc_default_transport_endpoint(state, NCACN_NP, - table); + state->pipe_name = talloc_strdup(state, pipe_name); if (tevent_req_nomem(state->pipe_name, req)) { return tevent_req_post(req, ev); } diff --git a/source3/rpc_client/wsp_cli.c b/source3/rpc_client/wsp_cli.c index 992b1a83b2ba..20c054c14ca3 100644 --- a/source3/rpc_client/wsp_cli.c +++ b/source3/rpc_client/wsp_cli.c @@ -1831,7 +1831,6 @@ static NTSTATUS wsp_resp_pdu_complete(struct tstream_context *stream, } static NTSTATUS wsp_rpc_transport_np_connect(struct cli_state *cli, - const struct ndr_interface_table *table, TALLOC_CTX *mem_ctx, struct rpc_cli_transport **presult) { @@ -1843,7 +1842,7 @@ static NTSTATUS wsp_rpc_transport_np_connect(struct cli_state *cli, if (ev == NULL) { goto fail; } - req = rpc_transport_np_init_send(ev, ev, cli, table); + req = rpc_transport_np_init_send(ev, ev, cli, "MsFteWds"); if (req == NULL) { goto fail; } @@ -1897,7 +1896,6 @@ NTSTATUS wsp_server_connect(TALLOC_CTX *mem_ctx, } status = wsp_rpc_transport_np_connect(cli, - &ndr_table_msftewds, cli, &transport); if (!NT_STATUS_IS_OK(status)) { -- 2.49.0 From 70631a34ea4e6ff8053ae4ba25b7ff271aa77766 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 16 Sep 2024 21:56:50 +0200 Subject: [PATCH 61/80] s3:rpc_client: add struct rpc_client_{association,connection} and helpers They will be every useful for NCACN_NP and NCACN_IP_TCP, so that we can support alter_context or more than one connection per association group. We mark the helpers as _UNUSED_ for now in order to compile... Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 327fe920d07e5bcbcaa0f09f276aad2b99d68235) --- source3/rpc_client/cli_pipe.c | 151 ++++++++++++++++++++++++++++++++ source3/rpc_client/rpc_client.h | 11 ++- 2 files changed, 160 insertions(+), 2 deletions(-) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 86e437754f9e..f2b64eaba030 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -50,6 +50,157 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_RPC_CLI +struct rpc_client_association { + struct dcerpc_binding *binding; + + struct samba_sockaddr addr; +}; + +_UNUSED_ +static NTSTATUS rpc_client_association_create(TALLOC_CTX *mem_ctx, + const char *target_hostname, + enum dcerpc_transport_t transport, + const struct samba_sockaddr *addr, + const char *endpoint, + struct rpc_client_association **passoc) +{ + struct rpc_client_association *assoc = NULL; + struct dcerpc_binding *bd = NULL; + NTSTATUS status; + + assoc = talloc_zero(mem_ctx, struct rpc_client_association); + if (assoc == NULL) { + return NT_STATUS_NO_MEMORY; + } + + status = dcerpc_parse_binding(assoc, "", &bd); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(assoc); + return status; + } + status = dcerpc_binding_set_transport(bd, transport); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(assoc); + return status; + } + status = dcerpc_binding_set_string_option(bd, + "host", + target_hostname); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(assoc); + return status; + } + status = dcerpc_binding_set_string_option(bd, + "target_hostname", + target_hostname); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(assoc); + return status; + } + status = dcerpc_binding_set_string_option(bd, + "endpoint", + endpoint); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(assoc); + return status; + } + + assoc->binding = bd; + assoc->addr = *addr; + + *passoc = assoc; + return NT_STATUS_OK; +} + +struct rpc_client_connection { + DATA_BLOB transport_session_key; + struct rpc_cli_transport *transport; +}; + +_UNUSED_ +static NTSTATUS rpc_client_connection_create(TALLOC_CTX *mem_ctx, + struct rpc_client_connection **pconn) +{ + struct rpc_client_connection *conn = NULL; + + conn = talloc_zero(mem_ctx, struct rpc_client_connection); + if (conn == NULL) { + return NT_STATUS_NO_MEMORY; + } + + *pconn = conn; + return NT_STATUS_OK; +} + +static int rpc_pipe_client_wrap_destructor(struct rpc_pipe_client *p) +{ + if (p->np_cli != NULL) { + DLIST_REMOVE(p->np_cli->pipe_list, p); + p->np_cli = NULL; + } + + return 0; +} + +_UNUSED_ +static NTSTATUS rpc_pipe_wrap_create( + const struct ndr_interface_table *table, + struct cli_state *np_cli, + struct rpc_client_association **passoc, + struct rpc_client_connection **pconn, + TALLOC_CTX *mem_ctx, + struct rpc_pipe_client **presult) +{ + struct rpc_pipe_client *result = NULL; + const char *hostname = NULL; + + result = talloc_zero(mem_ctx, struct rpc_pipe_client); + if (result == NULL) { + return NT_STATUS_NO_MEMORY; + } + talloc_set_destructor(result, rpc_pipe_client_wrap_destructor); + + result->assoc = talloc_move(result, passoc); + result->conn = talloc_move(result, pconn); + + result->transport_session_key = result->conn->transport_session_key; + result->transport = result->conn->transport; + + result->abstract_syntax = table->syntax_id; + result->transfer_syntax = ndr_transfer_syntax_ndr; + + hostname = dcerpc_binding_get_string_option(result->assoc->binding, + "target_hostname"); + result->desthost = talloc_strdup(result, hostname); + if (result->desthost == NULL) { + TALLOC_FREE(result); + return NT_STATUS_NO_MEMORY; + } + + result->srv_name_slash = talloc_asprintf_strupper_m( + result, "\\\\%s", result->desthost); + if (result->srv_name_slash == NULL) { + TALLOC_FREE(result); + return NT_STATUS_NO_MEMORY; + } + + result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN; + + result->binding_handle = rpccli_bh_create(result, NULL, table); + if (result->binding_handle == NULL) { + TALLOC_FREE(result); + return NT_STATUS_NO_MEMORY; + } + + if (np_cli != NULL) { + result->np_cli = np_cli; + DLIST_ADD_END(np_cli->pipe_list, result); + } + + *presult = result; + return NT_STATUS_OK; +} + /******************************************************************** Pipe description for a DEBUG ********************************************************************/ diff --git a/source3/rpc_client/rpc_client.h b/source3/rpc_client/rpc_client.h index 84422188a498..4cc037d567cb 100644 --- a/source3/rpc_client/rpc_client.h +++ b/source3/rpc_client/rpc_client.h @@ -39,6 +39,9 @@ struct dcerpc_binding_handle; +struct rpc_client_association; +struct rpc_client_connection; + struct rpc_pipe_client { struct rpc_pipe_client *prev, *next; @@ -50,6 +53,12 @@ struct rpc_pipe_client { SOURCE3_LIBRPC_INTERNALS_BEGIN + struct cli_state *np_cli; + + struct rpc_client_association *assoc; + struct rpc_client_connection *conn; + struct pipe_auth_data *auth; + DATA_BLOB transport_session_key; struct rpc_cli_transport *transport; @@ -72,8 +81,6 @@ struct rpc_pipe_client { uint16_t max_xmit_frag; - struct pipe_auth_data *auth; - SOURCE3_LIBRPC_INTERNALS_END; }; -- 2.49.0 From 022f411a8fd10a976145ab1eeb5c5f338b3049d8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 16 Sep 2024 21:56:50 +0200 Subject: [PATCH 62/80] s3:rpc_client: convert rpc_pipe_open_ncalrpc() to rpc_client_{association,connection} For rpc_pipe_open_ncalrpc() it's not really important to abstract these out, but we want to have these for all... Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 5e9c2ebb37b276d7c90b4cc8397c4853f62aa189) --- source3/rpc_client/cli_pipe.c | 97 +++++++++++++++++++---------------- 1 file changed, 53 insertions(+), 44 deletions(-) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index f2b64eaba030..ce3cc2ad8159 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -56,7 +56,6 @@ struct rpc_client_association { struct samba_sockaddr addr; }; -_UNUSED_ static NTSTATUS rpc_client_association_create(TALLOC_CTX *mem_ctx, const char *target_hostname, enum dcerpc_transport_t transport, @@ -117,7 +116,6 @@ struct rpc_client_connection { struct rpc_cli_transport *transport; }; -_UNUSED_ static NTSTATUS rpc_client_connection_create(TALLOC_CTX *mem_ctx, struct rpc_client_connection **pconn) { @@ -142,7 +140,6 @@ static int rpc_pipe_client_wrap_destructor(struct rpc_pipe_client *p) return 0; } -_UNUSED_ static NTSTATUS rpc_pipe_wrap_create( const struct ndr_interface_table *table, struct cli_state *np_cli, @@ -3233,8 +3230,9 @@ NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const struct ndr_interface_table *table, struct rpc_pipe_client **presult) { + TALLOC_CTX *frame = talloc_stackframe(); + char *myname = NULL; char *socket_name = NULL; - struct rpc_pipe_client *result; struct samba_sockaddr saddr = { .sa_socklen = sizeof(struct sockaddr_un), .u = { @@ -3243,21 +3241,27 @@ NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, }, }, }; + struct rpc_client_association *assoc = NULL; + struct rpc_client_connection *conn = NULL; + struct rpc_pipe_client *result = NULL; int pathlen; NTSTATUS status; int fd = -1; - result = talloc_zero(mem_ctx, struct rpc_pipe_client); - if (result == NULL) { + myname = get_myname(frame); + if (myname == NULL) { + TALLOC_FREE(frame); return NT_STATUS_NO_MEMORY; } - status = rpc_pipe_get_ncalrpc_name( - &table->syntax_id, result, &socket_name); + status = rpc_pipe_get_ncalrpc_name(&table->syntax_id, + frame, + &socket_name); if (!NT_STATUS_IS_OK(status)) { DBG_DEBUG("rpc_pipe_get_ncalrpc_name failed: %s\n", nt_errstr(status)); - goto fail; + TALLOC_FREE(frame); + return status; } pathlen = snprintf( @@ -3268,66 +3272,71 @@ NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, socket_name); if ((pathlen < 0) || ((size_t)pathlen >= sizeof(saddr.u.un.sun_path))) { DBG_DEBUG("socket_path for %s too long\n", socket_name); - status = NT_STATUS_NAME_TOO_LONG; - goto fail; + TALLOC_FREE(frame); + return NT_STATUS_NAME_TOO_LONG; } TALLOC_FREE(socket_name); - result->abstract_syntax = table->syntax_id; - result->transfer_syntax = ndr_transfer_syntax_ndr; - - result->desthost = get_myname(result); - if (result->desthost == NULL) { - status = NT_STATUS_NO_MEMORY; - goto fail; + status = rpc_client_association_create(mem_ctx, + myname, + NCALRPC, + &saddr, + socket_name, + &assoc); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(frame); + return status; } + talloc_steal(frame, assoc); - result->srv_name_slash = talloc_asprintf_strupper_m( - result, "\\\\%s", result->desthost); - if (result->srv_name_slash == NULL) { - status = NT_STATUS_NO_MEMORY; - goto fail; + status = rpc_client_connection_create(mem_ctx, &conn); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(frame); + return status; } - - result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN; + talloc_steal(frame, conn); fd = socket(AF_UNIX, SOCK_STREAM, 0); if (fd == -1) { status = map_nt_error_from_unix(errno); - goto fail; + TALLOC_FREE(frame); + return status; } if (connect(fd, &saddr.u.sa, saddr.sa_socklen) == -1) { - DBG_WARNING("connect(%s) failed: %s\n", - saddr.u.un.sun_path, - strerror(errno)); status = map_nt_error_from_unix(errno); - goto fail; + close(fd); + DBG_WARNING("connect(%s) failed: %s - %s\n", + saddr.u.un.sun_path, + strerror(errno), nt_errstr(status)); + TALLOC_FREE(frame); + return status; } - status = rpc_transport_sock_init(result, fd, &result->transport); + status = rpc_transport_sock_init(conn, fd, &conn->transport); if (!NT_STATUS_IS_OK(status)) { - goto fail; + close(fd); + TALLOC_FREE(frame); + return status; } fd = -1; - result->transport->transport = NCALRPC; + conn->transport->transport = NCALRPC; - result->binding_handle = rpccli_bh_create(result, NULL, table); - if (result->binding_handle == NULL) { - status = NT_STATUS_NO_MEMORY; - goto fail; + status = rpc_pipe_wrap_create(table, + NULL, + &assoc, + &conn, + mem_ctx, + &result); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(frame); + return status; } *presult = result; + TALLOC_FREE(frame); return NT_STATUS_OK; - - fail: - if (fd != -1) { - close(fd); - } - TALLOC_FREE(result); - return status; } NTSTATUS rpc_pipe_open_local_np( -- 2.49.0 From a794b2fdab0fbf2651c55fe0d00e8cf9a16782f4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 16 Sep 2024 22:01:06 +0200 Subject: [PATCH 63/80] s3:rpc_client: convert rpc_pipe_open_local_np() to rpc_client_{association,connection} For rpc_pipe_open_local_np() it's not really important to abstract these out, but we want to have these for all... Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 338dd71cc39195fcf25977b40b9772775972bc9f) --- source3/rpc_client/cli_pipe.c | 101 +++++++++++++++++++++------------- 1 file changed, 63 insertions(+), 38 deletions(-) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index ce3cc2ad8159..d89e2b2b11c4 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -3349,42 +3349,59 @@ NTSTATUS rpc_pipe_open_local_np( const struct auth_session_info *session_info, struct rpc_pipe_client **presult) { + TALLOC_CTX *frame = talloc_stackframe(); + struct rpc_client_association *assoc = NULL; + struct rpc_client_connection *conn = NULL; struct rpc_pipe_client *result = NULL; struct pipe_auth_data *auth = NULL; + struct samba_sockaddr saddr = { .sa_socklen = 0, }; const char *pipe_name = NULL; struct tstream_context *npa_stream = NULL; NTSTATUS status = NT_STATUS_NO_MEMORY; int ret; - result = talloc_zero(mem_ctx, struct rpc_pipe_client); - if (result == NULL) { - goto fail; - } - result->abstract_syntax = table->syntax_id; - result->transfer_syntax = ndr_transfer_syntax_ndr; - result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN; - - pipe_name = dcerpc_default_transport_endpoint( - result, NCACN_NP, table); + pipe_name = dcerpc_default_transport_endpoint(frame, + NCACN_NP, + table); if (pipe_name == NULL) { DBG_DEBUG("dcerpc_default_transport_endpoint failed\n"); - status = NT_STATUS_OBJECT_NAME_NOT_FOUND; - goto fail; + TALLOC_FREE(frame); + return NT_STATUS_OBJECT_NAME_NOT_FOUND; } if (local_server_name == NULL) { - result->desthost = get_myname(result); - } else { - result->desthost = talloc_strdup(result, local_server_name); + local_server_name = get_myname(result); } - if (result->desthost == NULL) { - goto fail; + + if (local_server_addr != NULL) { + saddr.sa_socklen = tsocket_address_bsd_sockaddr(local_server_addr, + &saddr.u.sa, + sizeof(saddr.u.ss)); + if (saddr.sa_socklen == -1) { + status = map_nt_error_from_unix(errno); + TALLOC_FREE(frame); + return status; + } } - result->srv_name_slash = talloc_asprintf_strupper_m( - result, "\\\\%s", result->desthost); - if (result->srv_name_slash == NULL) { - goto fail; + + status = rpc_client_association_create(mem_ctx, + local_server_name, + NCACN_NP, + &saddr, + pipe_name, + &assoc); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(frame); + return status; + } + talloc_steal(frame, assoc); + + status = rpc_client_connection_create(mem_ctx, &conn); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(frame); + return status; } + talloc_steal(frame, conn); ret = local_np_connect( pipe_name, @@ -3395,7 +3412,7 @@ NTSTATUS rpc_pipe_open_local_np( local_server_addr, session_info, true, - result, + conn, &npa_stream); if (ret != 0) { DBG_DEBUG("local_np_connect for %s and " @@ -3405,43 +3422,51 @@ NTSTATUS rpc_pipe_open_local_np( session_info->info->account_name, strerror(ret)); status = map_nt_error_from_unix(ret); - goto fail; + TALLOC_FREE(frame); + return status; } - status = rpc_transport_tstream_init( - result, &npa_stream, &result->transport); + status = rpc_transport_tstream_init(conn, + &npa_stream, + &conn->transport); if (!NT_STATUS_IS_OK(status)) { DBG_DEBUG("rpc_transport_tstream_init failed: %s\n", nt_errstr(status)); - goto fail; + TALLOC_FREE(frame); + return status; } + conn->transport->transport = NCACN_NP; - result->binding_handle = rpccli_bh_create(result, NULL, table); - if (result->binding_handle == NULL) { - status = NT_STATUS_NO_MEMORY; - DBG_DEBUG("Failed to create binding handle.\n"); - goto fail; + status = rpc_pipe_wrap_create(table, + NULL, + &assoc, + &conn, + mem_ctx, + &result); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(frame); + return status; } + talloc_steal(frame, result); status = rpccli_anon_bind_data(result, &auth); if (!NT_STATUS_IS_OK(status)) { DBG_DEBUG("rpccli_anon_bind_data failed: %s\n", nt_errstr(status)); - goto fail; + TALLOC_FREE(frame); + return status; } status = rpc_pipe_bind(result, auth); if (!NT_STATUS_IS_OK(status)) { DBG_DEBUG("rpc_pipe_bind failed: %s\n", nt_errstr(status)); - goto fail; + TALLOC_FREE(frame); + return status; } - *presult = result; + *presult = talloc_move(mem_ctx, &result); + TALLOC_FREE(frame); return NT_STATUS_OK; - -fail: - TALLOC_FREE(result); - return status; } struct rpc_pipe_client_np_ref { -- 2.49.0 From ec08524e02eaaf3e7799da281479b132a62db146 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 16 Sep 2024 22:04:49 +0200 Subject: [PATCH 64/80] s3:rpc_client: convert rpc_pipe_open_tcp_port() to rpc_client_{association,connection} Note that cli_rpc_pipe_open() calls rpc_client_association_create() without a need for NCACN_NP, but that will change in the next commits... Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 637a8e5270fefaea5c61921d4b6ecfc4455a91aa) --- source3/rpc_client/cli_pipe.c | 281 ++++++++++++++++++++++------------ 1 file changed, 179 insertions(+), 102 deletions(-) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index d89e2b2b11c4..81661ddeae36 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2843,75 +2843,55 @@ NTSTATUS rpccli_ncalrpc_bind_data(TALLOC_CTX *mem_ctx, /** * Create an rpc pipe client struct, connecting to a tcp port. */ -static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host, - const struct sockaddr_storage *ss_addr, - uint16_t port, - const struct ndr_interface_table *table, - struct rpc_pipe_client **presult) +static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, + const struct rpc_client_association *assoc, + struct rpc_client_connection **pconn) { - struct rpc_pipe_client *result; - struct sockaddr_storage addr; + struct rpc_client_connection *conn = NULL; + enum dcerpc_transport_t transport; + const char *endpoint = NULL; + uint16_t port; NTSTATUS status; int fd; - result = talloc_zero(mem_ctx, struct rpc_pipe_client); - if (result == NULL) { - return NT_STATUS_NO_MEMORY; + transport = dcerpc_binding_get_transport(assoc->binding); + if (transport != NCACN_IP_TCP) { + return NT_STATUS_RPC_WRONG_KIND_OF_BINDING; } - result->abstract_syntax = table->syntax_id; - result->transfer_syntax = ndr_transfer_syntax_ndr; - - result->desthost = talloc_strdup(result, host); - if (result->desthost == NULL) { - status = NT_STATUS_NO_MEMORY; - goto fail; + endpoint = dcerpc_binding_get_string_option(assoc->binding, + "endpoint"); + if (endpoint == NULL) { + return NT_STATUS_RPC_INVALID_ENDPOINT_FORMAT; } - - result->srv_name_slash = talloc_asprintf_strupper_m( - result, "\\\\%s", result->desthost); - if (result->srv_name_slash == NULL) { - status = NT_STATUS_NO_MEMORY; - goto fail; + port = (uint16_t)atoi(endpoint); + if (port == 0) { + return NT_STATUS_RPC_INVALID_ENDPOINT_FORMAT; } - result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN; - - if (ss_addr == NULL) { - if (!resolve_name(host, &addr, NBT_NAME_SERVER, false)) { - status = NT_STATUS_NOT_FOUND; - goto fail; - } - } else { - addr = *ss_addr; + status = rpc_client_connection_create(mem_ctx, &conn); + if (!NT_STATUS_IS_OK(status)) { + return status; } - status = open_socket_out(&addr, port, 60*1000, &fd); + status = open_socket_out(&assoc->addr.u.ss, port, 60*1000, &fd); if (!NT_STATUS_IS_OK(status)) { - goto fail; + TALLOC_FREE(conn); + return status; } set_socket_options(fd, lp_socket_options()); - status = rpc_transport_sock_init(result, fd, &result->transport); + status = rpc_transport_sock_init(conn, fd, &conn->transport); if (!NT_STATUS_IS_OK(status)) { close(fd); - goto fail; + TALLOC_FREE(conn); + return status; } - result->transport->transport = NCACN_IP_TCP; - - result->binding_handle = rpccli_bh_create(result, NULL, table); - if (result->binding_handle == NULL) { - TALLOC_FREE(result); - return NT_STATUS_NO_MEMORY; - } + conn->transport->transport = NCACN_IP_TCP; - *presult = result; + *pconn = conn; return NT_STATUS_OK; - - fail: - TALLOC_FREE(result); - return status; } static NTSTATUS rpccli_epm_map_binding( @@ -3080,88 +3060,98 @@ static NTSTATUS rpccli_epm_map_interface( * target host. */ static NTSTATUS rpc_pipe_get_tcp_port(const char *host, - const struct sockaddr_storage *addr, + const struct samba_sockaddr *saddr, const struct ndr_interface_table *table, uint16_t *pport) { - NTSTATUS status; + TALLOC_CTX *frame = talloc_stackframe(); + const char *epm_ep = NULL; + struct rpc_client_association *epm_assoc = NULL; + struct rpc_client_connection *epm_conn = NULL; struct rpc_pipe_client *epm_pipe = NULL; - struct pipe_auth_data *auth = NULL; + struct pipe_auth_data *epm_auth = NULL; char *endpoint = NULL; - TALLOC_CTX *tmp_ctx = talloc_stackframe(); + uint16_t port = 0; + NTSTATUS status; - if (pport == NULL) { - status = NT_STATUS_INVALID_PARAMETER; - goto done; + endpoint = dcerpc_default_transport_endpoint(frame, + NCACN_IP_TCP, + table); + if (endpoint != NULL) { + port = (uint16_t)atoi(endpoint); } - if (ndr_syntax_id_equal(&table->syntax_id, - &ndr_table_epmapper.syntax_id)) { - *pport = 135; - status = NT_STATUS_OK; - goto done; + if (port != 0) { + *pport = port; + TALLOC_FREE(frame); + return NT_STATUS_OK; + } + + epm_ep = dcerpc_default_transport_endpoint(frame, + NCACN_IP_TCP, + &ndr_table_epmapper); + if (epm_ep == NULL) { + TALLOC_FREE(frame); + return NT_STATUS_RPC_INTERNAL_ERROR; + } + + status = rpc_client_association_create(frame, + host, + NCACN_IP_TCP, + saddr, + epm_ep, + &epm_assoc); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(frame); + return status; } /* open the connection to the endpoint mapper */ - status = rpc_pipe_open_tcp_port(tmp_ctx, host, addr, 135, - &ndr_table_epmapper, - &epm_pipe); + status = rpc_pipe_open_tcp_port(frame, epm_assoc, &epm_conn); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(frame); + return status; + } + status = rpccli_anon_bind_data(frame, &epm_auth); if (!NT_STATUS_IS_OK(status)) { - goto done; + TALLOC_FREE(frame); + return status; } - status = rpccli_anon_bind_data(tmp_ctx, &auth); + status = rpc_pipe_wrap_create(&ndr_table_epmapper, + NULL, + &epm_assoc, + &epm_conn, + frame, + &epm_pipe); if (!NT_STATUS_IS_OK(status)) { - goto done; + TALLOC_FREE(frame); + return status; } - status = rpc_pipe_bind(epm_pipe, auth); + status = rpc_pipe_bind(epm_pipe, epm_auth); if (!NT_STATUS_IS_OK(status)) { - goto done; + TALLOC_FREE(frame); + return status; } status = rpccli_epm_map_interface( epm_pipe->binding_handle, NCACN_IP_TCP, &table->syntax_id, - tmp_ctx, + frame, &endpoint); if (!NT_STATUS_IS_OK(status)) { DBG_DEBUG("rpccli_epm_map_interface failed: %s\n", nt_errstr(status)); - goto done; - } - - *pport = (uint16_t)atoi(endpoint); - -done: - TALLOC_FREE(tmp_ctx); - return status; -} - -/** - * Create a rpc pipe client struct, connecting to a host via tcp. - * The port is determined by asking the endpoint mapper on the given - * host. - */ -static NTSTATUS rpc_pipe_open_tcp( - TALLOC_CTX *mem_ctx, - const char *host, - const struct sockaddr_storage *addr, - const struct ndr_interface_table *table, - struct rpc_pipe_client **presult) -{ - NTSTATUS status; - uint16_t port = 0; - - status = rpc_pipe_get_tcp_port(host, addr, table, &port); - if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(frame); return status; } - return rpc_pipe_open_tcp_port(mem_ctx, host, addr, port, - table, presult); + *pport = (uint16_t)atoi(endpoint); + TALLOC_FREE(frame); + return NT_STATUS_OK; } static NTSTATUS rpc_pipe_get_ncalrpc_name( @@ -3648,17 +3638,104 @@ static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli, const struct sockaddr_storage *remote_sockaddr, struct rpc_pipe_client **presult) { + TALLOC_CTX *frame = talloc_stackframe(); + struct samba_sockaddr saddr = { .sa_socklen = 0, }; + struct rpc_client_association *assoc = NULL; + struct rpc_client_connection *conn = NULL; + struct rpc_pipe_client *result = NULL; + char _tcp_endpoint[6] = { 0, }; + const char *endpoint = NULL; + NTSTATUS status; + + if (cli != NULL && remote_name == NULL) { + remote_name = smbXcli_conn_remote_name(cli->conn); + } + if (cli != NULL && remote_sockaddr == NULL) { + remote_sockaddr = smbXcli_conn_remote_sockaddr(cli->conn); + } + + if (remote_sockaddr != NULL) { + saddr.u.ss = *remote_sockaddr; + } else { + bool ok; + + ok = resolve_name(remote_name, + &saddr.u.ss, + NBT_NAME_SERVER, + false); + if (!ok) { + TALLOC_FREE(frame); + return NT_STATUS_NOT_FOUND; + } + } + + endpoint = dcerpc_default_transport_endpoint(frame, + transport, + table); + if (endpoint == NULL) { + uint16_t port = 0; + + if (transport != NCACN_IP_TCP) { + TALLOC_FREE(frame); + return NT_STATUS_RPC_NO_ENDPOINT_FOUND; + } + + status = rpc_pipe_get_tcp_port(remote_name, + &saddr, + table, + &port); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + snprintf(_tcp_endpoint, sizeof(_tcp_endpoint), "%u", port); + endpoint = _tcp_endpoint; + } + + status = rpc_client_association_create(NULL, + remote_name, + transport, + &saddr, + endpoint, + &assoc); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(frame); + return status; + } + talloc_steal(frame, assoc); + switch (transport) { case NCACN_IP_TCP: - return rpc_pipe_open_tcp(NULL, - remote_name, - remote_sockaddr, - table, presult); + status = rpc_pipe_open_tcp_port(NULL, + assoc, + &conn); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(frame); + return status; + } + talloc_steal(frame, conn); + break; case NCACN_NP: + TALLOC_FREE(frame); return rpc_pipe_open_np(cli, table, presult); default: + TALLOC_FREE(frame); return NT_STATUS_NOT_IMPLEMENTED; } + status = rpc_pipe_wrap_create(table, + cli, + &assoc, + &conn, + NULL, + &result); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(frame); + return status; + } + + *presult = result; + TALLOC_FREE(frame); + return NT_STATUS_OK; } /**************************************************************************** -- 2.49.0 From 86677c9f29fa3015f7379261ee2947385755fc60 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 16 Sep 2024 22:09:34 +0200 Subject: [PATCH 65/80] s3:rpc_client: convert rpc_pipe_open_np() to rpc_client_{association,connection} This split out rpc_client_connection_np_send/recv, which will be used as shortcut in a later commit. Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 7b9cef2a29333c6338520754927ee37027738010) --- source3/rpc_client/cli_pipe.c | 210 +++++++++++++++++++++------------- 1 file changed, 129 insertions(+), 81 deletions(-) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 81661ddeae36..2766ff2f4fd1 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -3459,33 +3459,115 @@ NTSTATUS rpc_pipe_open_local_np( return NT_STATUS_OK; } -struct rpc_pipe_client_np_ref { +struct rpc_client_connection_np_state { struct cli_state *cli; - struct rpc_pipe_client *pipe; + const char *pipe_name; + struct rpc_client_connection *conn; }; -static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref) +static void rpc_client_connection_np_done(struct tevent_req *subreq); + +static struct tevent_req *rpc_client_connection_np_send( + TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct cli_state *cli, + const struct rpc_client_association *assoc) { - DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe); - return 0; + struct tevent_req *req = NULL, *subreq = NULL; + struct rpc_client_connection_np_state *state = NULL; + enum dcerpc_transport_t transport; + const char *endpoint = NULL; + struct smbXcli_session *session = NULL; + NTSTATUS status; + + req = tevent_req_create(mem_ctx, &state, + struct rpc_client_connection_np_state); + if (req == NULL) { + return NULL; + } + + transport = dcerpc_binding_get_transport(assoc->binding); + if (transport != NCACN_NP) { + tevent_req_nterror(req, NT_STATUS_RPC_WRONG_KIND_OF_BINDING); + return tevent_req_post(req, ev); + } + + endpoint = dcerpc_binding_get_string_option(assoc->binding, + "endpoint"); + if (endpoint == NULL) { + tevent_req_nterror(req, NT_STATUS_RPC_INVALID_ENDPOINT_FORMAT); + return tevent_req_post(req, ev); + } + + status = rpc_client_connection_create(state, &state->conn); + if (tevent_req_nterror(req, status)) { + return tevent_req_post(req, ev); + } + + if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) { + session = cli->smb2.session; + } else { + session = cli->smb1.session; + } + + status = smbXcli_session_application_key(session, state->conn, + &state->conn->transport_session_key); + if (!NT_STATUS_IS_OK(status)) { + state->conn->transport_session_key = data_blob_null; + } + + subreq = rpc_transport_np_init_send(state, ev, cli, endpoint); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, rpc_client_connection_np_done, req); + return req; } -/**************************************************************************** - Open a named pipe over SMB to a remote server. - * - * CAVEAT CALLER OF THIS FUNCTION: - * The returned rpc_pipe_client saves a copy of the cli_state cli pointer, - * so be sure that this function is called AFTER any structure (vs pointer) - * assignment of the cli. In particular, libsmbclient does structure - * assignments of cli, which invalidates the data in the returned - * rpc_pipe_client if this function is called before the structure assignment - * of cli. - * - ****************************************************************************/ +static void rpc_client_connection_np_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct rpc_client_connection_np_state *state = tevent_req_data( + req, struct rpc_client_connection_np_state); + NTSTATUS status; + + status = rpc_transport_np_init_recv(subreq, + state->conn, + &state->conn->transport); + TALLOC_FREE(subreq); + if (tevent_req_nterror(req, status)) { + return; + } + + state->conn->transport->transport = NCACN_NP; + + tevent_req_done(req); +} + +static NTSTATUS rpc_client_connection_np_recv( + struct tevent_req *req, + TALLOC_CTX *mem_ctx, + struct rpc_client_connection **pconn) +{ + struct rpc_client_connection_np_state *state = tevent_req_data( + req, struct rpc_client_connection_np_state); + NTSTATUS status; + + if (tevent_req_is_nterror(req, &status)) { + tevent_req_received(req); + return status; + } + *pconn = talloc_move(mem_ctx, &state->conn); + tevent_req_received(req); + return NT_STATUS_OK; +} struct rpc_pipe_open_np_state { struct cli_state *cli; const struct ndr_interface_table *table; + struct rpc_client_association *assoc; + struct rpc_client_connection *conn; struct rpc_pipe_client *result; }; @@ -3499,8 +3581,11 @@ struct tevent_req *rpc_pipe_open_np_send( { struct tevent_req *req = NULL, *subreq = NULL; struct rpc_pipe_open_np_state *state = NULL; - struct rpc_pipe_client *result = NULL; + const char *remote_name = NULL; + const struct sockaddr_storage *remote_sockaddr = NULL; + struct samba_sockaddr saddr = { .sa_socklen = 0, }; const char *pipe_name = NULL; + NTSTATUS status; req = tevent_req_create( mem_ctx, &state, struct rpc_pipe_open_np_state); @@ -3510,28 +3595,9 @@ struct tevent_req *rpc_pipe_open_np_send( state->cli = cli; state->table = table; - state->result = talloc_zero(state, struct rpc_pipe_client); - if (tevent_req_nomem(state->result, req)) { - return tevent_req_post(req, ev); - } - result = state->result; - - result->abstract_syntax = table->syntax_id; - result->transfer_syntax = ndr_transfer_syntax_ndr; - - result->desthost = talloc_strdup( - result, smbXcli_conn_remote_name(cli->conn)); - if (tevent_req_nomem(result->desthost, req)) { - return tevent_req_post(req, ev); - } - - result->srv_name_slash = talloc_asprintf_strupper_m( - result, "\\\\%s", result->desthost); - if (tevent_req_nomem(result->srv_name_slash, req)) { - return tevent_req_post(req, ev); - } - - result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN; + remote_name = smbXcli_conn_remote_name(cli->conn); + remote_sockaddr = smbXcli_conn_remote_sockaddr(cli->conn); + saddr.u.ss = *remote_sockaddr; pipe_name = dcerpc_default_transport_endpoint(state, NCACN_NP, @@ -3540,7 +3606,17 @@ struct tevent_req *rpc_pipe_open_np_send( return tevent_req_post(req, ev); } - subreq = rpc_transport_np_init_send(state, ev, cli, pipe_name); + status = rpc_client_association_create(state, + remote_name, + NCACN_NP, + &saddr, + pipe_name, + &state->assoc); + if (tevent_req_nterror(req, status)) { + return tevent_req_post(req, ev); + } + + subreq = rpc_client_connection_np_send(state, ev, cli, state->assoc); if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); } @@ -3554,31 +3630,23 @@ static void rpc_pipe_open_np_done(struct tevent_req *subreq) subreq, struct tevent_req); struct rpc_pipe_open_np_state *state = tevent_req_data( req, struct rpc_pipe_open_np_state); - struct rpc_pipe_client *result = state->result; - struct rpc_pipe_client_np_ref *np_ref = NULL; NTSTATUS status; - status = rpc_transport_np_init_recv( - subreq, result, &result->transport); + status = rpc_client_connection_np_recv(subreq, + state, + &state->conn); TALLOC_FREE(subreq); if (tevent_req_nterror(req, status)) { return; } - result->transport->transport = NCACN_NP; - - np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref); - if (tevent_req_nomem(np_ref, req)) { - return; - } - np_ref->cli = state->cli; - np_ref->pipe = result; - - DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe); - talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor); - - result->binding_handle = rpccli_bh_create(result, NULL, state->table); - if (tevent_req_nomem(result->binding_handle, req)) { + status = rpc_pipe_wrap_create(state->table, + state->cli, + &state->assoc, + &state->conn, + state, + &state->result); + if (tevent_req_nterror(req, status)) { return; } @@ -3595,9 +3663,11 @@ NTSTATUS rpc_pipe_open_np_recv( NTSTATUS status; if (tevent_req_is_nterror(req, &status)) { + tevent_req_received(req); return status; } *_result = talloc_move(mem_ctx, &state->result); + tevent_req_received(req); return NT_STATUS_OK; } @@ -3771,28 +3841,6 @@ NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli, return status; } - /* - * This is a bit of an abstraction violation due to the fact that an - * anonymous bind on an authenticated SMB inherits the user/domain - * from the enclosing SMB creds - */ - - if (transport == NCACN_NP) { - struct smbXcli_session *session; - - if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) { - session = cli->smb2.session; - } else { - session = cli->smb1.session; - } - - status = smbXcli_session_application_key(session, result, - &result->transport_session_key); - if (!NT_STATUS_IS_OK(status)) { - result->transport_session_key = data_blob_null; - } - } - status = rpc_pipe_bind(result, auth); if (!NT_STATUS_IS_OK(status)) { int lvl = 0; -- 2.49.0 From 06a6467c7b8805eaa1f7e59fd0cf726d395e7dda Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 16 Sep 2024 22:10:00 +0200 Subject: [PATCH 66/80] s3:rpc_client: let cli_rpc_pipe_open() use rpc_client_connection_np() This way cli_rpc_pipe_open() uses the same flow for rpc_client_connection_np() and rpc_pipe_open_tcp_port(). Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit fab0d27c5cf4885c31d7ed04ea69eda7992ea209) --- source3/rpc_client/cli_pipe.c | 63 +++++++++++++++++++---------------- source3/rpc_client/cli_pipe.h | 3 -- 2 files changed, 35 insertions(+), 31 deletions(-) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 2766ff2f4fd1..74e471d978b3 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -3563,6 +3563,32 @@ static NTSTATUS rpc_client_connection_np_recv( return NT_STATUS_OK; } +static NTSTATUS rpc_client_connection_np(struct cli_state *cli, + const struct rpc_client_association *assoc, + struct rpc_client_connection **pconn) +{ + struct tevent_context *ev = NULL; + struct tevent_req *req = NULL; + NTSTATUS status = NT_STATUS_NO_MEMORY; + + ev = samba_tevent_context_init(cli); + if (ev == NULL) { + goto fail; + } + req = rpc_client_connection_np_send(ev, ev, cli, assoc); + if (req == NULL) { + goto fail; + } + if (!tevent_req_poll_ntstatus(req, ev, &status)) { + goto fail; + } + status = rpc_client_connection_np_recv(req, NULL, pconn); +fail: + TALLOC_FREE(req); + TALLOC_FREE(ev); + return status; +} + struct rpc_pipe_open_np_state { struct cli_state *cli; const struct ndr_interface_table *table; @@ -3671,32 +3697,6 @@ NTSTATUS rpc_pipe_open_np_recv( return NT_STATUS_OK; } -NTSTATUS rpc_pipe_open_np(struct cli_state *cli, - const struct ndr_interface_table *table, - struct rpc_pipe_client **presult) -{ - struct tevent_context *ev = NULL; - struct tevent_req *req = NULL; - NTSTATUS status = NT_STATUS_NO_MEMORY; - - ev = samba_tevent_context_init(cli); - if (ev == NULL) { - goto fail; - } - req = rpc_pipe_open_np_send(ev, ev, cli, table); - if (req == NULL) { - goto fail; - } - if (!tevent_req_poll_ntstatus(req, ev, &status)) { - goto fail; - } - status = rpc_pipe_open_np_recv(req, NULL, presult); -fail: - TALLOC_FREE(req); - TALLOC_FREE(ev); - return status; -} - /**************************************************************************** Open a pipe to a remote server. ****************************************************************************/ @@ -3786,8 +3786,15 @@ static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli, talloc_steal(frame, conn); break; case NCACN_NP: - TALLOC_FREE(frame); - return rpc_pipe_open_np(cli, table, presult); + status = rpc_client_connection_np(cli, + assoc, + &conn); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(frame); + return status; + } + talloc_steal(frame, conn); + break; default: TALLOC_FREE(frame); return NT_STATUS_NOT_IMPLEMENTED; diff --git a/source3/rpc_client/cli_pipe.h b/source3/rpc_client/cli_pipe.h index e6a66bbbe158..9dc46e755ead 100644 --- a/source3/rpc_client/cli_pipe.h +++ b/source3/rpc_client/cli_pipe.h @@ -47,9 +47,6 @@ NTSTATUS rpc_pipe_open_np_recv( struct tevent_req *req, TALLOC_CTX *mem_ctx, struct rpc_pipe_client **_result); -NTSTATUS rpc_pipe_open_np(struct cli_state *cli, - const struct ndr_interface_table *table, - struct rpc_pipe_client **presult); unsigned int rpccli_set_timeout(struct rpc_pipe_client *cli, unsigned int timeout); -- 2.49.0 From d5e2f96be099cd6abb79039d37e881a90382af4a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 15 Sep 2024 18:26:07 +0200 Subject: [PATCH 67/80] s3:rpc_client: make real use of rpc_client_{association,connection} This will allow NCACN_NP and NCACN_IP_TCP to support alter_context with security context multiplexing or otherwise more than one connection per association group. Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 899c9f2d6836c3b63acb6f261690c087e287afde) --- source3/rpc_client/cli_pipe.c | 426 ++++++++++++++++++++++++-------- source3/rpc_client/rpc_client.h | 23 +- 2 files changed, 331 insertions(+), 118 deletions(-) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 74e471d978b3..1d48dab85b3c 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -46,17 +46,32 @@ #include "libcli/named_pipe_auth/npa_tstream.h" #include "librpc/gen_ndr/ndr_winreg.h" #include "local_np.h" +#include "libcli/smb/tstream_smbXcli_np.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_RPC_CLI +static const uint16_t default_bt_features = + DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN | + DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING; + struct rpc_client_association { struct dcerpc_binding *binding; + struct { + uint16_t client; + uint16_t negotiated; + bool negotiation_done; + } features; + struct samba_sockaddr addr; + + uint32_t next_call_id; }; static NTSTATUS rpc_client_association_create(TALLOC_CTX *mem_ctx, + uint16_t client_features, + uint32_t flags, const char *target_hostname, enum dcerpc_transport_t transport, const struct samba_sockaddr *addr, @@ -71,6 +86,15 @@ static NTSTATUS rpc_client_association_create(TALLOC_CTX *mem_ctx, if (assoc == NULL) { return NT_STATUS_NO_MEMORY; } + assoc->features.client = client_features; + if (client_features == 0) { + /* + * Without requested features there + * is no point in trying to negotiate + * something, so we are done... + */ + assoc->features.negotiation_done = true; + } status = dcerpc_parse_binding(assoc, "", &bd); if (!NT_STATUS_IS_OK(status)) { @@ -103,6 +127,11 @@ static NTSTATUS rpc_client_association_create(TALLOC_CTX *mem_ctx, TALLOC_FREE(assoc); return status; } + status = dcerpc_binding_set_flags(bd, flags, 0); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(assoc); + return status; + } assoc->binding = bd; assoc->addr = *addr; @@ -114,17 +143,35 @@ static NTSTATUS rpc_client_association_create(TALLOC_CTX *mem_ctx, struct rpc_client_connection { DATA_BLOB transport_session_key; struct rpc_cli_transport *transport; + + struct { + uint16_t max_xmit_frag; + uint16_t max_recv_frag; + bool client_hdr_signing; + bool hdr_signing; + bool bind_done; + } features; + + uint32_t next_auth_context_id; + uint16_t next_pres_context_id; }; static NTSTATUS rpc_client_connection_create(TALLOC_CTX *mem_ctx, + const struct rpc_client_association *assoc, + uint16_t max_frag, struct rpc_client_connection **pconn) { struct rpc_client_connection *conn = NULL; + uint32_t flags = dcerpc_binding_get_flags(assoc->binding); + bool client_hdr_signing = (flags & DCERPC_PROPOSE_HEADER_SIGNING); conn = talloc_zero(mem_ctx, struct rpc_client_connection); if (conn == NULL) { return NT_STATUS_NO_MEMORY; } + conn->features.max_xmit_frag = max_frag; + conn->features.max_recv_frag = max_frag; + conn->features.client_hdr_signing = client_hdr_signing; *pconn = conn; return NT_STATUS_OK; @@ -160,10 +207,9 @@ static NTSTATUS rpc_pipe_wrap_create( result->assoc = talloc_move(result, passoc); result->conn = talloc_move(result, pconn); - result->transport_session_key = result->conn->transport_session_key; - result->transport = result->conn->transport; - - result->abstract_syntax = table->syntax_id; + /* rpc_pipe_bind_send should allocate an id... */ + result->pres_context_id = UINT16_MAX; + result->table = table; result->transfer_syntax = ndr_transfer_syntax_ndr; hostname = dcerpc_binding_get_string_option(result->assoc->binding, @@ -181,14 +227,6 @@ static NTSTATUS rpc_pipe_wrap_create( return NT_STATUS_NO_MEMORY; } - result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN; - - result->binding_handle = rpccli_bh_create(result, NULL, table); - if (result->binding_handle == NULL) { - TALLOC_FREE(result); - return NT_STATUS_NO_MEMORY; - } - if (np_cli != NULL) { result->np_cli = np_cli; DLIST_ADD_END(np_cli->pipe_list, result); @@ -211,16 +249,6 @@ static const char *rpccli_pipe_txt(TALLOC_CTX *mem_ctx, return result; } -/******************************************************************** - Rpc pipe call id. - ********************************************************************/ - -static uint32_t get_rpc_call_id(void) -{ - static uint32_t call_id = 0; - return ++call_id; -} - /******************************************************************* Use SMBreadX to get rest of one fragment's worth of rpc data. Reads the whole size or give an error message @@ -422,7 +450,7 @@ static struct tevent_req *get_complete_frag_send(TALLOC_CTX *mem_ctx, return tevent_req_post(req, ev); } subreq = rpc_read_send(state, state->ev, - state->cli->transport, + state->cli->conn->transport, pdu->data + received, RPC_HEADER_LEN - received); if (tevent_req_nomem(subreq, req)) { @@ -455,7 +483,7 @@ static struct tevent_req *get_complete_frag_send(TALLOC_CTX *mem_ctx, subreq = rpc_read_send( state, state->ev, - state->cli->transport, + state->cli->conn->transport, pdu->data + received, state->frag_len - received); if (tevent_req_nomem(subreq, req)) { @@ -495,7 +523,8 @@ static void get_complete_frag_got_header(struct tevent_req *subreq) * RPC_HEADER_LEN bytes into state->pdu. */ - subreq = rpc_read_send(state, state->ev, state->cli->transport, + subreq = rpc_read_send(state, state->ev, + state->cli->conn->transport, state->pdu->data + RPC_HEADER_LEN, state->frag_len - RPC_HEADER_LEN); if (tevent_req_nomem(subreq, req)) { @@ -943,7 +972,7 @@ static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx, /* * Ensure we're not sending too much. */ - if (data->length > cli->max_xmit_frag) { + if (data->length > cli->conn->features.max_xmit_frag) { tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); return tevent_req_post(req, ev); } @@ -951,7 +980,7 @@ static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx, DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(talloc_tos(), cli))); if (state->expected_pkt_type == DCERPC_PKT_AUTH3) { - subreq = rpc_write_send(state, ev, cli->transport, + subreq = rpc_write_send(state, ev, cli->conn->transport, data->data, data->length); if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); @@ -964,7 +993,7 @@ static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx, * the frag_length available */ max_recv_frag = RPC_HEADER_LEN; - subreq = cli_api_pipe_send(state, ev, cli->transport, + subreq = cli_api_pipe_send(state, ev, cli->conn->transport, data->data, data->length, max_recv_frag); if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); @@ -1046,7 +1075,7 @@ static void rpc_api_pipe_got_pdu(struct tevent_req *subreq) * * For now do it sync... */ - TALLOC_FREE(state->cli->transport); + TALLOC_FREE(state->cli->conn); tevent_req_oom(req); return; } @@ -1060,7 +1089,7 @@ static void rpc_api_pipe_got_pdu(struct tevent_req *subreq) * * For now do it sync... */ - TALLOC_FREE(state->cli->transport); + TALLOC_FREE(state->cli->conn); return; } @@ -1087,21 +1116,21 @@ static void rpc_api_pipe_got_pdu(struct tevent_req *subreq) * * For now do it sync... */ - TALLOC_FREE(state->cli->transport); + TALLOC_FREE(state->cli->conn); } else if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) { /* * TODO: do a real async disconnect ... * * For now do it sync... */ - TALLOC_FREE(state->cli->transport); + TALLOC_FREE(state->cli->conn); } else if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_SEC_PKG_ERROR)) { /* * TODO: do a real async disconnect ... * * For now do it sync... */ - TALLOC_FREE(state->cli->transport); + TALLOC_FREE(state->cli->conn); } if (tevent_req_nterror(req, status)) { return; @@ -1131,7 +1160,7 @@ static void rpc_api_pipe_got_pdu(struct tevent_req *subreq) * * For now do it sync... */ - TALLOC_FREE(state->cli->transport); + TALLOC_FREE(state->cli->conn); tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR); return; } @@ -1142,7 +1171,7 @@ static void rpc_api_pipe_got_pdu(struct tevent_req *subreq) * * For now do it sync... */ - TALLOC_FREE(state->cli->transport); + TALLOC_FREE(state->cli->conn); tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR); return; } @@ -1156,7 +1185,7 @@ static void rpc_api_pipe_got_pdu(struct tevent_req *subreq) * * For now do it sync... */ - TALLOC_FREE(state->cli->transport); + TALLOC_FREE(state->cli->conn); tevent_req_oom(req); return; } @@ -1191,7 +1220,7 @@ static void rpc_api_pipe_got_pdu(struct tevent_req *subreq) * * For now do it sync... */ - TALLOC_FREE(state->cli->transport); + TALLOC_FREE(state->cli->conn); } if (tevent_req_nomem(subreq, req)) { return; @@ -1260,6 +1289,9 @@ static NTSTATUS create_generic_auth_rpc_bind_req(struct rpc_pipe_client *cli, static NTSTATUS create_bind_or_alt_ctx_internal(TALLOC_CTX *mem_ctx, enum dcerpc_pkt_type ptype, uint32_t rpc_call_id, + struct rpc_client_association *assoc, + struct rpc_client_connection *conn, + uint16_t pres_context_id, const struct ndr_syntax_id *abstract, const struct ndr_syntax_id *transfer, const DATA_BLOB *auth_info, @@ -1268,37 +1300,56 @@ static NTSTATUS create_bind_or_alt_ctx_internal(TALLOC_CTX *mem_ctx, uint16_t auth_len = auth_info->length; NTSTATUS status; struct ndr_syntax_id bind_time_features = dcerpc_construct_bind_time_features( - DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING | - DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN); + assoc->features.client); struct dcerpc_ctx_list ctx_list[2] = { [0] = { - .context_id = 0, + .context_id = pres_context_id, .num_transfer_syntaxes = 1, .abstract_syntax = *abstract, .transfer_syntaxes = (struct ndr_syntax_id *)discard_const(transfer), }, [1] = { - .context_id = 1, + /* + * For now we assume pres_context_id is 0 + * because bind time feature negotiation + * only happens once per association, + * with the first DCERPC Bind. + * + * With that we use pres_context_id + 1, + * but only consume it from conn->next_pres_context_id + * in check_bind_response(). + */ + .context_id = pres_context_id + 1, .num_transfer_syntaxes = 1, .abstract_syntax = *abstract, .transfer_syntaxes = &bind_time_features, }, }; + uint32_t assoc_group_id = + dcerpc_binding_get_assoc_group_id(assoc->binding); union dcerpc_payload u = { - .bind.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN, - .bind.max_recv_frag = RPC_MAX_PDU_FRAG_LEN, - .bind.num_contexts = ptype == DCERPC_PKT_BIND ? 2 : 1, + .bind.max_xmit_frag = conn->features.max_xmit_frag, + .bind.max_recv_frag = conn->features.max_recv_frag, + .bind.assoc_group_id = assoc_group_id, + .bind.num_contexts = assoc->features.negotiation_done ? 1 : 2, .bind.ctx_list = ctx_list, .bind.auth_info = *auth_info, }; uint8_t pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST; - if (auth_len) { - auth_len -= DCERPC_AUTH_TRAILER_LENGTH; + if (conn->features.client_hdr_signing && + auth_len != 0 && + !conn->features.hdr_signing) + { + /* + * The first authenticated bind or alter_context + * negotiates header signing + */ + pfc_flags |= DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN; } - if (ptype == DCERPC_PKT_BIND) { - pfc_flags |= DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN; + if (auth_len) { + auth_len -= DCERPC_AUTH_TRAILER_LENGTH; } status = dcerpc_push_ncacn_packet(mem_ctx, @@ -1327,10 +1378,15 @@ static NTSTATUS create_rpc_bind_req(TALLOC_CTX *mem_ctx, const struct ndr_syntax_id *transfer, DATA_BLOB *rpc_out) { + enum dcerpc_pkt_type ptype = DCERPC_PKT_BIND; DATA_BLOB auth_token = { .data = NULL }; DATA_BLOB auth_info = { .data = NULL }; NTSTATUS ret; + if (cli->conn->features.bind_done) { + ptype = DCERPC_PKT_ALTER; + } + if (auth->auth_type != DCERPC_AUTH_TYPE_NONE) { ret = create_generic_auth_rpc_bind_req( cli, mem_ctx, &auth_token); @@ -1356,8 +1412,11 @@ static NTSTATUS create_rpc_bind_req(TALLOC_CTX *mem_ctx, } ret = create_bind_or_alt_ctx_internal(mem_ctx, - DCERPC_PKT_BIND, + ptype, rpc_call_id, + cli->assoc, + cli->conn, + cli->pres_context_id, abstract, transfer, &auth_info, @@ -1418,9 +1477,9 @@ static struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx, state->op_num = op_num; state->object_uuid = object_uuid; state->req_data = req_data; - state->call_id = get_rpc_call_id(); + state->call_id = ++cli->assoc->next_call_id; - if (cli->max_xmit_frag < DCERPC_REQUEST_LENGTH + if (cli->conn->features.max_xmit_frag < DCERPC_REQUEST_LENGTH + RPC_MAX_SIGN_SIZE) { /* Server is screwed up ! */ tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); @@ -1447,7 +1506,7 @@ static struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx, } tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req); } else { - subreq = rpc_write_send(state, ev, cli->transport, + subreq = rpc_write_send(state, ev, cli->conn->transport, state->rpc_out.data, state->rpc_out.length); if (tevent_req_nomem(subreq, req)) { @@ -1490,7 +1549,7 @@ static NTSTATUS prepare_verification_trailer(struct rpc_api_pipe_req_state *stat } t->commands[t->count.count++] = (struct dcerpc_sec_vt) { .command = DCERPC_SEC_VT_COMMAND_BITMASK1, - .u.bitmask1 = (state->cli->client_hdr_signing) ? + .u.bitmask1 = (state->cli->conn->features.client_hdr_signing) ? DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0, }; @@ -1507,7 +1566,7 @@ static NTSTATUS prepare_verification_trailer(struct rpc_api_pipe_req_state *stat t->commands[t->count.count++] = (struct dcerpc_sec_vt) { .command = DCERPC_SEC_VT_COMMAND_PCONTEXT, .u.pcontext.abstract_syntax = - state->cli->abstract_syntax, + state->cli->table->syntax_id, .u.pcontext.transfer_syntax = state->cli->transfer_syntax, }; @@ -1526,7 +1585,7 @@ static NTSTATUS prepare_verification_trailer(struct rpc_api_pipe_req_state *stat .u.header2.ptype = DCERPC_PKT_REQUEST, .u.header2.drep[0] = DCERPC_DREP_LE, .u.header2.call_id = state->call_id, - .u.header2.context_id = 0, + .u.header2.context_id = state->cli->pres_context_id, .u.header2.opnum = state->op_num, }; } @@ -1608,7 +1667,7 @@ static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state, status = dcerpc_guess_sizes(state->cli->auth, DCERPC_REQUEST_LENGTH, total_left, - state->cli->max_xmit_frag, + state->cli->conn->features.max_xmit_frag, &total_thistime, &frag_len, &auth_len, &pad_len); if (!NT_STATUS_IS_OK(status)) { @@ -1632,7 +1691,7 @@ static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state, u = (union dcerpc_payload) { .request.alloc_hint = total_left, - .request.context_id = 0, + .request.context_id = state->cli->pres_context_id, .request.opnum = state->op_num, }; @@ -1733,7 +1792,7 @@ static void rpc_api_pipe_req_write_done(struct tevent_req *subreq) tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req); } else { subreq = rpc_write_send(state, state->ev, - state->cli->transport, + state->cli->conn->transport, state->rpc_out.data, state->rpc_out.length); if (tevent_req_nomem(subreq, req)) { @@ -1806,6 +1865,8 @@ static bool check_bind_response(const struct dcerpc_bind_ack *r, struct rpc_pipe_client *cli) { const struct ndr_syntax_id *transfer = &cli->transfer_syntax; + uint32_t assoc_group_id = + dcerpc_binding_get_assoc_group_id(cli->assoc->binding); struct dcerpc_ack_ctx ctx; bool equal; @@ -1813,6 +1874,48 @@ static bool check_bind_response(const struct dcerpc_bind_ack *r, DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)\n")); } + if (assoc_group_id == 0) { + NTSTATUS status; + + /* + * We only capture the first assoc_group_id we're + * getting. + * + * Current samba releases may ignore the client value + * and return a different assoc_group_id if the + * client given one is not found in the preforked + * process. This applies to the source4 netlogon, + * which uses DCESRV_INTERFACE_FLAGS_HANDLES_NOT_USED. + */ + + status = dcerpc_binding_set_assoc_group_id(cli->assoc->binding, + r->assoc_group_id); + if (!NT_STATUS_IS_OK(status)) { + return false; + } + } + + if (!cli->conn->features.bind_done) { + /* + * DCE-RPC 1.1 (c706) specifies + * CONST_MUST_RCV_FRAG_SIZE as 1432 + */ + + if (r->max_xmit_frag < 1432) { + return false; + } + if (r->max_recv_frag < 1432) { + return false; + } + + cli->conn->features.max_xmit_frag = + MIN(cli->conn->features.max_xmit_frag, r->max_xmit_frag); + cli->conn->features.max_recv_frag = + MIN(cli->conn->features.max_recv_frag, r->max_recv_frag); + + cli->conn->features.bind_done = true; + } + if (r->num_results < 1 || !r->ctx_list) { return false; } @@ -1836,7 +1939,13 @@ static bool check_bind_response(const struct dcerpc_bind_ack *r, const struct dcerpc_ack_ctx *neg = &r->ctx_list[1]; if (neg->result == DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK) { - cli->bind_time_features = neg->reason.negotiate; + cli->assoc->features.negotiated = neg->reason.negotiate; + cli->assoc->features.negotiation_done = true; + /* + * consume presentation context used for bind time + * feature negotiation + */ + cli->conn->next_pres_context_id++; } else { DBG_DEBUG("bind_time_feature failed - " "result: %d reason %x\n", @@ -1901,6 +2010,9 @@ static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx, static NTSTATUS create_rpc_alter_context(TALLOC_CTX *mem_ctx, struct pipe_auth_data *auth, uint32_t rpc_call_id, + struct rpc_client_association *assoc, + struct rpc_client_connection *conn, + uint16_t pres_context_id, const struct ndr_syntax_id *abstract, const struct ndr_syntax_id *transfer, const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */ @@ -1923,6 +2035,9 @@ static NTSTATUS create_rpc_alter_context(TALLOC_CTX *mem_ctx, status = create_bind_or_alt_ctx_internal(mem_ctx, DCERPC_PKT_ALTER, rpc_call_id, + assoc, + conn, + pres_context_id, abstract, transfer, &auth_info, @@ -1960,8 +2075,13 @@ struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx, struct rpc_pipe_bind_state *state; struct cli_credentials *creds = NULL; const char *username = NULL; + enum dcerpc_pkt_type rep_ptype = DCERPC_PKT_BIND_ACK; NTSTATUS status; + if (cli->conn->features.bind_done) { + rep_ptype = DCERPC_PKT_ALTER_RESP; + } + req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state); if (req == NULL) { return NULL; @@ -1974,11 +2094,28 @@ struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx, state->ev = ev; state->cli = cli; - state->rpc_call_id = get_rpc_call_id(); - - cli->client_hdr_signing = true; + state->rpc_call_id = ++cli->assoc->next_call_id; cli->auth = talloc_move(cli, &auth); + if (cli->auth->auth_context_id == UINT32_MAX) { + if (cli->conn->next_auth_context_id == UINT32_MAX) { + tevent_req_nterror(req, NT_STATUS_RPC_NO_MORE_BINDINGS); + return tevent_req_post(req, ev); + } + cli->auth->auth_context_id = cli->conn->next_auth_context_id++; + } + if (cli->pres_context_id == UINT16_MAX) { + if (cli->conn->next_pres_context_id == UINT16_MAX) { + tevent_req_nterror(req, NT_STATUS_RPC_NO_MORE_BINDINGS); + return tevent_req_post(req, ev); + } + cli->pres_context_id = cli->conn->next_pres_context_id++; + } + + cli->binding_handle = rpccli_bh_create(cli, NULL, cli->table); + if (tevent_req_nomem(cli->binding_handle, req)) { + return tevent_req_post(req, ev); + } creds = gensec_get_credentials(cli->auth->auth_ctx); username = cli_credentials_get_username(creds); @@ -1991,7 +2128,7 @@ struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx, status = create_rpc_bind_req(state, cli, cli->auth, state->rpc_call_id, - &cli->abstract_syntax, + &cli->table->syntax_id, &cli->transfer_syntax, &state->rpc_out); @@ -2002,7 +2139,7 @@ struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx, } subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out, - DCERPC_PKT_BIND_ACK, state->rpc_call_id); + rep_ptype, state->rpc_call_id); if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); } @@ -2043,14 +2180,12 @@ static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq) return; } - if (pkt->ptype == DCERPC_PKT_BIND_ACK) { - if (pkt->pfc_flags & DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN) { - state->cli->hdr_signing = true; - } + if (state->cli->conn->features.client_hdr_signing && + pkt->pfc_flags & DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN) + { + state->cli->conn->features.hdr_signing = true; } - state->cli->max_xmit_frag = pkt->u.bind_ack.max_xmit_frag; - if (pauth->auth_type == DCERPC_AUTH_TYPE_NONE) { /* Bind complete. */ tevent_req_done(req); @@ -2062,7 +2197,7 @@ static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq) return; } - pauth->hdr_signing = state->cli->hdr_signing; + pauth->hdr_signing = state->cli->conn->features.hdr_signing; /* get auth credentials */ status = dcerpc_pull_auth_trailer(pkt, talloc_tos(), @@ -2149,7 +2284,10 @@ static NTSTATUS rpc_bind_next_send(struct tevent_req *req, status = create_rpc_alter_context(state, auth, state->rpc_call_id, - &state->cli->abstract_syntax, + state->cli->assoc, + state->cli->conn, + state->cli->pres_context_id, + &state->cli->table->syntax_id, &state->cli->transfer_syntax, auth_token, &state->rpc_out); @@ -2280,8 +2418,17 @@ static bool rpccli_bh_is_connected(struct dcerpc_binding_handle *h) { struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h, struct rpccli_bh_state); - struct rpc_cli_transport *transport = hs->rpc_cli->transport; + struct rpc_cli_transport *transport = NULL; + + if (hs->rpc_cli == NULL) { + return false; + } + if (hs->rpc_cli->conn == NULL) { + return false; + } + + transport = hs->rpc_cli->conn->transport; if (transport == NULL) { return false; } @@ -2298,9 +2445,14 @@ static uint32_t rpccli_bh_set_timeout(struct dcerpc_binding_handle *h, { struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h, struct rpccli_bh_state); - struct rpc_cli_transport *transport = hs->rpc_cli->transport; + struct rpc_cli_transport *transport = NULL; unsigned int old; + if (hs->rpc_cli->conn == NULL) { + return RPCCLI_DEFAULT_TIMEOUT; + } + + transport = hs->rpc_cli->conn->transport; if (transport == NULL) { return RPCCLI_DEFAULT_TIMEOUT; } @@ -2329,11 +2481,15 @@ static NTSTATUS rpccli_bh_transport_session_key(struct dcerpc_binding_handle *h, return NT_STATUS_NO_USER_SESSION_KEY; } - if (hs->rpc_cli->transport_session_key.length == 0) { + if (hs->rpc_cli->conn == NULL) { return NT_STATUS_NO_USER_SESSION_KEY; } - sk = hs->rpc_cli->transport_session_key; + if (hs->rpc_cli->conn->transport_session_key.length == 0) { + return NT_STATUS_NO_USER_SESSION_KEY; + } + + sk = hs->rpc_cli->conn->transport_session_key; sk.length = MIN(sk.length, 16); *session_key = data_blob_dup_talloc(mem_ctx, sk); @@ -2526,7 +2682,7 @@ static struct tevent_req *rpccli_bh_disconnect_send(TALLOC_CTX *mem_ctx, * * For now we do it sync... */ - TALLOC_FREE(hs->rpc_cli->transport); + TALLOC_FREE(hs->rpc_cli->conn); hs->rpc_cli = NULL; tevent_req_done(req); @@ -2593,8 +2749,67 @@ struct dcerpc_binding_handle *rpccli_bh_create(struct rpc_pipe_client *c, struct dcerpc_binding_handle *h = NULL; struct rpccli_bh_state *hs = NULL; struct dcerpc_binding *b = NULL; + uint32_t a_flags = 0; + uint32_t c_flags = 0; NTSTATUS status; + if (c->conn->features.hdr_signing) { + a_flags |= DCERPC_HEADER_SIGNING; + } else { + c_flags |= DCERPC_HEADER_SIGNING; + } + + switch (c->auth->auth_type) { + case DCERPC_AUTH_TYPE_KRB5: + a_flags |= DCERPC_AUTH_KRB5; + c_flags |= DCERPC_AUTH_NTLM; + c_flags |= DCERPC_AUTH_SPNEGO; + c_flags |= DCERPC_SCHANNEL; + break; + case DCERPC_AUTH_TYPE_NTLMSSP: + c_flags |= DCERPC_AUTH_KRB5; + a_flags |= DCERPC_AUTH_NTLM; + c_flags |= DCERPC_AUTH_SPNEGO; + c_flags |= DCERPC_SCHANNEL; + break; + case DCERPC_AUTH_TYPE_SPNEGO: + c_flags |= DCERPC_AUTH_KRB5; + c_flags |= DCERPC_AUTH_NTLM; + a_flags |= DCERPC_AUTH_SPNEGO; + c_flags |= DCERPC_SCHANNEL; + break; + case DCERPC_AUTH_TYPE_SCHANNEL: + c_flags |= DCERPC_AUTH_KRB5; + c_flags |= DCERPC_AUTH_NTLM; + c_flags |= DCERPC_AUTH_SPNEGO; + a_flags |= DCERPC_SCHANNEL; + break; + default: + c_flags |= DCERPC_AUTH_KRB5; + c_flags |= DCERPC_AUTH_NTLM; + c_flags |= DCERPC_AUTH_SPNEGO; + c_flags |= DCERPC_SCHANNEL; + break; + } + + if (c->auth->auth_level >= DCERPC_AUTH_LEVEL_PRIVACY) { + a_flags |= DCERPC_SEAL; + c_flags |= DCERPC_SIGN; + c_flags |= DCERPC_CONNECT; + } else if (c->auth->auth_level >= DCERPC_AUTH_LEVEL_INTEGRITY) { + c_flags |= DCERPC_SEAL; + a_flags |= DCERPC_SIGN; + c_flags |= DCERPC_CONNECT; + } else if (c->auth->auth_level >= DCERPC_AUTH_LEVEL_CONNECT) { + c_flags |= DCERPC_SEAL; + c_flags |= DCERPC_SIGN; + a_flags |= DCERPC_CONNECT; + } else { + c_flags |= DCERPC_SEAL; + c_flags |= DCERPC_SIGN; + c_flags |= DCERPC_CONNECT; + } + h = dcerpc_binding_handle_create(c, &rpccli_bh_ops, object, @@ -2607,27 +2822,17 @@ struct dcerpc_binding_handle *rpccli_bh_create(struct rpc_pipe_client *c, } hs->rpc_cli = c; - status = dcerpc_parse_binding(hs, "", &b); - if (!NT_STATUS_IS_OK(status)) { - TALLOC_FREE(h); - return NULL; - } - status = dcerpc_binding_set_transport(b, c->transport->transport); - if (!NT_STATUS_IS_OK(status)) { + b = dcerpc_binding_dup(h, c->assoc->binding); + if (b == NULL) { TALLOC_FREE(h); return NULL; } - status = dcerpc_binding_set_string_option(b, "host", c->desthost); - if (!NT_STATUS_IS_OK(status)) { - TALLOC_FREE(h); - return NULL; - } - status = dcerpc_binding_set_string_option(b, "target_hostname", c->desthost); + status = dcerpc_binding_set_abstract_syntax(b, &table->syntax_id); if (!NT_STATUS_IS_OK(status)) { TALLOC_FREE(h); return NULL; } - status = dcerpc_binding_set_abstract_syntax(b, &table->syntax_id); + status = dcerpc_binding_set_flags(b, a_flags, c_flags); if (!NT_STATUS_IS_OK(status)) { TALLOC_FREE(h); return NULL; @@ -2652,7 +2857,8 @@ NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx, result->auth_type = DCERPC_AUTH_TYPE_NONE; result->auth_level = DCERPC_AUTH_LEVEL_NONE; - result->auth_context_id = 0; + /* rpc_pipe_bind_send should allocate an id... */ + result->auth_context_id = UINT32_MAX; status = auth_generic_client_prepare(result, &auth_generic_ctx); @@ -2713,7 +2919,8 @@ static NTSTATUS rpccli_generic_bind_data(TALLOC_CTX *mem_ctx, result->auth_type = auth_type; result->auth_level = auth_level; - result->auth_context_id = 1; + /* rpc_pipe_bind_send should allocate an id... */ + result->auth_context_id = UINT32_MAX; status = auth_generic_client_prepare(result, &auth_generic_ctx); @@ -2786,7 +2993,8 @@ static NTSTATUS rpccli_generic_bind_data_from_creds(TALLOC_CTX *mem_ctx, result->auth_type = auth_type; result->auth_level = auth_level; - result->auth_context_id = 1; + /* rpc_pipe_bind_send should allocate an id... */ + result->auth_context_id = UINT32_MAX; status = auth_generic_client_prepare(result, &auth_generic_ctx); @@ -2869,7 +3077,10 @@ static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, return NT_STATUS_RPC_INVALID_ENDPOINT_FORMAT; } - status = rpc_client_connection_create(mem_ctx, &conn); + status = rpc_client_connection_create(mem_ctx, + assoc, + DCERPC_FRAG_MAX_SIZE, + &conn); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -3096,6 +3307,8 @@ static NTSTATUS rpc_pipe_get_tcp_port(const char *host, } status = rpc_client_association_create(frame, + default_bt_features, + DCERPC_PROPOSE_HEADER_SIGNING, host, NCACN_IP_TCP, saddr, @@ -3268,6 +3481,8 @@ NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, TALLOC_FREE(socket_name); status = rpc_client_association_create(mem_ctx, + 0, /* no client_features */ + 0, /* flags */ myname, NCALRPC, &saddr, @@ -3279,7 +3494,10 @@ NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, } talloc_steal(frame, assoc); - status = rpc_client_connection_create(mem_ctx, &conn); + status = rpc_client_connection_create(mem_ctx, + assoc, + DCERPC_FRAG_MAX_SIZE, + &conn); if (!NT_STATUS_IS_OK(status)) { TALLOC_FREE(frame); return status; @@ -3375,6 +3593,8 @@ NTSTATUS rpc_pipe_open_local_np( } status = rpc_client_association_create(mem_ctx, + 0, /* no client_features */ + 0, /* flags */ local_server_name, NCACN_NP, &saddr, @@ -3386,7 +3606,10 @@ NTSTATUS rpc_pipe_open_local_np( } talloc_steal(frame, assoc); - status = rpc_client_connection_create(mem_ctx, &conn); + status = rpc_client_connection_create(mem_ctx, + assoc, + DCERPC_FRAG_MAX_SIZE, + &conn); if (!NT_STATUS_IS_OK(status)) { TALLOC_FREE(frame); return status; @@ -3499,7 +3722,10 @@ static struct tevent_req *rpc_client_connection_np_send( return tevent_req_post(req, ev); } - status = rpc_client_connection_create(state, &state->conn); + status = rpc_client_connection_create(state, + assoc, + TSTREAM_SMBXCLI_NP_MAX_BUF_SIZE, + &state->conn); if (tevent_req_nterror(req, status)) { return tevent_req_post(req, ev); } @@ -3633,6 +3859,8 @@ struct tevent_req *rpc_pipe_open_np_send( } status = rpc_client_association_create(state, + default_bt_features, + DCERPC_PROPOSE_HEADER_SIGNING, remote_name, NCACN_NP, &saddr, @@ -3763,6 +3991,8 @@ static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli, } status = rpc_client_association_create(NULL, + default_bt_features, + DCERPC_PROPOSE_HEADER_SIGNING, remote_name, transport, &saddr, diff --git a/source3/rpc_client/rpc_client.h b/source3/rpc_client/rpc_client.h index 4cc037d567cb..ab3de01543b3 100644 --- a/source3/rpc_client/rpc_client.h +++ b/source3/rpc_client/rpc_client.h @@ -59,29 +59,12 @@ struct rpc_pipe_client { struct rpc_client_connection *conn; struct pipe_auth_data *auth; - DATA_BLOB transport_session_key; - struct rpc_cli_transport *transport; - - /* - * This is per connection - */ - bool client_hdr_signing; - bool hdr_signing; - - /* - * This is per association_group, but - * for now we only have one connection - * per association_group. - */ - uint16_t bind_time_features; - - struct ndr_syntax_id abstract_syntax; + uint16_t pres_context_id; + const struct ndr_interface_table *table; struct ndr_syntax_id transfer_syntax; bool verified_pcontext; - uint16_t max_xmit_frag; - - SOURCE3_LIBRPC_INTERNALS_END; + SOURCE3_LIBRPC_INTERNALS_END }; #endif /* _RPC_CLIENT_H */ -- 2.49.0 From 73bc73285c2e15d4e9adb060ea667b162913e670 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 17 Sep 2024 05:54:05 +0200 Subject: [PATCH 68/80] s3:rpc_client: add cli_rpc_pipe_client_prepare_alter() helper This will allow to do an alter context if security context multiplexing is negotiated or opening a new connection in the same association group. The old connection will be kept open, but not used anymore... Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit dd7980841593d18081216e6eb3e1b0fb9bd9c757) --- source3/rpc_client/cli_pipe.c | 81 +++++++++++++++++++++++++++++++++++ source3/rpc_client/cli_pipe.h | 5 +++ 2 files changed, 86 insertions(+) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 1d48dab85b3c..143a91138331 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -4045,6 +4045,87 @@ static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli, return NT_STATUS_OK; } +static NTSTATUS cli_rpc_pipe_client_reconnect(struct rpc_pipe_client *p) +{ + enum dcerpc_transport_t transport = + dcerpc_binding_get_transport(p->assoc->binding); + NTSTATUS status; + + switch (transport) { + case NCACN_IP_TCP: + status = rpc_pipe_open_tcp_port(p, + p->assoc, + &p->conn); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + break; + case NCACN_NP: + status = rpc_client_connection_np(p->np_cli, + p->assoc, + &p->conn); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + talloc_steal(p, p->conn); + break; + default: + return NT_STATUS_NOT_IMPLEMENTED; + } + + return NT_STATUS_OK; +} + +NTSTATUS cli_rpc_pipe_client_prepare_alter(struct rpc_pipe_client *p, + bool new_auth_context, + const struct ndr_interface_table *table, + bool new_pres_context) +{ + uint32_t f = p->assoc->features.negotiated; + NTSTATUS status; + + if (!new_auth_context && !new_pres_context) { + return NT_STATUS_INVALID_PARAMETER_MIX; + } + + TALLOC_FREE(p->binding_handle); + + if (new_auth_context) { + p->auth = NULL; + } + + if (new_auth_context && + !(f & DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING)) + { + /* + * new auth context without + * security context multiplexing. + * + * We need to create a new transport + * connection is the same association + * group + * + * We need to keep the old connection alive + * in order to connect to the existing association + * group..., so no TALLOC_FREE(p->conn) + */ + p->conn = NULL; + status = cli_rpc_pipe_client_reconnect(p); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + } + + if (new_pres_context) { + /* rpc_pipe_bind_send should allocate an id... */ + p->pres_context_id = UINT16_MAX; + p->table = table; + p->transfer_syntax = ndr_transfer_syntax_ndr; + } + + return NT_STATUS_OK; +} + /**************************************************************************** Open a named pipe to an SMB server and bind anonymously. ****************************************************************************/ diff --git a/source3/rpc_client/cli_pipe.h b/source3/rpc_client/cli_pipe.h index 9dc46e755ead..006a30684b0a 100644 --- a/source3/rpc_client/cli_pipe.h +++ b/source3/rpc_client/cli_pipe.h @@ -81,6 +81,11 @@ NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli, const struct ndr_interface_table *table, struct rpc_pipe_client **presult); +NTSTATUS cli_rpc_pipe_client_prepare_alter(struct rpc_pipe_client *p, + bool new_auth_context, + const struct ndr_interface_table *table, + bool new_pres_context); + NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli, enum dcerpc_transport_t transport, const struct ndr_interface_table *table, -- 2.49.0 From 7daa2ed44fdbce43d5e9738785cf143b68466a2f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 17 Sep 2024 04:23:40 +0200 Subject: [PATCH 69/80] s3:rpc_client: split out cli_rpc_pipe_client_auth_schannel() This will allow us to use it without creating a new association group and transport connection. Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 14fe854ec5379c422e805cde6ed6290f86ad66db) --- source3/rpc_client/cli_pipe.c | 72 ++++++++++++++++++++++------------- source3/rpc_client/cli_pipe.h | 4 ++ 2 files changed, 49 insertions(+), 27 deletions(-) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 143a91138331..e231d5875a52 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -4266,40 +4266,27 @@ NTSTATUS cli_rpc_pipe_open_with_creds(struct cli_state *cli, return status; } -NTSTATUS cli_rpc_pipe_open_bind_schannel( - struct cli_state *cli, +NTSTATUS cli_rpc_pipe_client_auth_schannel( + struct rpc_pipe_client *rpccli, const struct ndr_interface_table *table, - enum dcerpc_transport_t transport, - struct netlogon_creds_cli_context *netlogon_creds, - const char *remote_name, - const struct sockaddr_storage *remote_sockaddr, - struct rpc_pipe_client **_rpccli) + struct netlogon_creds_cli_context *netlogon_creds) { - struct rpc_pipe_client *rpccli; - struct pipe_auth_data *rpcauth; + TALLOC_CTX *frame = talloc_stackframe(); + struct pipe_auth_data *rpcauth = NULL; const char *target_service = table->authservices->names[0]; - struct cli_credentials *cli_creds; + struct cli_credentials *cli_creds = NULL; enum dcerpc_AuthLevel auth_level; NTSTATUS status; - status = cli_rpc_pipe_open(cli, - transport, - table, - remote_name, - remote_sockaddr, - &rpccli); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - auth_level = netlogon_creds_cli_auth_level(netlogon_creds); - status = netlogon_creds_bind_cli_credentials( - netlogon_creds, rpccli, &cli_creds); + status = netlogon_creds_bind_cli_credentials(netlogon_creds, + frame, + &cli_creds); if (!NT_STATUS_IS_OK(status)) { DBG_DEBUG("netlogon_creds_bind_cli_credentials failed: %s\n", nt_errstr(status)); - TALLOC_FREE(rpccli); + TALLOC_FREE(frame); return status; } @@ -4313,16 +4300,47 @@ NTSTATUS cli_rpc_pipe_open_bind_schannel( if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("rpccli_generic_bind_data_from_creds returned %s\n", nt_errstr(status))); - TALLOC_FREE(rpccli); + TALLOC_FREE(frame); return status; } status = rpc_pipe_bind(rpccli, rpcauth); + if (!NT_STATUS_IS_OK(status)) { + DBG_DEBUG("rpc_pipe_bind failed with error %s\n", + nt_errstr(status)); + TALLOC_FREE(frame); + return status; + } + + TALLOC_FREE(frame); + return NT_STATUS_OK; +} + +NTSTATUS cli_rpc_pipe_open_bind_schannel( + struct cli_state *cli, + const struct ndr_interface_table *table, + enum dcerpc_transport_t transport, + struct netlogon_creds_cli_context *netlogon_creds, + const char *remote_name, + const struct sockaddr_storage *remote_sockaddr, + struct rpc_pipe_client **_rpccli) +{ + struct rpc_pipe_client *rpccli = NULL; + NTSTATUS status; - /* No TALLOC_FREE, gensec takes references */ - talloc_unlink(rpccli, cli_creds); - cli_creds = NULL; + status = cli_rpc_pipe_open(cli, + transport, + table, + remote_name, + remote_sockaddr, + &rpccli); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + status = cli_rpc_pipe_client_auth_schannel(rpccli, + table, + netlogon_creds); if (!NT_STATUS_IS_OK(status)) { DBG_DEBUG("rpc_pipe_bind failed with error %s\n", nt_errstr(status)); diff --git a/source3/rpc_client/cli_pipe.h b/source3/rpc_client/cli_pipe.h index 006a30684b0a..2639cba884f0 100644 --- a/source3/rpc_client/cli_pipe.h +++ b/source3/rpc_client/cli_pipe.h @@ -109,6 +109,10 @@ NTSTATUS cli_rpc_pipe_open_with_creds(struct cli_state *cli, struct cli_credentials *creds, struct rpc_pipe_client **presult); +NTSTATUS cli_rpc_pipe_client_auth_schannel( + struct rpc_pipe_client *rpccli, + const struct ndr_interface_table *table, + struct netlogon_creds_cli_context *netlogon_creds); NTSTATUS cli_rpc_pipe_open_bind_schannel( struct cli_state *cli, const struct ndr_interface_table *table, -- 2.49.0 From f66c98c10b08cf5fd4ef7b01f5faecdeb6c8d07c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 27 Sep 2024 12:00:59 +0200 Subject: [PATCH 70/80] s3:rpc_client: add missing TALLOC_FREE(frame) in cli_rpc_pipe_open() This was missing in commit 637a8e5270fefaea5c61921d4b6ecfc4455a91aa. Signed-off-by: Stefan Metzmacher Reviewed-by: Volker Lendecke (cherry picked from commit c3222192a40a2b1608c9c48f0352cb6f18f26d79) --- source3/rpc_client/cli_pipe.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index e231d5875a52..d512dde386f6 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -3983,6 +3983,7 @@ static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli, table, &port); if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(frame); return status; } -- 2.49.0 From 95c2479eeb9748e9d17dec51a6a88f1c3e7a6544 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Oct 2024 12:52:15 +0200 Subject: [PATCH 71/80] s3:rpc_client: remember the local/remote ipv4 or ipv6 addresses Signed-off-by: Stefan Metzmacher Reviewed-by: Andreas Schneider (cherry picked from commit b6123197d13b5350b8fc88e9c8d59f0f05c3aed6) --- source3/rpc_client/cli_pipe.c | 62 +++++++++++++++++++++++++++++++---- 1 file changed, 56 insertions(+), 6 deletions(-) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index d512dde386f6..188b7fe28385 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -80,6 +80,7 @@ static NTSTATUS rpc_client_association_create(TALLOC_CTX *mem_ctx, { struct rpc_client_association *assoc = NULL; struct dcerpc_binding *bd = NULL; + char addrstr[INET6_ADDRSTRLEN] = { 0, }; NTSTATUS status; assoc = talloc_zero(mem_ctx, struct rpc_client_association); @@ -106,12 +107,29 @@ static NTSTATUS rpc_client_association_create(TALLOC_CTX *mem_ctx, TALLOC_FREE(assoc); return status; } - status = dcerpc_binding_set_string_option(bd, - "host", - target_hostname); - if (!NT_STATUS_IS_OK(status)) { - TALLOC_FREE(assoc); - return status; + switch (addr->u.sa.sa_family) { + case AF_INET: + case AF_INET6: + print_sockaddr(addrstr, + sizeof(addrstr), + &addr->u.ss); + status = dcerpc_binding_set_string_option(bd, + "host", + addrstr); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(assoc); + return status; + } + break; + default: + status = dcerpc_binding_set_string_option(bd, + "host", + target_hostname); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(assoc); + return status; + } + break; } status = dcerpc_binding_set_string_option(bd, "target_hostname", @@ -143,6 +161,7 @@ static NTSTATUS rpc_client_association_create(TALLOC_CTX *mem_ctx, struct rpc_client_connection { DATA_BLOB transport_session_key; struct rpc_cli_transport *transport; + struct samba_sockaddr localaddr; struct { uint16_t max_xmit_frag; @@ -2749,6 +2768,7 @@ struct dcerpc_binding_handle *rpccli_bh_create(struct rpc_pipe_client *c, struct dcerpc_binding_handle *h = NULL; struct rpccli_bh_state *hs = NULL; struct dcerpc_binding *b = NULL; + char localaddr[INET6_ADDRSTRLEN] = { 0, }; uint32_t a_flags = 0; uint32_t c_flags = 0; NTSTATUS status; @@ -2838,6 +2858,22 @@ struct dcerpc_binding_handle *rpccli_bh_create(struct rpc_pipe_client *c, return NULL; } + switch (c->conn->localaddr.u.sa.sa_family) { + case AF_INET: + case AF_INET6: + print_sockaddr(localaddr, + sizeof(localaddr), + &c->conn->localaddr.u.ss); + status = dcerpc_binding_set_string_option(b, + "localaddress", + localaddr); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(h); + return NULL; + } + break; + } + hs->binding = b; return h; @@ -3061,6 +3097,7 @@ static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, uint16_t port; NTSTATUS status; int fd; + int ret; transport = dcerpc_binding_get_transport(assoc->binding); if (transport != NCACN_IP_TCP) { @@ -3092,6 +3129,15 @@ static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, } set_socket_options(fd, lp_socket_options()); + conn->localaddr.sa_socklen = sizeof(conn->localaddr.u.ss); + ret = getsockname(fd, &conn->localaddr.u.sa, &conn->localaddr.sa_socklen); + if (ret != 0) { + status = map_nt_error_from_unix_common(errno); + close(fd); + TALLOC_FREE(conn); + return status; + } + status = rpc_transport_sock_init(conn, fd, &conn->transport); if (!NT_STATUS_IS_OK(status)) { close(fd); @@ -3700,6 +3746,7 @@ static struct tevent_req *rpc_client_connection_np_send( struct rpc_client_connection_np_state *state = NULL; enum dcerpc_transport_t transport; const char *endpoint = NULL; + const struct sockaddr_storage *local_sockaddr = NULL; struct smbXcli_session *session = NULL; NTSTATUS status; @@ -3730,6 +3777,9 @@ static struct tevent_req *rpc_client_connection_np_send( return tevent_req_post(req, ev); } + local_sockaddr = smbXcli_conn_local_sockaddr(cli->conn); + state->conn->localaddr.u.ss = *local_sockaddr; + if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) { session = cli->smb2.session; } else { -- 2.49.0 From af550308d59561dcfa3c16290f0c693352e4b573 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 6 Nov 2024 14:16:27 +0100 Subject: [PATCH 72/80] s3:cli_pipe: pass target_service to cli_rpc_pipe_open_with_creds() Signed-off-by: Stefan Metzmacher Reviewed-by: Andreas Schneider --- source3/libsmb/passchange.c | 1 + source3/rpc_client/cli_pipe.c | 16 +++++++++++----- source3/rpc_client/cli_pipe.h | 3 ++- source3/rpcclient/rpcclient.c | 1 + source3/utils/net_rpc.c | 1 + source3/winbindd/winbindd_cm.c | 2 ++ 6 files changed, 18 insertions(+), 6 deletions(-) diff --git a/source3/libsmb/passchange.c b/source3/libsmb/passchange.c index 3231d0bfff2d..e7482173cef7 100644 --- a/source3/libsmb/passchange.c +++ b/source3/libsmb/passchange.c @@ -163,6 +163,7 @@ NTSTATUS remote_password_change(const char *remote_machine, NCACN_NP, DCERPC_AUTH_TYPE_NTLMSSP, DCERPC_AUTH_LEVEL_PRIVACY, + NULL, /* target_service */ remote_machine, remote_sockaddr, creds, diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 188b7fe28385..4c70c406dbde 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -4265,20 +4265,24 @@ NTSTATUS cli_rpc_pipe_open_with_creds(struct cli_state *cli, enum dcerpc_transport_t transport, enum dcerpc_AuthType auth_type, enum dcerpc_AuthLevel auth_level, - const char *server, + const char *target_service, + const char *target_hostname, const struct sockaddr_storage *remote_sockaddr, struct cli_credentials *creds, struct rpc_pipe_client **presult) { struct rpc_pipe_client *result; struct pipe_auth_data *auth = NULL; - const char *target_service = table->authservices->names[0]; NTSTATUS status; + if (target_service == NULL) { + target_service = table->authservices->names[0]; + } + status = cli_rpc_pipe_open(cli, transport, table, - server, + target_hostname, remote_sockaddr, &result); if (!NT_STATUS_IS_OK(status)) { @@ -4286,8 +4290,10 @@ NTSTATUS cli_rpc_pipe_open_with_creds(struct cli_state *cli, } status = rpccli_generic_bind_data_from_creds(result, - auth_type, auth_level, - server, target_service, + auth_type, + auth_level, + target_hostname, + target_service, creds, &auth); if (!NT_STATUS_IS_OK(status)) { diff --git a/source3/rpc_client/cli_pipe.h b/source3/rpc_client/cli_pipe.h index 2639cba884f0..d6e472afcf6d 100644 --- a/source3/rpc_client/cli_pipe.h +++ b/source3/rpc_client/cli_pipe.h @@ -104,7 +104,8 @@ NTSTATUS cli_rpc_pipe_open_with_creds(struct cli_state *cli, enum dcerpc_transport_t transport, enum dcerpc_AuthType auth_type, enum dcerpc_AuthLevel auth_level, - const char *server, + const char *target_service, + const char *target_hostname, const struct sockaddr_storage *remote_sockaddr, struct cli_credentials *creds, struct rpc_pipe_client **presult); diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c index 95b6baf32b03..b81020482e6a 100644 --- a/source3/rpcclient/rpcclient.c +++ b/source3/rpcclient/rpcclient.c @@ -958,6 +958,7 @@ static NTSTATUS do_cmd(struct cli_state *cli, transport, auth_type, auth_level, + NULL, /* target_service */ remote_name, remote_sockaddr, creds, diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index 4e4de84b6e39..86cd9a5600b8 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -214,6 +214,7 @@ int run_rpc_command(struct net_context *c, NCACN_IP_TCP : NCACN_NP, DCERPC_AUTH_TYPE_NTLMSSP, DCERPC_AUTH_LEVEL_PRIVACY, + NULL, /* target_service */ smbXcli_conn_remote_name(cli->conn), smbXcli_conn_remote_sockaddr(cli->conn), c->creds, &pipe_hnd); diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c index 9d59876970a8..e07b6fb0f321 100644 --- a/source3/winbindd/winbindd_cm.c +++ b/source3/winbindd/winbindd_cm.c @@ -2639,6 +2639,7 @@ NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, NCACN_NP, DCERPC_AUTH_TYPE_SPNEGO, conn->auth_level, + NULL, /* target_service */ remote_name, remote_sockaddr, creds, @@ -2974,6 +2975,7 @@ NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, (conn->cli, &ndr_table_lsarpc, NCACN_NP, DCERPC_AUTH_TYPE_SPNEGO, conn->auth_level, + NULL, /* target_service */ remote_name, remote_sockaddr, creds, -- 2.49.0 From 85665dcbca68d939d652f7e8239f7ec05caa589d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 12 Feb 2025 12:35:20 +0100 Subject: [PATCH 73/80] s3:rpc_client: Add cli_rpc_pipe_reopen_np_noauth() BUG: https://bugzilla.samba.org/show_bug.cgi?id=15680 Signed-off-by: Stefan Metzmacher Reviewed-by: Andreas Schneider (cherry picked from commit d2ac6221db48b93581d7ce48d31f8851c88b77bc) (cherry picked from commit 60dc107d2a6154bf3254218e10b91c2a91ee88d9) --- source3/rpc_client/cli_pipe.c | 88 +++++++++++++++++++++++++++++++++++ source3/rpc_client/cli_pipe.h | 2 + 2 files changed, 90 insertions(+) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 4c70c406dbde..46cd8390a28e 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -4254,6 +4254,94 @@ NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli, presult); } +/**************************************************************************** + * Reopen a connection with the same parameters. + * + * This is useful if we try an RPC function the server doesn't know about and + * disconnects us. + ****************************************************************************/ +NTSTATUS cli_rpc_pipe_reopen_np_noauth(struct rpc_pipe_client *rpccli) +{ + TALLOC_CTX *frame = talloc_stackframe(); + enum dcerpc_transport_t transport; + struct cli_state *cli = NULL; + struct rpc_client_association *assoc = NULL; + struct rpc_client_connection *new_conn = NULL; + struct pipe_auth_data *new_auth = NULL; + NTSTATUS status; + + if (rpccli->assoc == NULL) { + TALLOC_FREE(frame); + return NT_STATUS_INVALID_PARAMETER_MIX; + } + + transport = dcerpc_binding_get_transport(rpccli->assoc->binding); + if (transport != NCACN_NP) { + TALLOC_FREE(frame); + return NT_STATUS_INVALID_PARAMETER_MIX; + } + + if (rpccli->np_cli == NULL) { + TALLOC_FREE(frame); + return NT_STATUS_INVALID_PARAMETER_MIX; + } + cli = rpccli->np_cli; + + /* + * close the old connection + */ + TALLOC_FREE(rpccli->conn); + + /* + * Free the auth context + */ + TALLOC_FREE(rpccli->auth); + + /* + * Reset the association + */ + assoc = talloc_move(frame, &rpccli->assoc); + status = dcerpc_binding_set_assoc_group_id(assoc->binding, 0); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + assoc->features.negotiated = 0; + if (assoc->features.client != 0) { + assoc->features.negotiation_done = false; + } + assoc->next_call_id = 0; + + status = rpc_client_connection_np(cli, + assoc, + &new_conn); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(frame); + return status; + } + + rpccli->assoc = talloc_move(rpccli, &assoc); + rpccli->conn = talloc_move(rpccli, &new_conn); + + /* rpc_pipe_bind_send should allocate an id... */ + rpccli->pres_context_id = UINT16_MAX; + rpccli->verified_pcontext = false; + + status = rpccli_anon_bind_data(rpccli, &new_auth); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(frame); + return status; + } + + status = rpc_pipe_bind(rpccli, new_auth); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(frame); + return status; + } + + TALLOC_FREE(frame); + return NT_STATUS_OK; +} + /**************************************************************************** Open a named pipe to an SMB server and bind using the mech specified diff --git a/source3/rpc_client/cli_pipe.h b/source3/rpc_client/cli_pipe.h index d6e472afcf6d..e90dd3b94467 100644 --- a/source3/rpc_client/cli_pipe.h +++ b/source3/rpc_client/cli_pipe.h @@ -81,6 +81,8 @@ NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli, const struct ndr_interface_table *table, struct rpc_pipe_client **presult); +NTSTATUS cli_rpc_pipe_reopen_np_noauth(struct rpc_pipe_client *rpccli); + NTSTATUS cli_rpc_pipe_client_prepare_alter(struct rpc_pipe_client *p, bool new_auth_context, const struct ndr_interface_table *table, -- 2.49.0 From 9ac8229eb4f5010201f210f453a90046c87c6d12 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 12 Feb 2025 14:17:30 +0100 Subject: [PATCH 74/80] s3:rpc_cerver: Use dcerpc_lsa_open_policy3() for internal RPC BUG: https://bugzilla.samba.org/show_bug.cgi?id=15680 Signed-off-by: Stefan Metzmacher Reviewed-by: Andreas Schneider (cherry picked from commit 0c68d9bc0cd5873f7b59be0fe93d64d6d47b5a57) (cherry picked from commit d0420684649383ffbd309d23c69a0bf8a051fc06) --- source3/rpc_server/netlogon/srv_netlog_nt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c index 2ba16d423e3c..e5abcbdbd84c 100644 --- a/source3/rpc_server/netlogon/srv_netlog_nt.c +++ b/source3/rpc_server/netlogon/srv_netlog_nt.c @@ -460,7 +460,7 @@ NTSTATUS _netr_NetrEnumerateTrustedDomains(struct pipes_struct *p, return status; } - status = dcerpc_lsa_open_policy_fallback( + status = dcerpc_lsa_open_policy3( h, p->mem_ctx, NULL, -- 2.49.0 From 507a3984add4ab4a3e41c99d3737dd4b7123d89d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 12 Feb 2025 12:45:19 +0100 Subject: [PATCH 75/80] s3:rpc_client: Use cli_rpc_pipe_reopen_np_noauth() for OpenPolicy fallback BUG: https://bugzilla.samba.org/show_bug.cgi?id=15680 Signed-off-by: Stefan Metzmacher Reviewed-by: Andreas Schneider (cherry picked from commit 3bbe35d42c4d4a0ce663580dfb035b6beb329ebb) (cherry picked from commit 1a3be37e0eb564604b20c5d2ab1842661d466433) --- source3/lib/netapi/localgroup.c | 2 +- source3/rpc_client/cli_lsarpc.c | 15 ++++++++++- source3/rpc_client/cli_lsarpc.h | 4 +-- source3/rpcclient/cmd_lsarpc.c | 48 ++++++++++++++++----------------- source3/utils/net_rpc.c | 6 ++--- source3/utils/net_rpc_rights.c | 4 +-- source3/utils/net_rpc_trust.c | 2 +- source3/winbindd/winbindd_cm.c | 2 +- source3/wscript_build | 2 +- 9 files changed, 49 insertions(+), 36 deletions(-) diff --git a/source3/lib/netapi/localgroup.c b/source3/lib/netapi/localgroup.c index a63fca4366ab..db72b1d15b6c 100644 --- a/source3/lib/netapi/localgroup.c +++ b/source3/lib/netapi/localgroup.c @@ -984,7 +984,7 @@ static NTSTATUS libnetapi_lsa_lookup_names3(TALLOC_CTX *mem_ctx, init_lsa_String(&names, name); status = dcerpc_lsa_open_policy_fallback( - b, + lsa_pipe, mem_ctx, lsa_pipe->srv_name_slash, false, diff --git a/source3/rpc_client/cli_lsarpc.c b/source3/rpc_client/cli_lsarpc.c index cf2572ed61cf..fcb0e9b0f1e8 100644 --- a/source3/rpc_client/cli_lsarpc.c +++ b/source3/rpc_client/cli_lsarpc.c @@ -24,6 +24,7 @@ #include "includes.h" #include "rpc_client/rpc_client.h" +#include "rpc_client/cli_pipe.h" #include "../librpc/gen_ndr/ndr_lsa_c.h" #include "rpc_client/cli_lsarpc.h" #include "rpc_client/init_lsa.h" @@ -167,7 +168,7 @@ NTSTATUS dcerpc_lsa_open_policy3(struct dcerpc_binding_handle *h, result); } -NTSTATUS dcerpc_lsa_open_policy_fallback(struct dcerpc_binding_handle *h, +NTSTATUS dcerpc_lsa_open_policy_fallback(struct rpc_pipe_client *rpccli, TALLOC_CTX *mem_ctx, const char *srv_name_slash, bool sec_qos, @@ -177,7 +178,9 @@ NTSTATUS dcerpc_lsa_open_policy_fallback(struct dcerpc_binding_handle *h, struct policy_handle *pol, NTSTATUS *result) { + struct dcerpc_binding_handle *h = rpccli->binding_handle; NTSTATUS status; + bool policy2 = false; status = dcerpc_lsa_open_policy3(h, mem_ctx, @@ -189,6 +192,16 @@ NTSTATUS dcerpc_lsa_open_policy_fallback(struct dcerpc_binding_handle *h, pol, result); if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) { + policy2 = true; + } else if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) { + status = cli_rpc_pipe_reopen_np_noauth(rpccli); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + policy2 = true; + } + + if (policy2) { *out_version = 1; *out_revision_info = (union lsa_revision_info) { .info1 = { diff --git a/source3/rpc_client/cli_lsarpc.h b/source3/rpc_client/cli_lsarpc.h index 0a0f399346e6..269dec1ec44d 100644 --- a/source3/rpc_client/cli_lsarpc.h +++ b/source3/rpc_client/cli_lsarpc.h @@ -120,7 +120,7 @@ NTSTATUS dcerpc_lsa_open_policy3(struct dcerpc_binding_handle *h, * This first calls lsa_open_policy3 and falls back to lsa_open_policy2 in case * it isn't implemented. * - * @param[in] h The dcerpc binding handle to use. + * @param[in] rpccli The rpc pipe client structure to use. * * @param[in] mem_ctx The memory context to use. * @@ -139,7 +139,7 @@ NTSTATUS dcerpc_lsa_open_policy3(struct dcerpc_binding_handle *h, * * @return A corresponding NTSTATUS error code for the connection. */ -NTSTATUS dcerpc_lsa_open_policy_fallback(struct dcerpc_binding_handle *h, +NTSTATUS dcerpc_lsa_open_policy_fallback(struct rpc_pipe_client *rpccli, TALLOC_CTX *mem_ctx, const char *srv_name_slash, bool sec_qos, diff --git a/source3/rpcclient/cmd_lsarpc.c b/source3/rpcclient/cmd_lsarpc.c index a5693504cddb..b23e8cf80cdc 100644 --- a/source3/rpcclient/cmd_lsarpc.c +++ b/source3/rpcclient/cmd_lsarpc.c @@ -186,7 +186,7 @@ static NTSTATUS cmd_lsa_query_info_policy(struct rpc_pipe_client *cli, uint32_t out_version = 0; status = dcerpc_lsa_open_policy_fallback( - b, + cli, mem_ctx, cli->srv_name_slash, true, @@ -938,7 +938,7 @@ static NTSTATUS cmd_lsa_create_account(struct rpc_pipe_client *cli, if (!NT_STATUS_IS_OK(status)) goto done; - status = dcerpc_lsa_open_policy_fallback(b, + status = dcerpc_lsa_open_policy_fallback(cli, mem_ctx, cli->srv_name_slash, true, @@ -1004,7 +1004,7 @@ static NTSTATUS cmd_lsa_enum_privsaccounts(struct rpc_pipe_client *cli, if (!NT_STATUS_IS_OK(status)) goto done; - status = dcerpc_lsa_open_policy_fallback(b, + status = dcerpc_lsa_open_policy_fallback(cli, mem_ctx, cli->srv_name_slash, true, @@ -1089,7 +1089,7 @@ static NTSTATUS cmd_lsa_enum_acct_rights(struct rpc_pipe_client *cli, if (!NT_STATUS_IS_OK(status)) goto done; - status = dcerpc_lsa_open_policy_fallback(b, + status = dcerpc_lsa_open_policy_fallback(cli, mem_ctx, cli->srv_name_slash, true, @@ -1156,7 +1156,7 @@ static NTSTATUS cmd_lsa_add_acct_rights(struct rpc_pipe_client *cli, if (!NT_STATUS_IS_OK(status)) goto done; - status = dcerpc_lsa_open_policy_fallback(b, + status = dcerpc_lsa_open_policy_fallback(cli, mem_ctx, cli->srv_name_slash, true, @@ -1227,7 +1227,7 @@ static NTSTATUS cmd_lsa_remove_acct_rights(struct rpc_pipe_client *cli, if (!NT_STATUS_IS_OK(status)) goto done; - status = dcerpc_lsa_open_policy_fallback(b, + status = dcerpc_lsa_open_policy_fallback(cli, mem_ctx, cli->srv_name_slash, true, @@ -1295,7 +1295,7 @@ static NTSTATUS cmd_lsa_lookup_priv_value(struct rpc_pipe_client *cli, return NT_STATUS_OK; } - status = dcerpc_lsa_open_policy_fallback(b, + status = dcerpc_lsa_open_policy_fallback(cli, mem_ctx, cli->srv_name_slash, true, @@ -1358,7 +1358,7 @@ static NTSTATUS cmd_lsa_query_secobj(struct rpc_pipe_client *cli, if (argc == 2) sscanf(argv[1], "%x", &sec_info); - status = dcerpc_lsa_open_policy_fallback(b, + status = dcerpc_lsa_open_policy_fallback(cli, mem_ctx, cli->srv_name_slash, true, @@ -1463,7 +1463,7 @@ static NTSTATUS cmd_lsa_query_trustdominfobysid(struct rpc_pipe_client *cli, if (argc == 3) info_class = atoi(argv[2]); - status = dcerpc_lsa_open_policy_fallback(b, + status = dcerpc_lsa_open_policy_fallback(cli, mem_ctx, cli->srv_name_slash, true, @@ -1532,7 +1532,7 @@ static NTSTATUS cmd_lsa_query_trustdominfobyname(struct rpc_pipe_client *cli, if (argc == 3) info_class = atoi(argv[2]); - status = dcerpc_lsa_open_policy_fallback(b, + status = dcerpc_lsa_open_policy_fallback(cli, mem_ctx, cli->srv_name_slash, true, @@ -1613,7 +1613,7 @@ static NTSTATUS cmd_lsa_set_trustdominfo(struct rpc_pipe_client *cli, return NT_STATUS_INVALID_PARAMETER; } - status = dcerpc_lsa_open_policy_fallback(b, + status = dcerpc_lsa_open_policy_fallback(cli, mem_ctx, cli->srv_name_slash, true, @@ -1691,7 +1691,7 @@ static NTSTATUS cmd_lsa_query_trustdominfo(struct rpc_pipe_client *cli, if (argc == 3) info_class = atoi(argv[2]); - status = dcerpc_lsa_open_policy_fallback(b, + status = dcerpc_lsa_open_policy_fallback(cli, mem_ctx, cli->srv_name_slash, true, @@ -1812,7 +1812,7 @@ static NTSTATUS cmd_lsa_add_priv(struct rpc_pipe_client *cli, goto done; } - status = dcerpc_lsa_open_policy_fallback(b, + status = dcerpc_lsa_open_policy_fallback(cli, mem_ctx, cli->srv_name_slash, true, @@ -1921,7 +1921,7 @@ static NTSTATUS cmd_lsa_del_priv(struct rpc_pipe_client *cli, goto done; } - status = dcerpc_lsa_open_policy_fallback(b, + status = dcerpc_lsa_open_policy_fallback(cli, mem_ctx, cli->srv_name_slash, true, @@ -2022,7 +2022,7 @@ static NTSTATUS cmd_lsa_create_secret(struct rpc_pipe_client *cli, return NT_STATUS_OK; } - status = dcerpc_lsa_open_policy_fallback(b, + status = dcerpc_lsa_open_policy_fallback(cli, mem_ctx, cli->srv_name_slash, true, @@ -2082,7 +2082,7 @@ static NTSTATUS cmd_lsa_delete_secret(struct rpc_pipe_client *cli, return NT_STATUS_OK; } - status = dcerpc_lsa_open_policy_fallback(b, + status = dcerpc_lsa_open_policy_fallback(cli, mem_ctx, cli->srv_name_slash, true, @@ -2161,7 +2161,7 @@ static NTSTATUS cmd_lsa_query_secret(struct rpc_pipe_client *cli, return NT_STATUS_OK; } - status = dcerpc_lsa_open_policy_fallback(b, + status = dcerpc_lsa_open_policy_fallback(cli, mem_ctx, cli->srv_name_slash, true, @@ -2265,7 +2265,7 @@ static NTSTATUS cmd_lsa_set_secret(struct rpc_pipe_client *cli, return NT_STATUS_OK; } - status = dcerpc_lsa_open_policy_fallback(b, + status = dcerpc_lsa_open_policy_fallback(cli, mem_ctx, cli->srv_name_slash, true, @@ -2357,7 +2357,7 @@ static NTSTATUS cmd_lsa_retrieve_private_data(struct rpc_pipe_client *cli, return NT_STATUS_OK; } - status = dcerpc_lsa_open_policy_fallback(b, + status = dcerpc_lsa_open_policy_fallback(cli, mem_ctx, cli->srv_name_slash, true, @@ -2433,7 +2433,7 @@ static NTSTATUS cmd_lsa_store_private_data(struct rpc_pipe_client *cli, return NT_STATUS_OK; } - status = dcerpc_lsa_open_policy_fallback(b, + status = dcerpc_lsa_open_policy_fallback(cli, mem_ctx, cli->srv_name_slash, true, @@ -2504,7 +2504,7 @@ static NTSTATUS cmd_lsa_create_trusted_domain(struct rpc_pipe_client *cli, return NT_STATUS_OK; } - status = dcerpc_lsa_open_policy_fallback(b, + status = dcerpc_lsa_open_policy_fallback(cli, mem_ctx, cli->srv_name_slash, true, @@ -2595,7 +2595,7 @@ static NTSTATUS cmd_lsa_create_trusted_domain_ex3(struct rpc_pipe_client *cli, goto done; } - status = dcerpc_lsa_open_policy_fallback(b, + status = dcerpc_lsa_open_policy_fallback(cli, mem_ctx, cli->srv_name_slash, true, @@ -2710,7 +2710,7 @@ static NTSTATUS cmd_lsa_create_trusted_domain_ex2(struct rpc_pipe_client *cli, goto done; } - status = dcerpc_lsa_open_policy_fallback(b, + status = dcerpc_lsa_open_policy_fallback(cli, mem_ctx, cli->srv_name_slash, true, @@ -2798,7 +2798,7 @@ static NTSTATUS cmd_lsa_delete_trusted_domain(struct rpc_pipe_client *cli, return NT_STATUS_OK; } - status = dcerpc_lsa_open_policy_fallback(b, + status = dcerpc_lsa_open_policy_fallback(cli, mem_ctx, cli->srv_name_slash, true, diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index 86cd9a5600b8..7edb1ef247ae 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -6634,7 +6634,7 @@ static int rpc_trustdom_establish(struct net_context *c, int argc, b = pipe_hnd->binding_handle; - nt_status = dcerpc_lsa_open_policy_fallback(b, + nt_status = dcerpc_lsa_open_policy_fallback(pipe_hnd, frame, pipe_hnd->srv_name_slash, true, @@ -6919,7 +6919,7 @@ static int rpc_trustdom_vampire(struct net_context *c, int argc, b = pipe_hnd->binding_handle; - nt_status = dcerpc_lsa_open_policy_fallback(b, + nt_status = dcerpc_lsa_open_policy_fallback(pipe_hnd, mem_ctx, pipe_hnd->srv_name_slash, false, @@ -7112,7 +7112,7 @@ static int rpc_trustdom_list(struct net_context *c, int argc, const char **argv) b = pipe_hnd->binding_handle; - nt_status = dcerpc_lsa_open_policy_fallback(b, + nt_status = dcerpc_lsa_open_policy_fallback(pipe_hnd, mem_ctx, pipe_hnd->srv_name_slash, true, diff --git a/source3/utils/net_rpc_rights.c b/source3/utils/net_rpc_rights.c index 267ce6576e6f..a3b2a6dc80e4 100644 --- a/source3/utils/net_rpc_rights.c +++ b/source3/utils/net_rpc_rights.c @@ -507,7 +507,7 @@ static NTSTATUS rpc_rights_grant_internal(struct net_context *c, if (!NT_STATUS_IS_OK(status)) goto done; - status = dcerpc_lsa_open_policy_fallback(b, + status = dcerpc_lsa_open_policy_fallback(pipe_hnd, mem_ctx, pipe_hnd->srv_name_slash, true, @@ -593,7 +593,7 @@ static NTSTATUS rpc_rights_revoke_internal(struct net_context *c, if (!NT_STATUS_IS_OK(status)) return status; - status = dcerpc_lsa_open_policy_fallback(b, + status = dcerpc_lsa_open_policy_fallback(pipe_hnd, mem_ctx, pipe_hnd->srv_name_slash, true, diff --git a/source3/utils/net_rpc_trust.c b/source3/utils/net_rpc_trust.c index 4e57d7ce044e..5f89689068a8 100644 --- a/source3/utils/net_rpc_trust.c +++ b/source3/utils/net_rpc_trust.c @@ -235,7 +235,7 @@ static NTSTATUS connect_and_get_info(TALLOC_CTX *mem_ctx, } status = dcerpc_lsa_open_policy_fallback( - (*pipe_hnd)->binding_handle, + (*pipe_hnd), mem_ctx, (*pipe_hnd)->srv_name_slash, false, diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c index e07b6fb0f321..24616980af3c 100644 --- a/source3/winbindd/winbindd_cm.c +++ b/source3/winbindd/winbindd_cm.c @@ -2296,7 +2296,7 @@ static void set_dc_type_and_flags_connect( struct winbindd_domain *domain ) return; } - status = dcerpc_lsa_open_policy_fallback(cli->binding_handle, + status = dcerpc_lsa_open_policy_fallback(cli, mem_ctx, cli->srv_name_slash, true, diff --git a/source3/wscript_build b/source3/wscript_build index 824f961c1ecd..643b1768388f 100644 --- a/source3/wscript_build +++ b/source3/wscript_build @@ -1037,7 +1037,7 @@ bld.SAMBA3_SUBSYSTEM('LIBCLI_SAMR', bld.SAMBA3_LIBRARY('libcli_lsa3', source='rpc_client/cli_lsarpc.c', - deps='RPC_NDR_LSA INIT_LSA', + deps='RPC_NDR_LSA INIT_LSA msrpc3', private_library=True) bld.SAMBA3_LIBRARY('libcli_netlogon3', -- 2.49.0 From 409d0acec3df1a2c7f8022898b2d397e53fd678a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 17 Jul 2024 17:39:24 +0200 Subject: [PATCH 76/80] dcesrv_core: Make dcesrv_call_disconnect_after() public BUG: https://bugzilla.samba.org/show_bug.cgi?id=15680 Signed-off-by: Stefan Metzmacher Reviewed-by: Andreas Schneider (cherry picked from commit a094a29e426cc79e23bb4d866334d7735159fb41) (cherry picked from commit 310b5c9dcecfba72b3b02632fca08a68c042d2c1) --- librpc/rpc/dcesrv_core.c | 4 ++-- librpc/rpc/dcesrv_core.h | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/librpc/rpc/dcesrv_core.c b/librpc/rpc/dcesrv_core.c index 66478001640d..7fb23d49d615 100644 --- a/librpc/rpc/dcesrv_core.c +++ b/librpc/rpc/dcesrv_core.c @@ -783,8 +783,8 @@ static void dcesrv_call_set_list(struct dcesrv_call_state *call, } } -static void dcesrv_call_disconnect_after(struct dcesrv_call_state *call, - const char *reason) +void dcesrv_call_disconnect_after(struct dcesrv_call_state *call, + const char *reason) { struct dcesrv_auth *a = NULL; diff --git a/librpc/rpc/dcesrv_core.h b/librpc/rpc/dcesrv_core.h index 90f5bd21d64b..0b69af575b28 100644 --- a/librpc/rpc/dcesrv_core.h +++ b/librpc/rpc/dcesrv_core.h @@ -566,6 +566,9 @@ NTSTATUS dcesrv_auth_session_key(struct dcesrv_call_state *call, NTSTATUS dcesrv_transport_session_key(struct dcesrv_call_state *call, DATA_BLOB *session_key); +void dcesrv_call_disconnect_after(struct dcesrv_call_state *call, + const char *reason); + /* a useful macro for generating a RPC fault in the backend code */ #define DCESRV_FAULT(code) do { \ dce_call->fault_code = code; \ -- 2.49.0 From b73e57570a17569cf4aa788b51aedcb0b5e0b9f8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 17 Jul 2024 18:11:49 +0200 Subject: [PATCH 77/80] librpc:pyrpc: Allow new authenticated rpc connection on the same transport as the basis_connection BUG: https://bugzilla.samba.org/show_bug.cgi?id=15680 Signed-off-by: Stefan Metzmacher Reviewed-by: Andreas Schneider (cherry picked from commit 2c171fb1b8c88034a98c3aaf052e99ba5dbbafd9) (cherry picked from commit 82aa83142598f99d662fb9f16aa20c5e2f5fafa5) --- source4/librpc/rpc/pyrpc_util.c | 78 +++++++++++++++++++++++++++++---- 1 file changed, 70 insertions(+), 8 deletions(-) diff --git a/source4/librpc/rpc/pyrpc_util.c b/source4/librpc/rpc/pyrpc_util.c index e8de2f39eaeb..66f9562dae3c 100644 --- a/source4/librpc/rpc/pyrpc_util.c +++ b/source4/librpc/rpc/pyrpc_util.c @@ -181,6 +181,8 @@ PyObject *py_dcerpc_interface_init_helper(PyTypeObject *type, PyObject *args, Py struct dcerpc_pipe *base_pipe; PyObject *py_base; PyTypeObject *ClientConnection_Type; + struct loadparm_context *lp_ctx = NULL; + struct cli_credentials *credentials = NULL; py_base = PyImport_ImportModule("samba.dcerpc.base"); if (py_base == NULL) { @@ -225,16 +227,76 @@ PyObject *py_dcerpc_interface_init_helper(PyTypeObject *type, PyObject *args, Py return NULL; } - status = dcerpc_secondary_context(base_pipe, &ret->pipe, table); - if (!NT_STATUS_IS_OK(status)) { - PyErr_SetNTSTATUS(status); - Py_DECREF(ret); - Py_DECREF(py_base); - Py_DECREF(ClientConnection_Type); - return NULL; + if (py_lp_ctx != Py_None) { + lp_ctx = lpcfg_from_py_object(ret->ev, py_lp_ctx); + if (lp_ctx == NULL) { + PyErr_SetString(PyExc_TypeError, "Expected loadparm context"); + Py_DECREF(ret); + return NULL; + } + } + + if (py_credentials != Py_None) { + credentials = cli_credentials_from_py_object(py_credentials); + if (credentials == NULL) { + PyErr_SetString(PyExc_TypeError, "Expected credentials"); + Py_DECREF(ret); + return NULL; + } + } + + if (credentials != NULL) { + struct dcerpc_binding *binding = NULL; + + if (lp_ctx == NULL) { + PyErr_SetString( + PyExc_TypeError, + "Expected a loadparm context together " + "with provided credentials"); + Py_DECREF(ret); + Py_DECREF(py_base); + Py_DECREF(ClientConnection_Type); + return NULL; + } + + status = dcerpc_parse_binding(ret->mem_ctx, + binding_string, + &binding); + if (!NT_STATUS_IS_OK(status)) { + PyErr_SetNTSTATUS(status); + Py_DECREF(ret); + Py_DECREF(py_base); + Py_DECREF(ClientConnection_Type); + return NULL; + } + + status = dcerpc_secondary_auth_connection(base_pipe, + binding, + table, + credentials, + lp_ctx, + ret->mem_ctx, + &ret->pipe); + TALLOC_FREE(binding); + if (!NT_STATUS_IS_OK(status)) { + PyErr_SetNTSTATUS(status); + Py_DECREF(ret); + Py_DECREF(py_base); + Py_DECREF(ClientConnection_Type); + return NULL; + } + } else { + status = dcerpc_secondary_context(base_pipe, &ret->pipe, table); + if (!NT_STATUS_IS_OK(status)) { + PyErr_SetNTSTATUS(status); + Py_DECREF(ret); + Py_DECREF(py_base); + Py_DECREF(ClientConnection_Type); + return NULL; + } + ret->pipe = talloc_steal(ret->mem_ctx, ret->pipe); } - ret->pipe = talloc_steal(ret->mem_ctx, ret->pipe); Py_XDECREF(ClientConnection_Type); Py_XDECREF(py_base); } else { -- 2.49.0 From f895c5fedb7d85796cfd835783c8b5499e5ed458 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Mon, 17 Feb 2025 15:41:06 +0100 Subject: [PATCH 78/80] pidl: Update documentation for DCERPC interface connections https://realpython.com/documenting-python-code/ BUG: https://bugzilla.samba.org/show_bug.cgi?id=15680 Signed-off-by: Andreas Schneider Reviewed-by: Stefan Metzmacher (cherry picked from commit 73ce15e7d5b7ea867849f1aa4fa5390830660f11) (cherry picked from commit 1f84f56c6df0813e488701704daf2174bd0f7eb3) --- pidl/lib/Parse/Pidl/Samba4/Python.pm | 29 +++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/pidl/lib/Parse/Pidl/Samba4/Python.pm b/pidl/lib/Parse/Pidl/Samba4/Python.pm index 63f0f72605d0..9bcdea3b15b5 100644 --- a/pidl/lib/Parse/Pidl/Samba4/Python.pm +++ b/pidl/lib/Parse/Pidl/Samba4/Python.pm @@ -1547,11 +1547,30 @@ sub Interface($$$) $self->pidl(""); my $signature = -"\"$interface->{NAME}(binding, lp_ctx=None, credentials=None) -> connection\\n\" -\"\\n\" -\"binding should be a DCE/RPC binding string (for example: ncacn_ip_tcp:127.0.0.1)\\n\" -\"lp_ctx should be a path to a smb.conf file or a param.LoadParm object\\n\" -\"credentials should be a credentials.Credentials object.\\n\\n\""; +"\"$interface->{NAME}(binding, lp_ctx=None, credentials=None, basis_connection=None) -> connection\\n\" +\"\\n\\n\" +\"Parameters\\n\" +\"----------\\n\" +\"binding : str\\n\" +\" A DCE/RPC binding string (for example: ncacn_ip_tcp:127.0.0.1)\\n\" +\"lp_ctx : param.LoadParm\\n\" +\" Should be a path to a smb.conf file or a param.LoadParm object\\n\" +\"credentials : credentials.Credentials, optional\\n\" +\" A credentials.Credentials object (default is None).\\n\" +\"basis_connection : samba.dcerpc.ClientConnection, optional\\n\" +\" A $interface->{NAME} client connection object (default is None).\\n\" +\"\\n\\n\" +\"Returns\\n\" +\"-------\\n\" +\"samba.dcerpc.ClientConnection\\n\" +\" A ClientConnection object\\n\" +\"\\n\\n\" +\"Raises\\n\" +\"------\\n\" +\"samba.NTSTATUSError\\n\" +\" An NTSTATUS error\\n\" +\"\\n\""; + my $docstring = $self->DocString($interface, $interface->{NAME}); -- 2.49.0 From dcda56834552a6e404629b793cdac7d04d0ff406 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Thu, 13 Feb 2025 10:31:49 +0100 Subject: [PATCH 79/80] python:lsa_utils: Don't use optional arguments for OpenPolicyFallback() BUG: https://bugzilla.samba.org/show_bug.cgi?id=15680 Signed-off-by: Andreas Schneider Reviewed-by: Stefan Metzmacher (cherry picked from commit f9a3fc19f1e212c54351c3f94978e66fceeb8835) (cherry picked from commit 8a7346f6c03dd4f5e8394997e1d118d33c950c35) --- python/samba/lsa_utils.py | 4 ++-- python/samba/netcmd/domain/trust.py | 1 + python/samba/tests/dcerpc/lsa_utils.py | 6 ++++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/python/samba/lsa_utils.py b/python/samba/lsa_utils.py index 043e65f3341b..571beb46c851 100644 --- a/python/samba/lsa_utils.py +++ b/python/samba/lsa_utils.py @@ -35,8 +35,8 @@ def OpenPolicyFallback( system_name: str, in_version: int, in_revision_info: lsa.revision_info1, - sec_qos: bool = False, - access_mask: int = 0, + sec_qos: bool, + access_mask: int, ): attr = lsa.ObjectAttribute() if sec_qos: diff --git a/python/samba/netcmd/domain/trust.py b/python/samba/netcmd/domain/trust.py index 0784fa5e2822..f39d4814a111 100644 --- a/python/samba/netcmd/domain/trust.py +++ b/python/samba/netcmd/domain/trust.py @@ -222,6 +222,7 @@ from samba.lsa_utils import OpenPolicyFallback, CreateTrustedDomainFallback b''.decode('utf-8'), in_version, in_revision_info1, + False, policy_access ) diff --git a/python/samba/tests/dcerpc/lsa_utils.py b/python/samba/tests/dcerpc/lsa_utils.py index 229f57ec5468..fee9a45419bd 100644 --- a/python/samba/tests/dcerpc/lsa_utils.py +++ b/python/samba/tests/dcerpc/lsa_utils.py @@ -79,7 +79,8 @@ from samba.lsa_utils import ( '', in_version, in_revision_info1, - access_mask=security.SEC_FLAG_MAXIMUM_ALLOWED + False, + security.SEC_FLAG_MAXIMUM_ALLOWED ) self.assertIsNotNone(pol_handle) @@ -168,7 +169,8 @@ from samba.lsa_utils import ( '', in_version, in_revision_info1, - access_mask=security.SEC_FLAG_MAXIMUM_ALLOWED + False, + security.SEC_FLAG_MAXIMUM_ALLOWED ) self.assertIsNotNone(pol_handle) -- 2.49.0 From 74934b26b935852981e94eb39b2d3aaf37cf2ebf Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 17 Jul 2024 18:12:31 +0200 Subject: [PATCH 80/80] python:lsa_utils: Fix fallback to OpenPolicy2 BUG: https://bugzilla.samba.org/show_bug.cgi?id=15680 Pair-Programmed-With: Andreas Schneider Signed-off-by: Andreas Schneider Signed-off-by: Stefan Metzmacher Autobuild-User(master): Andreas Schneider Autobuild-Date(master): Mon Feb 17 18:33:15 UTC 2025 on atb-devel-224 (cherry picked from commit a814f5d90a3fb85a94c9516dba224037e8fd76f1) Autobuild-User(v4-22-test): Jule Anger Autobuild-Date(v4-22-test): Thu Feb 20 11:22:18 UTC 2025 on atb-devel-224 (cherry picked from commit 29bd6fe9cbe538b267bf0ed66823cfe8599afb3d) --- python/samba/lsa_utils.py | 63 +++++++++++------- python/samba/netcmd/domain/trust.py | 92 ++++++++++++-------------- python/samba/tests/dcerpc/lsa_utils.py | 45 ++++++++----- 3 files changed, 110 insertions(+), 90 deletions(-) diff --git a/python/samba/lsa_utils.py b/python/samba/lsa_utils.py index 571beb46c851..506dc399c93a 100644 --- a/python/samba/lsa_utils.py +++ b/python/samba/lsa_utils.py @@ -20,24 +20,27 @@ from samba.dcerpc import lsa, drsblobs, misc from samba.ndr import ndr_pack from samba import ( NTSTATUSError, + ntstatus, aead_aes_256_cbc_hmac_sha512, arcfour_encrypt, ) -from samba.ntstatus import ( - NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE -) from samba import crypto from secrets import token_bytes +# FIXME from collections.abc import Callable def OpenPolicyFallback( - conn: lsa.lsarpc, + # new_lsa_conn: Callable[[], lsa.lsarpc], - FIXME the type doesn't work + # with python version 3.6 (CentOS8, SLES15). + new_lsa_conn, system_name: str, in_version: int, in_revision_info: lsa.revision_info1, sec_qos: bool, access_mask: int, ): + conn = new_lsa_conn() + attr = lsa.ObjectAttribute() if sec_qos: qos = lsa.QosInfo() @@ -48,26 +51,38 @@ def OpenPolicyFallback( attr.sec_qos = qos - try: - out_version, out_rev_info, policy = conn.OpenPolicy3( - system_name, - attr, - access_mask, - in_version, - in_revision_info - ) - except NTSTATUSError as e: - if e.args[0] == NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE: - out_version = 1 - out_rev_info = lsa.revision_info1() - out_rev_info.revision = 1 - out_rev_info.supported_features = 0 - - policy = conn.OpenPolicy2(system_name, attr, access_mask) - else: - raise - - return out_version, out_rev_info, policy + open_policy2 = False + if in_revision_info is not None: + try: + out_version, out_rev_info, policy = conn.OpenPolicy3( + system_name, + attr, + access_mask, + in_version, + in_revision_info + ) + except NTSTATUSError as e: + if e.args[0] == ntstatus.NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE: + open_policy2 = True + if e.args[0] == ntstatus.NT_STATUS_ACCESS_DENIED: + # We need a new connection + conn = new_lsa_conn(basis_connection=conn) + + open_policy2 = True + else: + raise + else: + open_policy2 = True + + if open_policy2: + out_version = 1 + out_rev_info = lsa.revision_info1() + out_rev_info.revision = 1 + out_rev_info.supported_features = 0 + + policy = conn.OpenPolicy2(system_name, attr, access_mask) + + return conn, out_version, out_rev_info, policy def CreateTrustedDomainRelax( diff --git a/python/samba/netcmd/domain/trust.py b/python/samba/netcmd/domain/trust.py index f39d4814a111..f3d75f841377 100644 --- a/python/samba/netcmd/domain/trust.py +++ b/python/samba/netcmd/domain/trust.py @@ -125,8 +125,13 @@ from samba.lsa_utils import OpenPolicyFallback, CreateTrustedDomainFallback self.local_creds = local_creds return self.local_server - def new_local_lsa_connection(self): - return lsa.lsarpc(self.local_binding_string, self.local_lp, self.local_creds) + def new_local_lsa_connection(self, basis_connection=None): + return lsa.lsarpc( + self.local_binding_string, + self.local_lp, + self.local_creds, + basis_connection=basis_connection + ) def new_local_netlogon_connection(self): return netlogon.netlogon(self.local_binding_string, self.local_lp, self.local_creds) @@ -203,13 +208,23 @@ from samba.lsa_utils import OpenPolicyFallback, CreateTrustedDomainFallback self.remote_creds = remote_creds return self.remote_server - def new_remote_lsa_connection(self): - return lsa.lsarpc(self.remote_binding_string, self.local_lp, self.remote_creds) + def new_remote_lsa_connection(self, basis_connection=None): + return lsa.lsarpc( + self.remote_binding_string, + self.local_lp, + self.remote_creds, + basis_connection=basis_connection + ) - def new_remote_netlogon_connection(self): - return netlogon.netlogon(self.remote_binding_string, self.local_lp, self.remote_creds) + def new_remote_netlogon_connection(self, basis_connection=None): + return netlogon.netlogon( + self.remote_binding_string, + self.local_lp, + self.remote_creds, + basis_connection=basis_connection + ) - def get_lsa_info(self, conn, policy_access): + def get_lsa_info(self, conn_fn, policy_access): in_version = 1 in_revision_info1 = lsa.revision_info1() in_revision_info1.revision = 1 @@ -217,9 +232,9 @@ from samba.lsa_utils import OpenPolicyFallback, CreateTrustedDomainFallback lsa.LSA_FEATURE_TDO_AUTH_INFO_AES_CIPHER ) - out_version, out_revision_info1, policy = OpenPolicyFallback( - conn, - b''.decode('utf-8'), + conn, out_version, out_revision_info1, policy = OpenPolicyFallback( + conn_fn, + '', in_version, in_revision_info1, False, @@ -228,7 +243,7 @@ from samba.lsa_utils import OpenPolicyFallback, CreateTrustedDomainFallback info = conn.QueryInfoPolicy2(policy, lsa.LSA_POLICY_INFO_DNS) - return (policy, out_version, out_revision_info1, info) + return (conn, policy, out_version, out_revision_info1, info) def get_netlogon_dc_unc(self, conn, server, domain): try: @@ -508,19 +523,15 @@ from samba.lsa_utils import OpenPolicyFallback, CreateTrustedDomainFallback def run(self, domain, sambaopts=None, versionopts=None, localdcopts=None): self.setup_local_server(sambaopts, localdcopts) - try: - local_lsa = self.new_local_lsa_connection() - except RuntimeError as error: - raise self.LocalRuntimeError(self, error, "failed to connect lsa server") - try: local_policy_access = lsa.LSA_POLICY_VIEW_LOCAL_INFORMATION ( + local_lsa, local_policy, local_version, local_revision_info1, local_lsa_info - ) = self.get_lsa_info(local_lsa, local_policy_access) + ) = self.get_lsa_info(self.new_local_lsa_connection, local_policy_access) except RuntimeError as error: raise self.LocalRuntimeError(self, error, "failed to query LSA_POLICY_INFO_DNS") @@ -649,19 +660,16 @@ from samba.lsa_utils import OpenPolicyFallback, CreateTrustedDomainFallback raise CommandError("modification arguments are required, try --help") self.setup_local_server(sambaopts, localdcopts) - try: - local_lsa = self.new_local_lsa_connection() - except RuntimeError as error: - raise self.LocalRuntimeError(self, error, "failed to connect to lsa server") try: local_policy_access = lsa.LSA_POLICY_VIEW_LOCAL_INFORMATION ( + local_lsa, local_policy, local_version, local_revision_info1, local_lsa_info - ) = self.get_lsa_info(local_lsa, local_policy_access) + ) = self.get_lsa_info(self.new_local_lsa_connection, local_policy_access) except RuntimeError as error: raise self.LocalRuntimeError(self, error, "failed to query LSA_POLICY_INFO_DNS") @@ -908,18 +916,15 @@ from samba.lsa_utils import OpenPolicyFallback, CreateTrustedDomainFallback remote_trust_info.trust_attributes |= lsa.LSA_TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL local_server = self.setup_local_server(sambaopts, localdcopts) - try: - local_lsa = self.new_local_lsa_connection() - except RuntimeError as error: - raise self.LocalRuntimeError(self, error, "failed to connect lsa server") try: ( + local_lsa, local_policy, local_version, local_revision_info1, local_lsa_info - ) = self.get_lsa_info(local_lsa, local_policy_access) + ) = self.get_lsa_info(self.new_local_lsa_connection, local_policy_access) except RuntimeError as error: raise self.LocalRuntimeError(self, error, "failed to query LSA_POLICY_INFO_DNS") @@ -933,18 +938,14 @@ from samba.lsa_utils import OpenPolicyFallback, CreateTrustedDomainFallback except RuntimeError as error: raise self.RemoteRuntimeError(self, error, "failed to locate remote server") - try: - remote_lsa = self.new_remote_lsa_connection() - except RuntimeError as error: - raise self.RemoteRuntimeError(self, error, "failed to connect lsa server") - try: ( + remote_lsa, remote_policy, remote_version, remote_revision_info1, remote_lsa_info - ) = self.get_lsa_info(remote_lsa, remote_policy_access) + ) = self.get_lsa_info(self.new_remote_lsa_connection, remote_policy_access) except RuntimeError as error: raise self.RemoteRuntimeError(self, error, "failed to query LSA_POLICY_INFO_DNS") @@ -1297,18 +1298,15 @@ from samba.lsa_utils import OpenPolicyFallback, CreateTrustedDomainFallback remote_policy_access |= lsa.LSA_POLICY_CREATE_SECRET self.setup_local_server(sambaopts, localdcopts) - try: - local_lsa = self.new_local_lsa_connection() - except RuntimeError as error: - raise self.LocalRuntimeError(self, error, "failed to connect lsa server") try: ( + local_lsa, local_policy, local_version, local_revision_info1, local_lsa_info - ) = self.get_lsa_info(local_lsa, local_policy_access) + ) = self.get_lsa_info(self.new_local_lsa_connection, local_policy_access) except RuntimeError as error: raise self.LocalRuntimeError(self, error, "failed to query LSA_POLICY_INFO_DNS") @@ -1338,18 +1336,14 @@ from samba.lsa_utils import OpenPolicyFallback, CreateTrustedDomainFallback except RuntimeError as error: raise self.RemoteRuntimeError(self, error, "failed to locate remote server") - try: - remote_lsa = self.new_remote_lsa_connection() - except RuntimeError as error: - raise self.RemoteRuntimeError(self, error, "failed to connect lsa server") - try: ( + remote_lsa, remote_policy, remote_version, remote_revision_info1, remote_lsa_info - ) = self.get_lsa_info(remote_lsa, remote_policy_access) + ) = self.get_lsa_info(self.new_remote_lsa_connection, remote_policy_access) except RuntimeError as error: raise self.RemoteRuntimeError(self, error, "failed to query LSA_POLICY_INFO_DNS") @@ -1450,18 +1444,15 @@ from samba.lsa_utils import OpenPolicyFallback, CreateTrustedDomainFallback local_policy_access = lsa.LSA_POLICY_VIEW_LOCAL_INFORMATION local_server = self.setup_local_server(sambaopts, localdcopts) - try: - local_lsa = self.new_local_lsa_connection() - except RuntimeError as error: - raise self.LocalRuntimeError(self, error, "failed to connect lsa server") try: ( + local_lsa, local_policy, local_version, local_revision_info1, local_lsa_info - ) = self.get_lsa_info(local_lsa, local_policy_access) + ) = self.get_lsa_info(self.new_local_lsa_connection, local_policy_access) except RuntimeError as error: raise self.LocalRuntimeError(self, error, "failed to query LSA_POLICY_INFO_DNS") @@ -1897,11 +1888,12 @@ from samba.lsa_utils import OpenPolicyFallback, CreateTrustedDomainFallback try: ( + local_lsa, local_policy, local_version, local_revision_info1, local_lsa_info - ) = self.get_lsa_info(local_lsa, local_policy_access) + ) = self.get_lsa_info(self.new_local_lsa_connection, local_policy_access) except RuntimeError as error: raise self.LocalRuntimeError(self, error, "failed to query LSA_POLICY_INFO_DNS") diff --git a/python/samba/tests/dcerpc/lsa_utils.py b/python/samba/tests/dcerpc/lsa_utils.py index fee9a45419bd..8a3e7d242767 100644 --- a/python/samba/tests/dcerpc/lsa_utils.py +++ b/python/samba/tests/dcerpc/lsa_utils.py @@ -35,6 +35,7 @@ from samba.lsa_utils import ( class CreateTrustedDomain(TestCase): + smbencrypt = True def get_user_creds(self): c = Credentials() @@ -47,26 +48,35 @@ from samba.lsa_utils import ( c.set_password(password) return c - def _create_trust_relax(self, smbencrypt=True): + def new_lsa_conn(self, basis_connection=None): creds = self.get_user_creds() - - if smbencrypt: + if self.smbencrypt: creds.set_smb_encryption(SMB_ENCRYPTION_REQUIRED) else: creds.set_smb_encryption(SMB_ENCRYPTION_OFF) lp = self.get_loadparm() - binding_string = ( "ncacn_np:%s" % (samba.tests.env_get_var_value('SERVER')) ) - lsa_conn = lsa.lsarpc(binding_string, lp, creds) - if smbencrypt: + lsa_conn = lsa.lsarpc( + binding_string, + lp, + creds, + basis_connection=basis_connection + ) + + if self.smbencrypt: self.assertTrue(lsa_conn.transport_encrypted()) else: self.assertFalse(lsa_conn.transport_encrypted()) + return lsa_conn + + def _create_trust_relax(self, smbencrypt=True): + self.smbencrypt = smbencrypt + in_version = 1 in_revision_info1 = lsa.revision_info1() in_revision_info1.revision = 1 @@ -74,8 +84,13 @@ from samba.lsa_utils import ( lsa.LSA_FEATURE_TDO_AUTH_INFO_AES_CIPHER ) - out_version, out_revision_info1, pol_handle = OpenPolicyFallback( + ( lsa_conn, + out_version, + out_revision_info1, + pol_handle + ) = OpenPolicyFallback( + self.new_lsa_conn, '', in_version, in_revision_info1, @@ -148,14 +163,7 @@ from samba.lsa_utils import ( self.assertIsNone(trustdom_handle) def _create_trust_fallback(self): - creds = self.get_user_creds() - - lp = self.get_loadparm() - - binding_string = ( - "ncacn_np:%s" % (samba.tests.env_get_var_value('SERVER')) - ) - lsa_conn = lsa.lsarpc(binding_string, lp, creds) + self.smbencrypt = True in_version = 1 in_revision_info1 = lsa.revision_info1() @@ -164,8 +172,13 @@ from samba.lsa_utils import ( lsa.LSA_FEATURE_TDO_AUTH_INFO_AES_CIPHER ) - out_version, out_revision_info1, pol_handle = OpenPolicyFallback( + ( lsa_conn, + out_version, + out_revision_info1, + pol_handle + ) = OpenPolicyFallback( + self.new_lsa_conn, '', in_version, in_revision_info1, -- 2.49.0