};
/****************************************************************************
- Return the pipe name from the index.
+ Return the pipe name from the interface.
****************************************************************************/
-const char *cli_get_pipe_name(int pipe_idx)
-{
- return &pipe_names[pipe_idx].client_pipe[5];
-}
-
-static const char *cli_get_pipe_name_from_iface(TALLOC_CTX *mem_ctx,
- struct cli_state *cli,
- const struct ndr_syntax_id *interface)
+const char *cli_get_pipe_name_from_iface(TALLOC_CTX *mem_ctx,
+ struct cli_state *cli,
+ const struct ndr_syntax_id *interface)
{
int i;
for (i = 0; pipe_names[i].client_pipe; i++) {
if (ndr_syntax_id_equal(pipe_names[i].abstr_syntax,
interface)) {
- return cli_get_pipe_name(i);
+ return &pipe_names[i].client_pipe[5];
}
}
return NULL;
}
-/****************************************************************************
- Return the pipe idx from the syntax.
- ****************************************************************************/
-int cli_get_pipe_idx(const RPC_IFACE *syntax)
-{
- int i;
- for (i = 0; pipe_names[i].client_pipe; i++) {
- if (ndr_syntax_id_equal(pipe_names[i].abstr_syntax, syntax)) {
- return i;
- }
- }
-
- return -1;
-}
-
-/********************************************************************
- LEGACY function to ease transition from pipe_idx to interface
- ********************************************************************/
-const struct ndr_syntax_id *cli_get_iface(int pipe_idx)
-{
- SMB_ASSERT((pipe_idx >= 0) && (pipe_idx < PI_MAX_PIPES));
- return pipe_names[pipe_idx].abstr_syntax;
-}
-
/********************************************************************
Map internal value to wire value.
********************************************************************/
Read from a RPC named pipe
********************************************************************/
static NTSTATUS rpc_read_np(struct cli_state *cli, const char *pipe_name,
- int fnum, char *buf, off_t offset, size_t size,
+ int fnum, char *buf, size_t size,
ssize_t *pnum_read)
{
ssize_t num_read;
- num_read = cli_read(cli, fnum, buf, offset, size);
+ num_read = cli_read(cli, fnum, buf, 0, size);
- DEBUG(5,("rpc_read_np: num_read = %d, read offset: %u, to read: %u\n",
- (int)num_read, (unsigned int)offset, (unsigned int)size));
+ DEBUG(5,("rpc_read_np: num_read = %d, to read: %u\n", (int)num_read,
+ (unsigned int)size));
/*
* A dos error of ERRDOS/ERRmoredata is not an error.
return NT_STATUS_OK;
}
+/*
+ * Realloc pdu to have a least "size" bytes
+ */
+
+static bool rpc_grow_buffer(prs_struct *pdu, size_t size)
+{
+ size_t extra_size;
+
+ if (prs_data_size(pdu) >= size) {
+ return true;
+ }
+
+ extra_size = size - prs_data_size(pdu);
+
+ if (!prs_force_grow(pdu, extra_size)) {
+ DEBUG(0, ("rpc_grow_buffer: Failed to grow parse struct by "
+ "%d bytes.\n", (int)extra_size));
+ return false;
+ }
+
+ DEBUG(5, ("rpc_grow_buffer: grew buffer by %d bytes to %u\n",
+ (int)extra_size, prs_data_size(pdu)));
+ return true;
+}
+
/*******************************************************************
Use SMBreadX to get rest of one fragment's worth of rpc data.
- Will expand the current_pdu struct to the correct size.
+ Reads the whole size or give an error message
********************************************************************/
static NTSTATUS rpc_read(struct rpc_pipe_client *cli,
prs_struct *current_pdu,
- uint32 data_to_read,
- uint32 *current_pdu_offset)
+ size_t size,
+ uint32 current_pdu_offset)
{
- size_t size = (size_t)cli->max_recv_frag;
- uint32 stream_offset = 0;
ssize_t num_read = 0;
char *pdata;
- ssize_t extra_data_size = ((ssize_t)*current_pdu_offset) + ((ssize_t)data_to_read) - (ssize_t)prs_data_size(current_pdu);
-
- DEBUG(5,("rpc_read: data_to_read: %u current_pdu offset: %u extra_data_size: %d\n",
- (unsigned int)data_to_read, (unsigned int)*current_pdu_offset, (int)extra_data_size ));
-
- /*
- * Grow the buffer if needed to accommodate the data to be read.
- */
- if (extra_data_size > 0) {
- if(!prs_force_grow(current_pdu, (uint32)extra_data_size)) {
- DEBUG(0,("rpc_read: Failed to grow parse struct by %d bytes.\n", (int)extra_data_size ));
- return NT_STATUS_NO_MEMORY;
- }
- DEBUG(5,("rpc_read: grew buffer by %d bytes to %u\n", (int)extra_data_size, prs_data_size(current_pdu) ));
- }
+ DEBUG(5, ("rpc_read: data_to_read: %u current_pdu offset: %d\n",
+ (unsigned int)size, (unsigned int)current_pdu_offset));
- pdata = prs_data_p(current_pdu) + *current_pdu_offset;
+ pdata = prs_data_p(current_pdu) + current_pdu_offset;
- do {
+ while (num_read < size) {
+ ssize_t thistime = 0;
NTSTATUS status;
- /* read data using SMBreadX */
- if (size > (size_t)data_to_read) {
- size = (size_t)data_to_read;
- }
-
switch (cli->transport_type) {
case NCACN_NP:
status = rpc_read_np(cli->trans.np.cli,
cli->trans.np.pipe_name,
- cli->trans.np.fnum, pdata,
- (off_t)stream_offset, size,
- &num_read);
+ cli->trans.np.fnum,
+ pdata + num_read,
+ size - num_read, &thistime);
break;
case NCACN_IP_TCP:
case NCACN_UNIX_STREAM:
status = NT_STATUS_OK;
- num_read = sys_read(cli->trans.sock.fd, pdata, size);
- if (num_read == -1) {
+ thistime = sys_read(cli->trans.sock.fd,
+ pdata + num_read,
+ size - num_read);
+ if (thistime == -1) {
status = map_nt_error_from_unix(errno);
}
- if (num_read == 0) {
- status = NT_STATUS_END_OF_FILE;
- }
break;
default:
DEBUG(0, ("unknown transport type %d\n",
return NT_STATUS_INTERNAL_ERROR;
}
- data_to_read -= num_read;
- stream_offset += num_read;
- pdata += num_read;
+ if (thistime == 0) {
+ status = NT_STATUS_END_OF_FILE;
+ }
- } while (num_read > 0 && data_to_read > 0);
- /* && err == (0x80000000 | STATUS_BUFFER_OVERFLOW)); */
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ num_read += thistime;
+
+ }
- /*
- * Update the current offset into current_pdu by the amount read.
- */
- *current_pdu_offset += stream_offset;
return NT_STATUS_OK;
}
/* Ensure we have at least RPC_HEADER_LEN worth of data to parse. */
if (current_pdu_len < RPC_HEADER_LEN) {
- /* rpc_read expands the current_pdu struct as neccessary. */
- ret = rpc_read(cli, current_pdu, RPC_HEADER_LEN - current_pdu_len, ¤t_pdu_len);
+ if (!rpc_grow_buffer(current_pdu, RPC_HEADER_LEN)) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ ret = rpc_read(cli, current_pdu,
+ RPC_HEADER_LEN - current_pdu_len,
+ current_pdu_len);
if (!NT_STATUS_IS_OK(ret)) {
return ret;
}
+ current_pdu_len = RPC_HEADER_LEN;
}
/* This next call sets the endian bit correctly in current_pdu. */
return NT_STATUS_BUFFER_TOO_SMALL;
}
+ if (prhdr->frag_len > cli->max_recv_frag) {
+ DEBUG(0, ("cli_pipe_get_current_pdu: Server sent fraglen %d,"
+ " we only allow %d\n", (int)prhdr->frag_len,
+ (int)cli->max_recv_frag));
+ return NT_STATUS_BUFFER_TOO_SMALL;
+ }
+
/* Ensure we have frag_len bytes of data. */
if (current_pdu_len < prhdr->frag_len) {
- /* rpc_read expands the current_pdu struct as neccessary. */
- ret = rpc_read(cli, current_pdu, (uint32)prhdr->frag_len - current_pdu_len, ¤t_pdu_len);
+ if (!rpc_grow_buffer(current_pdu, prhdr->frag_len)) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ ret = rpc_read(cli, current_pdu,
+ (uint32)prhdr->frag_len - current_pdu_len,
+ current_pdu_len);
if (!NT_STATUS_IS_OK(ret)) {
return ret;
}
}
- if (current_pdu_len < prhdr->frag_len) {
- return NT_STATUS_BUFFER_TOO_SMALL;
- }
-
return NT_STATUS_OK;
}
DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault "
"code %s received from %s!\n",
- dcerpc_errstr(NT_STATUS_V(fault_resp.status)),
+ dcerpc_errstr(debug_ctx(), NT_STATUS_V(fault_resp.status)),
rpccli_pipe_txt(debug_ctx(), cli)));
if (NT_STATUS_IS_OK(fault_resp.status)) {
return NT_STATUS_UNSUCCESSFUL;
return NT_STATUS_OK;
}
+/****************************************************************************
+ Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
+****************************************************************************/
+
+static bool cli_api_pipe(struct cli_state *cli, const char *pipe_name,
+ uint16 *setup, uint32 setup_count,
+ uint32 max_setup_count,
+ char *params, uint32 param_count,
+ uint32 max_param_count,
+ char *data, uint32 data_count,
+ uint32 max_data_count,
+ char **rparam, uint32 *rparam_count,
+ char **rdata, uint32 *rdata_count)
+{
+ cli_send_trans(cli, SMBtrans,
+ pipe_name,
+ 0,0, /* fid, flags */
+ setup, setup_count, max_setup_count,
+ params, param_count, max_param_count,
+ data, data_count, max_data_count);
+
+ return (cli_receive_trans(cli, SMBtrans,
+ rparam, (unsigned int *)rparam_count,
+ rdata, (unsigned int *)rdata_count));
+}
+
/****************************************************************************
Send data on an rpc pipe via trans. The prs_struct data must be the last
pdu fragment of an NDR data stream.
while(1) {
RPC_HDR rhdr;
- char *ret_data;
- uint32 ret_data_len;
+ char *ret_data = NULL;
+ uint32 ret_data_len = 0;
/* Ensure we have enough data for a pdu. */
ret = cli_pipe_get_current_pdu(cli, &rhdr, ¤t_pdu);
uint16 frag_len = 0;
uint8 flags = 0;
uint32 ss_padding = 0;
+ ssize_t num_written;
data_sent_thistime = calculate_data_len_tosend(cli, data_left,
&frag_len, &auth_len, &ss_padding);
}
return ret;
- } else {
- /* More packets to come - write and continue. */
- ssize_t num_written;
-
- switch (cli->transport_type) {
- case NCACN_NP:
- num_written = cli_write(cli->trans.np.cli,
- cli->trans.np.fnum,
- 8, /* 8 means message mode. */
- prs_data_p(&outgoing_pdu),
- (off_t)0,
- (size_t)hdr.frag_len);
-
- if (num_written != hdr.frag_len) {
- prs_mem_free(&outgoing_pdu);
- return cli_get_nt_error(
- cli->trans.np.cli);
- }
- break;
- case NCACN_IP_TCP:
- case NCACN_UNIX_STREAM:
- num_written = write_data(
- cli->trans.sock.fd,
- prs_data_p(&outgoing_pdu),
- (size_t)hdr.frag_len);
- if (num_written != hdr.frag_len) {
- NTSTATUS status;
- status = map_nt_error_from_unix(errno);
- prs_mem_free(&outgoing_pdu);
- return status;
- }
- break;
- default:
- DEBUG(0, ("unknown transport type %d\n",
- cli->transport_type));
- return NT_STATUS_INTERNAL_ERROR;
+ }
+
+ switch (cli->transport_type) {
+ case NCACN_NP:
+ num_written = cli_write(cli->trans.np.cli,
+ cli->trans.np.fnum,
+ 8, /* 8 means message mode. */
+ prs_data_p(&outgoing_pdu),
+ (off_t)0,
+ (size_t)hdr.frag_len);
+
+ if (num_written != hdr.frag_len) {
+ prs_mem_free(&outgoing_pdu);
+ return cli_get_nt_error(cli->trans.np.cli);
+ }
+ break;
+ case NCACN_IP_TCP:
+ case NCACN_UNIX_STREAM:
+ num_written = write_data(
+ cli->trans.sock.fd,
+ prs_data_p(&outgoing_pdu),
+ (size_t)hdr.frag_len);
+ if (num_written != hdr.frag_len) {
+ NTSTATUS status;
+ status = map_nt_error_from_unix(errno);
+ prs_mem_free(&outgoing_pdu);
+ return status;
}
+ break;
+ default:
+ DEBUG(0, ("unknown transport type %d\n",
+ cli->transport_type));
+ return NT_STATUS_INTERNAL_ERROR;
}
current_data_offset += data_sent_thistime;
return cli_set_timeout(cli->trans.np.cli, timeout);
}
-bool rpccli_is_pipe_idx(struct rpc_pipe_client *cli, int pipe_idx)
-{
- return ndr_syntax_id_equal(&cli->abstract_syntax,
- pipe_names[pipe_idx].abstr_syntax);
-}
-
bool rpccli_get_pwd_hash(struct rpc_pipe_client *cli, uint8_t nt_hash[16])
{
if ((cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP)
goto fail;
}
- result->trans.sock.fd = open_socket_out(SOCK_STREAM, &addr, port, 60);
- if (result->trans.sock.fd == -1) {
- status = map_nt_error_from_unix(errno);
+ status = open_socket_out(&addr, port, 60, &result->trans.sock.fd);
+ if (!NT_STATUS_IS_OK(status)) {
goto fail;
}
result->abstract_syntax = *abstract_syntax;
result->transfer_syntax = ndr_transfer_syntax;
- result->desthost = get_myname(result);
+ result->desthost = talloc_get_myname(result);
result->srv_name_slash = talloc_asprintf_strupper_m(
result, "\\\\%s", result->desthost);
if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
result->srv_name_slash = talloc_asprintf_strupper_m(
result, "\\\\%s", result->desthost);
+ result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
+ result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
+
if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
TALLOC_FREE(result);
return NT_STATUS_NO_MEMORY;
fnum = cli_nt_create(cli, result->trans.np.pipe_name,
DESIRED_ACCESS_PIPE);
if (fnum == -1) {
- DEBUG(1,("rpc_pipe_open_np: cli_nt_create failed on pipe %s "
+ DEBUG(3,("rpc_pipe_open_np: cli_nt_create failed on pipe %s "
"to machine %s. Error was %s\n",
result->trans.np.pipe_name, cli->desthost,
cli_errstr(cli)));
auth->user_name = talloc_strdup(auth, cli->user_name);
auth->domain = talloc_strdup(auth, cli->domain);
+ auth->user_session_key = data_blob_talloc(auth,
+ cli->user_session_key.data,
+ cli->user_session_key.length);
if ((auth->user_name == NULL) || (auth->domain == NULL)) {
TALLOC_FREE(result);
/****************************************************************************
Get a the schannel session key out of an already opened netlogon pipe.
****************************************************************************/
-static bool get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
- struct cli_state *cli,
- const char *domain,
- uint32 *pneg_flags,
- NTSTATUS *perr)
+static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
+ struct cli_state *cli,
+ const char *domain,
+ uint32 *pneg_flags)
{
uint32 sec_chan_type = 0;
unsigned char machine_pwd[16];
const char *machine_account;
+ NTSTATUS status;
/* Get the machine account credentials from secrets.tdb. */
if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
DEBUG(0, ("get_schannel_session_key: could not fetch "
"trust account password for domain '%s'\n",
domain));
- *perr = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
- return false;
+ return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
}
- *perr = rpccli_netlogon_setup_creds(netlogon_pipe,
+ status = rpccli_netlogon_setup_creds(netlogon_pipe,
cli->desthost, /* server name */
domain, /* domain */
global_myname(), /* client name */
sec_chan_type,
pneg_flags);
- if (!NT_STATUS_IS_OK(*perr)) {
- DEBUG(3,("get_schannel_session_key_common: rpccli_netlogon_setup_creds "
- "failed with result %s to server %s, domain %s, machine account %s.\n",
- nt_errstr(*perr), cli->desthost, domain, machine_account ));
- return false;
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(3, ("get_schannel_session_key_common: "
+ "rpccli_netlogon_setup_creds failed with result %s "
+ "to server %s, domain %s, machine account %s.\n",
+ nt_errstr(status), cli->desthost, domain,
+ machine_account ));
+ return status;
}
if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
cli->desthost));
- *perr = NT_STATUS_INVALID_NETWORK_RESPONSE;
- return false;
+ return NT_STATUS_INVALID_NETWORK_RESPONSE;
}
- return true;
+ return NT_STATUS_OK;;
}
/****************************************************************************
****************************************************************************/
-struct rpc_pipe_client *get_schannel_session_key(struct cli_state *cli,
- const char *domain,
- uint32 *pneg_flags,
- NTSTATUS *perr)
+NTSTATUS get_schannel_session_key(struct cli_state *cli,
+ const char *domain,
+ uint32 *pneg_flags,
+ struct rpc_pipe_client **presult)
{
struct rpc_pipe_client *netlogon_pipe = NULL;
+ NTSTATUS status;
- *perr = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
- &netlogon_pipe);
- if (!NT_STATUS_IS_OK(*perr)) {
- return NULL;
+ status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
+ &netlogon_pipe);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
}
- if (!get_schannel_session_key_common(netlogon_pipe, cli, domain,
- pneg_flags, perr))
- {
+ status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
+ pneg_flags);
+ if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(netlogon_pipe);
- return NULL;
+ return status;
}
- return netlogon_pipe;
+ *presult = netlogon_pipe;
+ return NT_STATUS_OK;
}
/****************************************************************************
using session_key. sign and seal.
****************************************************************************/
-struct rpc_pipe_client *cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
- int pipe_idx,
- enum pipe_auth_level auth_level,
- const char *domain,
- const struct dcinfo *pdc,
- NTSTATUS *perr)
+NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
+ const struct ndr_syntax_id *interface,
+ enum pipe_auth_level auth_level,
+ const char *domain,
+ const struct dcinfo *pdc,
+ struct rpc_pipe_client **presult)
{
struct rpc_pipe_client *result;
struct cli_pipe_auth_data *auth;
+ NTSTATUS status;
- *perr = cli_rpc_pipe_open(cli, pipe_names[pipe_idx].abstr_syntax,
- &result);
- if (!NT_STATUS_IS_OK(*perr)) {
- return NULL;
+ status = cli_rpc_pipe_open(cli, interface, &result);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
}
- *perr = rpccli_schannel_bind_data(result, domain, auth_level,
- pdc->sess_key, &auth);
- if (!NT_STATUS_IS_OK(*perr)) {
+ status = rpccli_schannel_bind_data(result, domain, auth_level,
+ pdc->sess_key, &auth);
+ if (!NT_STATUS_IS_OK(status)) {
DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
- nt_errstr(*perr)));
+ nt_errstr(status)));
TALLOC_FREE(result);
- return NULL;
+ return status;
}
- *perr = rpc_pipe_bind(result, auth);
- if (!NT_STATUS_IS_OK(*perr)) {
- DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: cli_rpc_pipe_bind failed with error %s\n",
- nt_errstr(*perr) ));
+ status = rpc_pipe_bind(result, auth);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
+ "cli_rpc_pipe_bind failed with error %s\n",
+ nt_errstr(status) ));
TALLOC_FREE(result);
- return NULL;
+ return status;
}
/*
if (result->dc == NULL) {
DEBUG(0, ("talloc failed\n"));
TALLOC_FREE(result);
- return NULL;
+ return NT_STATUS_NO_MEMORY;
}
DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
"and bound using schannel.\n",
result->trans.np.pipe_name, cli->desthost, domain ));
- return result;
+ *presult = result;
+ return NT_STATUS_OK;
}
/****************************************************************************
version uses an ntlmssp auth bound netlogon pipe to get the key.
****************************************************************************/
-static struct rpc_pipe_client *get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
- const char *domain,
- const char *username,
- const char *password,
- uint32 *pneg_flags,
- NTSTATUS *perr)
+static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
+ const char *domain,
+ const char *username,
+ const char *password,
+ uint32 *pneg_flags,
+ struct rpc_pipe_client **presult)
{
struct rpc_pipe_client *netlogon_pipe = NULL;
+ NTSTATUS status;
- *perr = cli_rpc_pipe_open_spnego_ntlmssp(cli,
- &ndr_table_netlogon.syntax_id,
- PIPE_AUTH_LEVEL_PRIVACY,
- domain, username, password,
- &netlogon_pipe);
- if (!netlogon_pipe) {
- return NULL;
+ status = cli_rpc_pipe_open_spnego_ntlmssp(
+ cli, &ndr_table_netlogon.syntax_id, PIPE_AUTH_LEVEL_PRIVACY,
+ domain, username, password, &netlogon_pipe);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
}
- if (!get_schannel_session_key_common(netlogon_pipe, cli, domain,
- pneg_flags, perr))
- {
+ status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
+ pneg_flags);
+ if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(netlogon_pipe);
- return NULL;
+ return status;
}
- return netlogon_pipe;
+ *presult = netlogon_pipe;
+ return NT_STATUS_OK;
}
/****************************************************************************
uses an ntlmssp bind to get the session key.
****************************************************************************/
-struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
- int pipe_idx,
- enum pipe_auth_level auth_level,
- const char *domain,
- const char *username,
- const char *password,
- NTSTATUS *perr)
+NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
+ const struct ndr_syntax_id *interface,
+ enum pipe_auth_level auth_level,
+ const char *domain,
+ const char *username,
+ const char *password,
+ struct rpc_pipe_client **presult)
{
uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
struct rpc_pipe_client *netlogon_pipe = NULL;
struct rpc_pipe_client *result = NULL;
+ NTSTATUS status;
- netlogon_pipe = get_schannel_session_key_auth_ntlmssp(cli, domain, username,
- password, &neg_flags, perr);
- if (!netlogon_pipe) {
+ status = get_schannel_session_key_auth_ntlmssp(
+ cli, domain, username, password, &neg_flags, &netlogon_pipe);
+ if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
"key from server %s for domain %s.\n",
cli->desthost, domain ));
- return NULL;
+ return status;
}
- result = cli_rpc_pipe_open_schannel_with_key(cli, pipe_idx,
- auth_level,
- domain, netlogon_pipe->dc, perr);
+ status = cli_rpc_pipe_open_schannel_with_key(
+ cli, interface, auth_level, domain, netlogon_pipe->dc,
+ &result);
/* Now we've bound using the session key we can close the netlog pipe. */
TALLOC_FREE(netlogon_pipe);
- return result;
+ if (NT_STATUS_IS_OK(status)) {
+ *presult = result;
+ }
+ return status;
}
/****************************************************************************
Fetch the session key ourselves using a temporary netlogon pipe.
****************************************************************************/
-struct rpc_pipe_client *cli_rpc_pipe_open_schannel(struct cli_state *cli,
- int pipe_idx,
- enum pipe_auth_level auth_level,
- const char *domain,
- NTSTATUS *perr)
+NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
+ const struct ndr_syntax_id *interface,
+ enum pipe_auth_level auth_level,
+ const char *domain,
+ struct rpc_pipe_client **presult)
{
uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
struct rpc_pipe_client *netlogon_pipe = NULL;
struct rpc_pipe_client *result = NULL;
+ NTSTATUS status;
- netlogon_pipe = get_schannel_session_key(cli, domain, &neg_flags, perr);
- if (!netlogon_pipe) {
+ status = get_schannel_session_key(cli, domain, &neg_flags,
+ &netlogon_pipe);
+ if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
"key from server %s for domain %s.\n",
cli->desthost, domain ));
- return NULL;
+ return status;
}
- result = cli_rpc_pipe_open_schannel_with_key(cli, pipe_idx,
- auth_level,
- domain, netlogon_pipe->dc, perr);
+ status = cli_rpc_pipe_open_schannel_with_key(
+ cli, interface, auth_level, domain, netlogon_pipe->dc,
+ &result);
/* Now we've bound using the session key we can close the netlog pipe. */
TALLOC_FREE(netlogon_pipe);
- return result;
+ if (NT_STATUS_IS_OK(status)) {
+ *presult = result;
+ }
+
+ return NT_STATUS_OK;
}
/****************************************************************************
NULL so long as the caller has a TGT.
****************************************************************************/
-struct rpc_pipe_client *cli_rpc_pipe_open_krb5(struct cli_state *cli,
- int pipe_idx,
- enum pipe_auth_level auth_level,
- const char *service_princ,
- const char *username,
- const char *password,
- NTSTATUS *perr)
+NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
+ const struct ndr_syntax_id *interface,
+ enum pipe_auth_level auth_level,
+ const char *service_princ,
+ const char *username,
+ const char *password,
+ struct rpc_pipe_client **presult)
{
#ifdef HAVE_KRB5
struct rpc_pipe_client *result;
struct cli_pipe_auth_data *auth;
+ NTSTATUS status;
- *perr = cli_rpc_pipe_open(cli, pipe_names[pipe_idx].abstr_syntax,
- &result);
- if (!NT_STATUS_IS_OK(*perr)) {
- return NULL;
+ status = cli_rpc_pipe_open(cli, interface, &result);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
}
- *perr = rpccli_kerberos_bind_data(result, auth_level, service_princ,
- username, password, &auth);
- if (!NT_STATUS_IS_OK(*perr)) {
+ status = rpccli_kerberos_bind_data(result, auth_level, service_princ,
+ username, password, &auth);
+ if (!NT_STATUS_IS_OK(status)) {
DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
- nt_errstr(*perr)));
+ nt_errstr(status)));
TALLOC_FREE(result);
- return NULL;
+ return status;
}
- *perr = rpc_pipe_bind(result, auth);
- if (!NT_STATUS_IS_OK(*perr)) {
- DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed with error %s\n",
- nt_errstr(*perr) ));
+ status = rpc_pipe_bind(result, auth);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "
+ "with error %s\n", nt_errstr(status)));
TALLOC_FREE(result);
- return NULL;
+ return status;
}
- return result;
+ *presult = result;
+ return NT_STATUS_OK;
#else
DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
- return NULL;
+ return NT_STATUS_NOT_IMPLEMENTED;
#endif
}
cli->auth->a_u.kerberos_auth->session_key.length);
break;
case PIPE_AUTH_TYPE_NONE:
+ *session_key = data_blob_talloc(mem_ctx,
+ cli->auth->user_session_key.data,
+ cli->auth->user_session_key.length);
+ break;
default:
return NT_STATUS_NO_USER_SESSION_KEY;
}