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,
local_server_addr,
session_info,
true,
- result,
+ conn,
&npa_stream);
if (ret != 0) {
DBG_DEBUG("local_np_connect for %s and "
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 {