(unsigned int)RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len ));
return NT_STATUS_BUFFER_TOO_SMALL;
}
-
+
if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshall RPC_HDR_AUTH.\n"));
return NT_STATUS_BUFFER_TOO_SMALL;
} else {
return fault_resp.status;
}
-
}
default:
uint32 max_data = cli->max_xmit_frag ? cli->max_xmit_frag : RPC_MAX_PDU_FRAG_LEN;
uint32 current_rbuf_offset = 0;
prs_struct current_pdu;
-
+
#ifdef DEVELOPER
/* Ensure we're not sending too much. */
SMB_ASSERT(data_len <= max_data);
/* Use lp_workgroup() if domain not specified */
if (!cli->domain || !cli->domain[0]) {
- cli->domain = lp_workgroup();
+ cli->domain = talloc_strdup(cli, lp_workgroup());
+ if (cli->domain == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
}
init_rpc_auth_schannel_neg(&schannel_neg, cli->domain, global_myname());
}
/* Finally marshall the blob. */
-
+
if (!prs_copy_data_in(outgoing_pdu, (const char *)auth_blob.data, NTLMSSP_SIG_SIZE)) {
DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
(unsigned int)NTLMSSP_SIG_SIZE));
data_blob_free(&auth_blob);
return NT_STATUS_NO_MEMORY;
}
-
+
data_blob_free(&auth_blob);
return NT_STATUS_OK;
}
&verf,
outgoing_pdu,
0);
-
+
return NT_STATUS_OK;
}
init_rpc_hdr(&hdr, RPC_AUTH3, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id,
RPC_HEADER_LEN + 4 /* pad */ + RPC_HDR_AUTH_LEN + pauth_blob->length,
pauth_blob->length );
-
+
/* Marshall it. */
if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) {
DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n"));
server_response = data_blob(NULL, phdr->auth_len);
prs_copy_data_out((char *)server_response.data, rbuf, phdr->auth_len);
-
+
nt_status = ntlmssp_update(cli->auth.a_u.ntlmssp_state,
server_response,
&client_reply);
-
+
if (!NT_STATUS_IS_OK(nt_status)) {
DEBUG(0,("rpc_finish_auth3_bind: NTLMSSP update using server blob failed.\n"));
data_blob_free(&server_response);
server_spnego_response = data_blob(NULL, phdr->auth_len);
prs_copy_data_out((char *)server_spnego_response.data, rbuf, phdr->auth_len);
-
+
/* The server might give us back two challenges - tmp_blob is for the second. */
if (!spnego_parse_challenge(server_spnego_response, &server_ntlm_response, &tmp_blob)) {
data_blob_free(&server_spnego_response);
nt_status = ntlmssp_update(cli->auth.a_u.ntlmssp_state,
server_ntlm_response,
&client_reply);
-
+
/* Finished with the server_ntlm response */
data_blob_free(&server_ntlm_response);
return (cli->abstract_syntax == pipe_names[pipe_idx].abstr_syntax);
}
+struct cli_state *rpc_pipe_np_smb_conn(struct rpc_pipe_client *p)
+{
+ return p->cli;
+}
+
+static int rpc_pipe_destructor(struct rpc_pipe_client *p)
+{
+ bool ret;
+
+ ret = cli_close(p->cli, p->fnum);
+ if (!ret) {
+ DEBUG(1, ("rpc_pipe_destructor: cli_close failed on pipe %s, "
+ "fnum 0x%x to machine %s. Error was %s\n",
+ p->pipe_name, (int) p->fnum,
+ p->desthost, cli_errstr(p->cli)));
+ }
+
+ if (p->auth.cli_auth_data_free_func) {
+ (*p->auth.cli_auth_data_free_func)(&p->auth);
+ }
+
+ DEBUG(10, ("rpc_pipe_destructor: closed pipe %s to machine %s\n",
+ p->pipe_name, p->desthost ));
+
+ DLIST_REMOVE(p->cli->pipe_list, p);
+
+ return ret ? -1 : 0;
+}
+
/****************************************************************************
Open a named pipe over SMB to a remote server.
*
return NULL;
}
- if ( pipe_idx >= PI_MAX_PIPES ) {
- DEBUG(0, ("cli_rpc_pipe_open: Programmer error! Invalid pipe "
- "index [%d]\n", pipe_idx));
- *perr = NT_STATUS_INVALID_PARAMETER;
- return NULL;
- }
-
/* The pipe name index must fall within our array */
SMB_ASSERT((pipe_idx >= 0) && (pipe_idx < PI_MAX_PIPES));
result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
if (result == NULL) {
+ *perr = NT_STATUS_NO_MEMORY;
return NULL;
}
result->pipe_name = cli_get_pipe_name(pipe_idx);
- fnum = cli_nt_create(cli, result->pipe_name, DESIRED_ACCESS_PIPE);
-
- if (fnum == -1) {
- DEBUG(1,("cli_rpc_pipe_open: cli_nt_create failed on pipe %s "
- "to machine %s. Error was %s\n",
- result->pipe_name, cli->desthost,
- cli_errstr(cli)));
- *perr = cli_get_nt_error(cli);
- talloc_destroy(result);
- return NULL;
- }
-
- result->fnum = fnum;
result->cli = cli;
result->abstract_syntax = pipe_names[pipe_idx].abstr_syntax;
result->transfer_syntax = pipe_names[pipe_idx].trans_syntax;
result->auth.auth_type = PIPE_AUTH_TYPE_NONE;
result->auth.auth_level = PIPE_AUTH_LEVEL_NONE;
+ result->domain = talloc_strdup(result, cli->domain);
+ result->user_name = talloc_strdup(result, cli->user_name);
result->desthost = talloc_strdup(result, cli->desthost);
- if (result->desthost == NULL) {
- TALLOC_FREE(result);
- return NULL;
- }
-
result->srv_name_slash = talloc_asprintf_strupper_m(
result, "\\\\%s", result->desthost);
- if (result->srv_name_slash == NULL) {
+
+ if ((result->domain == NULL)
+ || (result->user_name == NULL)
+ || (result->desthost == NULL)
+ || (result->srv_name_slash == NULL)) {
+ *perr = NT_STATUS_NO_MEMORY;
TALLOC_FREE(result);
return NULL;
}
/* Set up a netlogon credential chain for a netlogon pipe. */
result->dc = TALLOC_ZERO_P(result, struct dcinfo);
if (result->dc == NULL) {
- talloc_destroy(result);
+ *perr = NT_STATUS_NO_MEMORY;
+ TALLOC_FREE(result);
return NULL;
}
}
+ fnum = cli_nt_create(cli, result->pipe_name, DESIRED_ACCESS_PIPE);
+ if (fnum == -1) {
+ DEBUG(1,("cli_rpc_pipe_open: cli_nt_create failed on pipe %s "
+ "to machine %s. Error was %s\n",
+ result->pipe_name, cli->desthost,
+ cli_errstr(cli)));
+ *perr = cli_get_nt_error(cli);
+ talloc_destroy(result);
+ return NULL;
+ }
+
+ result->fnum = fnum;
+
DLIST_ADD(cli->pipe_list, result);
+ talloc_set_destructor(result, rpc_pipe_destructor);
+
*perr = NT_STATUS_OK;
return result;
return NULL;
}
- result->domain = talloc_strdup(result, cli->domain);
- result->user_name = talloc_strdup(result, cli->user_name);
-
- if ((result->domain == NULL) || (result->user_name == NULL)) {
- *perr = NT_STATUS_NO_MEMORY;
- cli_rpc_pipe_close(result);
- return NULL;
- }
-
*perr = rpc_pipe_bind(result, PIPE_AUTH_TYPE_NONE, PIPE_AUTH_LEVEL_NONE);
if (!NT_STATUS_IS_OK(*perr)) {
int lvl = 0;
- if (pipe_idx == PI_DSSETUP) {
+ if (rpccli_is_pipe_idx(result, PI_DSSETUP)) {
/* non AD domains just don't have this pipe, avoid
* level 0 statement in that case - gd */
lvl = 3;
}
DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe %s failed with error %s\n",
cli_get_pipe_name(pipe_idx), nt_errstr(*perr) ));
- cli_rpc_pipe_close(result);
+ TALLOC_FREE(result);
return NULL;
}
if (result == NULL) {
return NULL;
}
-
+
result->auth.cli_auth_data_free_func = cli_ntlmssp_auth_free;
+ TALLOC_FREE(result->domain);
+ TALLOC_FREE(result->user_name);
+
result->domain = talloc_strdup(result, domain);
result->user_name = talloc_strdup(result, username);
} else if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) {
ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
}
-
+
*perr = rpc_pipe_bind(result, auth_type, auth_level);
if (!NT_STATUS_IS_OK(*perr)) {
DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
err:
- cli_rpc_pipe_close(result);
+ TALLOC_FREE(result);
return NULL;
}
if (!get_schannel_session_key_common(netlogon_pipe, cli, domain,
pneg_flags, perr))
{
- cli_rpc_pipe_close(netlogon_pipe);
+ TALLOC_FREE(netlogon_pipe);
return NULL;
}
result->auth.a_u.schannel_auth = TALLOC_ZERO_P(
result, struct schannel_auth_struct);
if (!result->auth.a_u.schannel_auth) {
- cli_rpc_pipe_close(result);
+ TALLOC_FREE(result);
+ *perr = NT_STATUS_NO_MEMORY;
+ return NULL;
+ }
+
+ TALLOC_FREE(result->domain);
+ result->domain = talloc_strdup(result, domain);
+ if (result->domain == NULL) {
+ TALLOC_FREE(result);
*perr = NT_STATUS_NO_MEMORY;
return NULL;
}
- result->domain = domain;
memcpy(result->auth.a_u.schannel_auth->sess_key, pdc->sess_key, 16);
*perr = rpc_pipe_bind(result, PIPE_AUTH_TYPE_SCHANNEL, auth_level);
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) ));
- cli_rpc_pipe_close(result);
+ TALLOC_FREE(result);
return NULL;
}
if (!get_schannel_session_key_common(netlogon_pipe, cli, domain,
pneg_flags, perr))
{
- cli_rpc_pipe_close(netlogon_pipe);
+ TALLOC_FREE(netlogon_pipe);
return NULL;
}
domain, netlogon_pipe->dc, perr);
/* Now we've bound using the session key we can close the netlog pipe. */
- cli_rpc_pipe_close(netlogon_pipe);
+ TALLOC_FREE(netlogon_pipe);
return result;
}
domain, netlogon_pipe->dc, perr);
/* Now we've bound using the session key we can close the netlog pipe. */
- cli_rpc_pipe_close(netlogon_pipe);
+ TALLOC_FREE(netlogon_pipe);
return result;
}
service_princ = talloc_asprintf(result, "%s$@%s",
cli->desthost, lp_realm() );
if (!service_princ) {
- cli_rpc_pipe_close(result);
+ TALLOC_FREE(result);
return NULL;
}
}
if (username && password) {
int ret = kerberos_kinit_password(username, password, 0, NULL);
if (ret) {
- cli_rpc_pipe_close(result);
+ TALLOC_FREE(result);
return NULL;
}
}
result->auth.a_u.kerberos_auth = TALLOC_ZERO_P(
result, struct kerberos_auth_struct);
if (!result->auth.a_u.kerberos_auth) {
- cli_rpc_pipe_close(result);
+ TALLOC_FREE(result);
*perr = NT_STATUS_NO_MEMORY;
return NULL;
}
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) ));
- cli_rpc_pipe_close(result);
+ TALLOC_FREE(result);
return NULL;
}