DATA_BLOB null_blob = data_blob_null;
NTSTATUS status;
- gensec_security = talloc_get_type_abort(cli->auth->auth_ctx,
- struct gensec_security);
+ gensec_security = cli->auth->auth_ctx;
DEBUG(5, ("create_generic_auth_rpc_bind_req: generate first token\n"));
status = gensec_update(gensec_security, mem_ctx, null_blob, auth_token);
NTSTATUS ret = NT_STATUS_OK;
switch (auth->auth_type) {
- case DCERPC_AUTH_TYPE_SCHANNEL:
- case DCERPC_AUTH_TYPE_NTLMSSP:
- case DCERPC_AUTH_TYPE_KRB5:
- case DCERPC_AUTH_TYPE_SPNEGO:
+ case DCERPC_AUTH_TYPE_NONE:
+ break;
+
+ default:
ret = create_generic_auth_rpc_bind_req(cli, mem_ctx,
&auth_token,
&auth->client_hdr_signing);
return ret;
}
break;
-
- case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
- auth_token = data_blob_talloc(mem_ctx,
- "NCALRPC_AUTH_TOKEN",
- 18);
- break;
-
- case DCERPC_AUTH_TYPE_NONE:
- break;
-
- default:
- /* "Can't" happen. */
- return NT_STATUS_INVALID_INFO_CLASS;
}
if (auth_token.length != 0) {
switch(pauth->auth_type) {
case DCERPC_AUTH_TYPE_NONE:
- case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
/* Bind complete. */
tevent_req_done(req);
return;
- case DCERPC_AUTH_TYPE_SCHANNEL:
- case DCERPC_AUTH_TYPE_NTLMSSP:
- case DCERPC_AUTH_TYPE_SPNEGO:
- case DCERPC_AUTH_TYPE_KRB5:
+ default:
/* Paranoid lenght checks */
if (pkt->frag_length < DCERPC_AUTH_TRAILER_LENGTH
+ pkt->auth_length) {
return;
}
break;
-
- default:
- goto err_out;
}
/*
switch(pauth->auth_type) {
case DCERPC_AUTH_TYPE_NONE:
- case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
/* Bind complete. */
tevent_req_done(req);
return;
- case DCERPC_AUTH_TYPE_SCHANNEL:
- case DCERPC_AUTH_TYPE_NTLMSSP:
- case DCERPC_AUTH_TYPE_KRB5:
- case DCERPC_AUTH_TYPE_SPNEGO:
- gensec_security = talloc_get_type_abort(pauth->auth_ctx,
- struct gensec_security);
+ default:
+ gensec_security = pauth->auth_ctx;
if (pkt->pfc_flags & DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN) {
if (pauth->client_hdr_signing) {
&auth_token);
}
break;
-
- default:
- goto err_out;
}
if (!NT_STATUS_IS_OK(status)) {
tevent_req_nterror(req, status);
}
return;
-
-err_out:
- DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
- (unsigned int)state->cli->auth->auth_type));
- tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
}
static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
return h;
}
-NTSTATUS rpccli_ncalrpc_bind_data(TALLOC_CTX *mem_ctx,
- struct pipe_auth_data **presult)
+NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
+ struct pipe_auth_data **presult)
{
struct pipe_auth_data *result;
+ struct auth_generic_state *auth_generic_ctx;
+ NTSTATUS status;
result = talloc_zero(mem_ctx, struct pipe_auth_data);
if (result == NULL) {
return NT_STATUS_NO_MEMORY;
}
- result->auth_type = DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM;
- result->auth_level = DCERPC_AUTH_LEVEL_CONNECT;
+ result->auth_type = DCERPC_AUTH_TYPE_NONE;
+ result->auth_level = DCERPC_AUTH_LEVEL_NONE;
- result->user_name = talloc_strdup(result, "");
- result->domain = talloc_strdup(result, "");
- if ((result->user_name == NULL) || (result->domain == NULL)) {
- TALLOC_FREE(result);
- return NT_STATUS_NO_MEMORY;
+ status = auth_generic_client_prepare(result,
+ &auth_generic_ctx);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(1, ("Failed to create auth_generic context: %s\n",
+ nt_errstr(status)));
}
- *presult = result;
- return NT_STATUS_OK;
-}
-
-NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
- struct pipe_auth_data **presult)
-{
- struct pipe_auth_data *result;
-
- result = talloc_zero(mem_ctx, struct pipe_auth_data);
- if (result == NULL) {
- return NT_STATUS_NO_MEMORY;
+ status = auth_generic_set_username(auth_generic_ctx, "");
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(1, ("Failed to set username: %s\n",
+ nt_errstr(status)));
}
- result->auth_type = DCERPC_AUTH_TYPE_NONE;
- result->auth_level = DCERPC_AUTH_LEVEL_NONE;
+ status = auth_generic_set_domain(auth_generic_ctx, "");
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(1, ("Failed to set domain: %s\n",
+ nt_errstr(status)));
+ return status;
+ }
- result->user_name = talloc_strdup(result, "");
- result->domain = talloc_strdup(result, "");
- if ((result->user_name == NULL) || (result->domain == NULL)) {
- TALLOC_FREE(result);
- return NT_STATUS_NO_MEMORY;
+ status = gensec_set_credentials(auth_generic_ctx->gensec_security,
+ auth_generic_ctx->credentials);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(1, ("Failed to set GENSEC credentials: %s\n",
+ nt_errstr(status)));
+ return status;
}
+ talloc_unlink(auth_generic_ctx, auth_generic_ctx->credentials);
+ auth_generic_ctx->credentials = NULL;
+ result->auth_ctx = talloc_move(result, &auth_generic_ctx->gensec_security);
+ talloc_free(auth_generic_ctx);
*presult = result;
return NT_STATUS_OK;
}
result->auth_type = auth_type;
result->auth_level = auth_level;
- result->user_name = talloc_strdup(result, username);
- result->domain = talloc_strdup(result, domain);
- if ((result->user_name == NULL) || (result->domain == NULL)) {
- status = NT_STATUS_NO_MEMORY;
- goto fail;
- }
-
status = auth_generic_client_prepare(result,
&auth_generic_ctx);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
+/* This routine steals the creds pointer that is passed in */
+static NTSTATUS rpccli_generic_bind_data_from_creds(TALLOC_CTX *mem_ctx,
+ enum dcerpc_AuthType auth_type,
+ enum dcerpc_AuthLevel auth_level,
+ const char *server,
+ const char *target_service,
+ struct cli_credentials *creds,
+ struct pipe_auth_data **presult)
+{
+ struct auth_generic_state *auth_generic_ctx;
+ struct pipe_auth_data *result;
+ NTSTATUS status;
+
+ result = talloc_zero(mem_ctx, struct pipe_auth_data);
+ if (result == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ result->auth_type = auth_type;
+ result->auth_level = auth_level;
+
+ status = auth_generic_client_prepare(result,
+ &auth_generic_ctx);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto fail;
+ }
+
+ status = auth_generic_set_creds(auth_generic_ctx, creds);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto fail;
+ }
+
+ status = gensec_set_target_service(auth_generic_ctx->gensec_security, target_service);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto fail;
+ }
+
+ status = gensec_set_target_hostname(auth_generic_ctx->gensec_security, server);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto fail;
+ }
+
+ status = auth_generic_client_start_by_authtype(auth_generic_ctx, auth_type, auth_level);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto fail;
+ }
+
+ result->auth_ctx = talloc_move(result, &auth_generic_ctx->gensec_security);
+ talloc_free(auth_generic_ctx);
+ *presult = result;
+ return NT_STATUS_OK;
+
+ fail:
+ TALLOC_FREE(result);
+ return status;
+}
+
+NTSTATUS rpccli_ncalrpc_bind_data(TALLOC_CTX *mem_ctx,
+ struct pipe_auth_data **presult)
+{
+ return rpccli_generic_bind_data(mem_ctx,
+ DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM,
+ DCERPC_AUTH_LEVEL_CONNECT,
+ NULL, /* server */
+ "host", /* target_service */
+ NAME_NT_AUTHORITY, /* domain */
+ "SYSTEM",
+ "", /* password */
+ CRED_DONT_USE_KERBEROS,
+ NULL, /* netlogon_creds_CredentialState */
+ presult);
+}
+
/**
* Create an rpc pipe client struct, connecting to a tcp port.
*/
* from the enclosing SMB creds
*/
- TALLOC_FREE(auth->user_name);
- TALLOC_FREE(auth->domain);
-
- auth->user_name = talloc_strdup(auth, cli->user_name);
- auth->domain = talloc_strdup(auth, cli->domain);
-
if (transport == NCACN_NP) {
struct smbXcli_session *session;
}
}
- if ((auth->user_name == NULL) || (auth->domain == NULL)) {
- TALLOC_FREE(result);
- return NT_STATUS_NO_MEMORY;
- }
-
status = rpc_pipe_bind(result, auth);
if (!NT_STATUS_IS_OK(status)) {
int lvl = 0;
/****************************************************************************
Open a named pipe to an SMB server and bind using the mech specified
+
+ This routine references the creds pointer that is passed in
+ ****************************************************************************/
+
+NTSTATUS cli_rpc_pipe_open_with_creds(struct cli_state *cli,
+ const struct ndr_interface_table *table,
+ enum dcerpc_transport_t transport,
+ enum dcerpc_AuthType auth_type,
+ enum dcerpc_AuthLevel auth_level,
+ const char *server,
+ 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;
+
+ status = cli_rpc_pipe_open(cli, transport, table, &result);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ status = rpccli_generic_bind_data_from_creds(result,
+ auth_type, auth_level,
+ server, target_service,
+ creds,
+ &auth);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("rpccli_generic_bind_data returned %s\n",
+ nt_errstr(status)));
+ goto err;
+ }
+
+ status = rpc_pipe_bind(result, auth);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("cli_rpc_pipe_open_generic_auth: cli_rpc_pipe_bind failed with error %s\n",
+ nt_errstr(status) ));
+ goto err;
+ }
+
+ DEBUG(10,("cli_rpc_pipe_open_generic_auth: opened pipe %s to "
+ "machine %s and bound as user %s.\n", table->name,
+ result->desthost, cli_credentials_get_unparsed_name(creds, talloc_tos())));
+
+ *presult = result;
+ return NT_STATUS_OK;
+
+ err:
+
+ TALLOC_FREE(result);
+ return status;
+}
+
+/****************************************************************************
+ Open a named pipe to an SMB server and bind using the mech specified
+
+ This routine steals the creds pointer that is passed in
****************************************************************************/
NTSTATUS cli_rpc_pipe_open_generic_auth(struct cli_state *cli,
const struct ndr_interface_table *table,
enum dcerpc_transport_t transport,
+ enum credentials_use_kerberos use_kerberos,
enum dcerpc_AuthType auth_type,
enum dcerpc_AuthLevel auth_level,
const char *server,
return NT_STATUS_OK;
}
-NTSTATUS cli_rpc_pipe_open_spnego(struct cli_state *cli,
- const struct ndr_interface_table *table,
- enum dcerpc_transport_t transport,
- const char *oid,
- enum dcerpc_AuthLevel auth_level,
- const char *server,
- const char *domain,
- const char *username,
- const char *password,
- struct rpc_pipe_client **presult)
+NTSTATUS cli_rpc_pipe_open_schannel_with_creds(struct cli_state *cli,
+ const struct ndr_interface_table *table,
+ enum dcerpc_transport_t transport,
+ struct cli_credentials *cli_creds,
+ struct netlogon_creds_cli_context *netlogon_creds,
+ struct rpc_pipe_client **_rpccli)
{
- struct rpc_pipe_client *result;
- struct pipe_auth_data *auth = NULL;
+ struct rpc_pipe_client *rpccli;
+ struct pipe_auth_data *rpcauth;
const char *target_service = table->authservices->names[0];
-
+ struct netlogon_creds_CredentialState *ncreds = NULL;
+ enum dcerpc_AuthLevel auth_level;
NTSTATUS status;
- enum credentials_use_kerberos use_kerberos;
+ int rpc_pipe_bind_dbglvl = 0;
- if (strcmp(oid, GENSEC_OID_KERBEROS5) == 0) {
- use_kerberos = CRED_MUST_USE_KERBEROS;
- } else if (strcmp(oid, GENSEC_OID_NTLMSSP) == 0) {
- use_kerberos = CRED_DONT_USE_KERBEROS;
- } else {
- return NT_STATUS_INVALID_PARAMETER;
+ status = cli_rpc_pipe_open(cli, transport, table, &rpccli);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
}
- status = cli_rpc_pipe_open(cli, transport, table, &result);
+ status = netlogon_creds_cli_lock(netlogon_creds, rpccli, &ncreds);
if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("netlogon_creds_cli_get returned %s\n",
+ nt_errstr(status)));
+ TALLOC_FREE(rpccli);
return status;
}
- status = rpccli_generic_bind_data(result,
- DCERPC_AUTH_TYPE_SPNEGO, auth_level,
- server, target_service,
- domain, username, password,
- use_kerberos, NULL,
- &auth);
+ auth_level = netlogon_creds_cli_auth_level(netlogon_creds);
+
+ cli_credentials_set_netlogon_creds(cli_creds, ncreds);
+
+ status = rpccli_generic_bind_data_from_creds(rpccli,
+ DCERPC_AUTH_TYPE_SCHANNEL,
+ auth_level,
+ rpccli->desthost,
+ target_service,
+ cli_creds,
+ &rpcauth);
if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0, ("rpccli_generic_bind_data returned %s\n",
+ DEBUG(0, ("rpccli_generic_bind_data_from_creds returned %s\n",
nt_errstr(status)));
- goto err;
+ TALLOC_FREE(rpccli);
+ return status;
}
- status = rpc_pipe_bind(result, auth);
+ status = rpc_pipe_bind(rpccli, rpcauth);
+ cli_credentials_set_netlogon_creds(cli_creds, NULL);
+ if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_ACCESS_DENIED)) {
+ rpc_pipe_bind_dbglvl = 1;
+ netlogon_creds_cli_delete(netlogon_creds, &ncreds);
+ }
if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0, ("cli_rpc_pipe_open_spnego: cli_rpc_pipe_bind failed with error %s\n",
- nt_errstr(status) ));
- goto err;
+ DEBUG(rpc_pipe_bind_dbglvl,
+ ("%s: rpc_pipe_bind failed with error %s\n",
+ __func__, nt_errstr(status)));
+ TALLOC_FREE(rpccli);
+ return status;
}
- DEBUG(10,("cli_rpc_pipe_open_spnego: opened pipe %s to "
- "machine %s.\n", table->name,
- result->desthost));
+ TALLOC_FREE(ncreds);
- *presult = result;
- return NT_STATUS_OK;
+ if (!ndr_syntax_id_equal(&table->syntax_id, &ndr_table_netlogon.syntax_id)) {
+ goto done;
+ }
- err:
+ status = netlogon_creds_cli_check(netlogon_creds,
+ rpccli->binding_handle);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("netlogon_creds_cli_check failed with %s\n",
+ nt_errstr(status)));
+ TALLOC_FREE(rpccli);
+ return status;
+ }
- TALLOC_FREE(result);
- return status;
+
+done:
+ DEBUG(10,("%s: opened pipe %s to machine %s "
+ "for domain %s and bound using schannel.\n",
+ __func__, table->name,
+ rpccli->desthost, cli_credentials_get_domain(cli_creds)));
+
+ *_rpccli = rpccli;
+ return NT_STATUS_OK;
}
NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
}
switch (cli->auth->auth_type) {
- case DCERPC_AUTH_TYPE_SPNEGO:
- case DCERPC_AUTH_TYPE_NTLMSSP:
- case DCERPC_AUTH_TYPE_KRB5:
- gensec_security = talloc_get_type_abort(a->auth_ctx,
- struct gensec_security);
- status = gensec_session_key(gensec_security, mem_ctx, &sk);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
- make_dup = false;
- break;
- case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
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;
}