summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/ntdomain.h2
-rw-r--r--source3/librpc/rpc/dcerpc_helpers.c110
-rw-r--r--source3/librpc/rpc/dcerpc_spnego.c108
-rw-r--r--source3/librpc/rpc/dcerpc_spnego.h7
-rw-r--r--source3/rpc_client/cli_pipe.c256
5 files changed, 321 insertions, 162 deletions
diff --git a/source3/include/ntdomain.h b/source3/include/ntdomain.h
index 98f2df9445..f42ff587ff 100644
--- a/source3/include/ntdomain.h
+++ b/source3/include/ntdomain.h
@@ -105,7 +105,7 @@ struct gse_context;
struct pipe_auth_data {
enum dcerpc_AuthType auth_type;
- enum pipe_auth_type_spnego spnego_type;
+ enum pipe_auth_type_spnego spnego_type; /* used by server only */
enum dcerpc_AuthLevel auth_level;
union {
diff --git a/source3/librpc/rpc/dcerpc_helpers.c b/source3/librpc/rpc/dcerpc_helpers.c
index 592832bdd8..26b44de5ea 100644
--- a/source3/librpc/rpc/dcerpc_helpers.c
+++ b/source3/librpc/rpc/dcerpc_helpers.c
@@ -524,6 +524,7 @@ static NTSTATUS add_spnego_auth_footer(struct spnego_context *spnego_ctx,
{
enum dcerpc_AuthType auth_type;
struct gse_context *gse_ctx;
+ struct auth_ntlmssp_state *ntlmssp_ctx;
void *auth_ctx;
NTSTATUS status;
@@ -548,8 +549,15 @@ static NTSTATUS add_spnego_auth_footer(struct spnego_context *spnego_ctx,
auth_level, rpc_out);
break;
- case DCERPC_AUTH_LEVEL_INTEGRITY:
- status = NT_STATUS_NOT_IMPLEMENTED;
+ case DCERPC_AUTH_TYPE_NTLMSSP:
+ ntlmssp_ctx = talloc_get_type(auth_ctx,
+ struct auth_ntlmssp_state);
+ if (!ntlmssp_ctx) {
+ status = NT_STATUS_INTERNAL_ERROR;
+ break;
+ }
+ status = add_ntlmssp_auth_footer(ntlmssp_ctx,
+ auth_level, rpc_out);
break;
default:
@@ -560,6 +568,55 @@ static NTSTATUS add_spnego_auth_footer(struct spnego_context *spnego_ctx,
return status;
}
+static NTSTATUS get_spnego_auth_footer(TALLOC_CTX *mem_ctx,
+ struct spnego_context *sp_ctx,
+ enum dcerpc_AuthLevel auth_level,
+ DATA_BLOB *data, DATA_BLOB *full_pkt,
+ DATA_BLOB *auth_token)
+{
+ enum dcerpc_AuthType auth_type;
+ struct auth_ntlmssp_state *ntlmssp_ctx;
+ struct gse_context *gse_ctx;
+ void *auth_ctx;
+ NTSTATUS status;
+
+ status = spnego_get_negotiated_mech(sp_ctx, &auth_type, &auth_ctx);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ switch (auth_type) {
+ case DCERPC_AUTH_TYPE_KRB5:
+ gse_ctx = talloc_get_type(auth_ctx,
+ struct gse_context);
+ if (!gse_ctx) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ DEBUG(10, ("KRB5 auth\n"));
+
+ return get_gssapi_auth_footer(mem_ctx, gse_ctx,
+ auth_level,
+ data, full_pkt,
+ auth_token);
+ case DCERPC_AUTH_TYPE_NTLMSSP:
+ ntlmssp_ctx = talloc_get_type(auth_ctx,
+ struct auth_ntlmssp_state);
+ if (!ntlmssp_ctx) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ DEBUG(10, ("NTLMSSP auth\n"));
+
+ return get_ntlmssp_auth_footer(ntlmssp_ctx,
+ auth_level,
+ data, full_pkt,
+ auth_token);
+ default:
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+}
+
/**
* @brief Append an auth footer according to what is the current mechanism
*
@@ -618,12 +675,16 @@ NTSTATUS dcerpc_add_auth_footer(struct pipe_auth_data *auth,
status = NT_STATUS_OK;
break;
case DCERPC_AUTH_TYPE_SPNEGO:
- if (auth->spnego_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
- return add_spnego_auth_footer(auth->a_u.spnego_state,
- auth->auth_level,
- rpc_out);
+ if (auth->spnego_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
+ /* compat for server code */
+ return add_ntlmssp_auth_footer(
+ auth->a_u.auth_ntlmssp_state,
+ auth->auth_level,
+ rpc_out);
}
- /* fall thorugh */
+ status = add_spnego_auth_footer(auth->a_u.spnego_state,
+ auth->auth_level, rpc_out);
+ break;
case DCERPC_AUTH_TYPE_NTLMSSP:
status = add_ntlmssp_auth_footer(auth->a_u.auth_ntlmssp_state,
auth->auth_level,
@@ -731,26 +792,12 @@ NTSTATUS dcerpc_check_auth(struct pipe_auth_data *auth,
return NT_STATUS_OK;
case DCERPC_AUTH_TYPE_SPNEGO:
- if (auth->spnego_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
- enum dcerpc_AuthType auth_type;
- struct gse_context *gse_ctx;
- void *auth_ctx;
-
- status = spnego_get_negotiated_mech(
- auth->a_u.spnego_state,
- &auth_type, &auth_ctx);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
- gse_ctx = talloc_get_type(auth_ctx,
- struct gse_context);
- if (!gse_ctx) {
- return NT_STATUS_INVALID_PARAMETER;
- }
+ if (auth->spnego_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
+ /* compat for server code */
+ DEBUG(10, ("NTLMSSP auth\n"));
- DEBUG(10, ("KRB5 auth\n"));
-
- status = get_gssapi_auth_footer(pkt, gse_ctx,
+ status = get_ntlmssp_auth_footer(
+ auth->a_u.auth_ntlmssp_state,
auth->auth_level,
&data, &full_pkt,
&auth_info.credentials);
@@ -759,7 +806,16 @@ NTSTATUS dcerpc_check_auth(struct pipe_auth_data *auth,
}
break;
}
- /* fall through */
+
+ status = get_spnego_auth_footer(pkt, auth->a_u.spnego_state,
+ auth->auth_level,
+ &data, &full_pkt,
+ &auth_info.credentials);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+ break;
+
case DCERPC_AUTH_TYPE_NTLMSSP:
DEBUG(10, ("NTLMSSP auth\n"));
diff --git a/source3/librpc/rpc/dcerpc_spnego.c b/source3/librpc/rpc/dcerpc_spnego.c
index e733469ac3..a0832ce09f 100644
--- a/source3/librpc/rpc/dcerpc_spnego.c
+++ b/source3/librpc/rpc/dcerpc_spnego.c
@@ -19,6 +19,8 @@
#include "includes.h"
#include "../libcli/auth/spnego.h"
+#include "include/ntlmssp_wrap.h"
+#include "librpc/gen_ndr/ntlmssp.h"
#include "dcerpc_spnego.h"
#include "dcerpc_gssapi.h"
@@ -26,7 +28,7 @@ struct spnego_context {
enum dcerpc_AuthType auth_type;
union {
- struct auth_ntlmssp_state *auth_ntlmssp_state;
+ struct auth_ntlmssp_state *ntlmssp_state;
struct gse_context *gssapi_state;
} mech_ctx;
@@ -88,12 +90,80 @@ NTSTATUS spnego_gssapi_init_client(TALLOC_CTX *mem_ctx,
return NT_STATUS_OK;
}
+NTSTATUS spnego_ntlmssp_init_client(TALLOC_CTX *mem_ctx,
+ enum dcerpc_AuthLevel auth_level,
+ const char *domain,
+ const char *username,
+ const char *password,
+ struct spnego_context **spnego_ctx)
+{
+ struct spnego_context *sp_ctx;
+ NTSTATUS status;
+
+ status = spnego_context_init(mem_ctx,
+ DCERPC_AUTH_TYPE_NTLMSSP, &sp_ctx);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ status = auth_ntlmssp_client_start(sp_ctx,
+ global_myname(),
+ lp_workgroup(),
+ lp_client_ntlmv2_auth(),
+ &sp_ctx->mech_ctx.ntlmssp_state);
+ if (!NT_STATUS_IS_OK(status)) {
+ TALLOC_FREE(sp_ctx);
+ return status;
+ }
+
+ status = auth_ntlmssp_set_username(sp_ctx->mech_ctx.ntlmssp_state,
+ username);
+ if (!NT_STATUS_IS_OK(status)) {
+ TALLOC_FREE(sp_ctx);
+ return status;
+ }
+
+ status = auth_ntlmssp_set_domain(sp_ctx->mech_ctx.ntlmssp_state,
+ domain);
+ if (!NT_STATUS_IS_OK(status)) {
+ TALLOC_FREE(sp_ctx);
+ return status;
+ }
+
+ status = auth_ntlmssp_set_password(sp_ctx->mech_ctx.ntlmssp_state,
+ password);
+ if (!NT_STATUS_IS_OK(status)) {
+ TALLOC_FREE(sp_ctx);
+ return status;
+ }
+
+ /*
+ * Turn off sign+seal to allow selected auth level to turn it back on.
+ */
+ auth_ntlmssp_and_flags(sp_ctx->mech_ctx.ntlmssp_state,
+ ~(NTLMSSP_NEGOTIATE_SIGN |
+ NTLMSSP_NEGOTIATE_SEAL));
+
+ if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
+ auth_ntlmssp_or_flags(sp_ctx->mech_ctx.ntlmssp_state,
+ NTLMSSP_NEGOTIATE_SIGN);
+ } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
+ auth_ntlmssp_or_flags(sp_ctx->mech_ctx.ntlmssp_state,
+ NTLMSSP_NEGOTIATE_SEAL |
+ NTLMSSP_NEGOTIATE_SIGN);
+ }
+
+ *spnego_ctx = sp_ctx;
+ return NT_STATUS_OK;
+}
+
NTSTATUS spnego_get_client_auth_token(TALLOC_CTX *mem_ctx,
struct spnego_context *sp_ctx,
DATA_BLOB *spnego_in,
DATA_BLOB *spnego_out)
{
struct gse_context *gse_ctx;
+ struct auth_ntlmssp_state *ntlmssp_ctx;
struct spnego_data sp_in, sp_out;
DATA_BLOB token_in = data_blob_null;
DATA_BLOB token_out = data_blob_null;
@@ -129,6 +199,7 @@ NTSTATUS spnego_get_client_auth_token(TALLOC_CTX *mem_ctx,
if (sp_ctx->state == SPNEGO_CONV_AUTH_CONFIRM) {
if (sp_in.negTokenTarg.negResult == SPNEGO_ACCEPT_COMPLETED) {
sp_ctx->state = SPNEGO_CONV_AUTH_DONE;
+ *spnego_out = data_blob_null;
status = NT_STATUS_OK;
} else {
status = NT_STATUS_ACCESS_DENIED;
@@ -152,8 +223,21 @@ NTSTATUS spnego_get_client_auth_token(TALLOC_CTX *mem_ctx,
break;
case DCERPC_AUTH_TYPE_NTLMSSP:
- status = NT_STATUS_NOT_IMPLEMENTED;
- goto done;
+
+ ntlmssp_ctx = sp_ctx->mech_ctx.ntlmssp_state;
+ status = auth_ntlmssp_update(ntlmssp_ctx,
+ token_in, &token_out);
+ if (NT_STATUS_EQUAL(status,
+ NT_STATUS_MORE_PROCESSING_REQUIRED)) {
+ mech_wants_more = true;
+ } else if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
+ mech_oids[0] = OID_NTLMSSP;
+
+ break;
+
default:
status = NT_STATUS_INTERNAL_ERROR;
goto done;
@@ -227,6 +311,8 @@ bool spnego_require_more_processing(struct spnego_context *sp_ctx)
case DCERPC_AUTH_TYPE_KRB5:
gse_ctx = sp_ctx->mech_ctx.gssapi_state;
return gse_require_more_processing(gse_ctx);
+ case DCERPC_AUTH_TYPE_NTLMSSP:
+ return false;
default:
DEBUG(0, ("Unsupported type in request!\n"));
return false;
@@ -242,7 +328,7 @@ NTSTATUS spnego_get_negotiated_mech(struct spnego_context *sp_ctx,
*auth_context = sp_ctx->mech_ctx.gssapi_state;
break;
case DCERPC_AUTH_TYPE_NTLMSSP:
- *auth_context = sp_ctx->mech_ctx.auth_ntlmssp_state;
+ *auth_context = sp_ctx->mech_ctx.ntlmssp_state;
break;
default:
return NT_STATUS_INTERNAL_ERROR;
@@ -252,3 +338,17 @@ NTSTATUS spnego_get_negotiated_mech(struct spnego_context *sp_ctx,
return NT_STATUS_OK;
}
+DATA_BLOB spnego_get_session_key(struct spnego_context *sp_ctx)
+{
+ switch (sp_ctx->auth_type) {
+ case DCERPC_AUTH_TYPE_KRB5:
+ return gse_get_session_key(sp_ctx->mech_ctx.gssapi_state);
+ case DCERPC_AUTH_TYPE_NTLMSSP:
+ return auth_ntlmssp_get_session_key(
+ sp_ctx->mech_ctx.ntlmssp_state);
+ default:
+ DEBUG(0, ("Unsupported type in request!\n"));
+ return data_blob_null;
+ }
+}
+
diff --git a/source3/librpc/rpc/dcerpc_spnego.h b/source3/librpc/rpc/dcerpc_spnego.h
index 08458b246f..58363fd072 100644
--- a/source3/librpc/rpc/dcerpc_spnego.h
+++ b/source3/librpc/rpc/dcerpc_spnego.h
@@ -31,6 +31,12 @@ NTSTATUS spnego_gssapi_init_client(TALLOC_CTX *mem_ctx,
const char *password,
uint32_t add_gss_c_flags,
struct spnego_context **spengo_ctx);
+NTSTATUS spnego_ntlmssp_init_client(TALLOC_CTX *mem_ctx,
+ enum dcerpc_AuthLevel auth_level,
+ const char *domain,
+ const char *username,
+ const char *password,
+ struct spnego_context **spnego_ctx);
NTSTATUS spnego_get_client_auth_token(TALLOC_CTX *mem_ctx,
struct spnego_context *sp_ctx,
@@ -43,4 +49,5 @@ NTSTATUS spnego_get_negotiated_mech(struct spnego_context *sp_ctx,
enum dcerpc_AuthType *auth_type,
void **auth_context);
+DATA_BLOB spnego_get_session_key(struct spnego_context *sp_ctx);
#endif /* _DCERPC_SPENGO_H_ */
diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c
index e41966f6fb..5fdfb6374e 100644
--- a/source3/rpc_client/cli_pipe.c
+++ b/source3/rpc_client/cli_pipe.c
@@ -1247,20 +1247,7 @@ static NTSTATUS create_rpc_bind_req(TALLOC_CTX *mem_ctx,
break;
case DCERPC_AUTH_TYPE_SPNEGO:
- switch (auth->spnego_type) {
- case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
- ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli,
- auth->auth_level,
- &auth_info);
- break;
-
- case PIPE_AUTH_TYPE_SPNEGO_KRB5:
- ret = create_spnego_auth_bind_req(cli, auth,
- &auth_info);
- break;
- default:
- return NT_STATUS_INTERNAL_ERROR;
- }
+ ret = create_spnego_auth_bind_req(cli, auth, &auth_info);
if (!NT_STATUS_IS_OK(ret)) {
return ret;
}
@@ -1331,17 +1318,17 @@ static NTSTATUS calculate_data_len_tosend(struct rpc_pipe_client *cli,
/* Treat the same for all authenticated rpc requests. */
switch(cli->auth->auth_type) {
case DCERPC_AUTH_TYPE_SPNEGO:
- switch (cli->auth->spnego_type) {
- case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
+ status = spnego_get_negotiated_mech(
+ cli->auth->a_u.spnego_state,
+ &auth_type, &auth_ctx);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+ switch (auth_type) {
+ case DCERPC_AUTH_TYPE_NTLMSSP:
*p_auth_len = NTLMSSP_SIG_SIZE;
break;
- case PIPE_AUTH_TYPE_SPNEGO_KRB5:
- status = spnego_get_negotiated_mech(
- cli->auth->a_u.spnego_state,
- &auth_type, &auth_ctx);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
+ case DCERPC_AUTH_TYPE_KRB5:
gse_ctx = talloc_get_type(auth_ctx,
struct gse_context);
if (!gse_ctx) {
@@ -1986,36 +1973,24 @@ static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
break;
case DCERPC_AUTH_TYPE_SPNEGO:
- switch (pauth->spnego_type) {
- case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
- /* Need to send alter context request and reply. */
- status = rpc_finish_spnego_ntlmssp_bind_send(req,
- state, &auth.credentials);
- break;
-
- case PIPE_AUTH_TYPE_SPNEGO_KRB5:
- status = spnego_get_client_auth_token(state,
+ status = spnego_get_client_auth_token(state,
pauth->a_u.spnego_state,
&auth.credentials,
&auth_token);
- if (!NT_STATUS_IS_OK(status)) {
- break;
- }
- if (auth_token.length == 0) {
- /* Bind complete. */
- tevent_req_done(req);
- return;
- }
- if (spnego_require_more_processing(pauth->a_u.spnego_state)) {
- status = rpc_bind_next_send(req, state,
- &auth_token);
- } else {
- status = rpc_bind_finish_send(req, state,
- &auth_token);
- }
+ if (!NT_STATUS_IS_OK(status)) {
break;
- default:
- status = NT_STATUS_INTERNAL_ERROR;
+ }
+ if (auth_token.length == 0) {
+ /* Bind complete. */
+ tevent_req_done(req);
+ return;
+ }
+ if (spnego_require_more_processing(pauth->a_u.spnego_state)) {
+ status = rpc_bind_next_send(req, state,
+ &auth_token);
+ } else {
+ status = rpc_bind_finish_send(req, state,
+ &auth_token);
}
break;
@@ -2358,12 +2333,31 @@ bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
{
+ struct auth_ntlmssp_state *a = NULL;
struct cli_state *cli;
- if ((rpc_cli->auth->auth_type == DCERPC_AUTH_TYPE_NTLMSSP)
- || ((rpc_cli->auth->auth_type == DCERPC_AUTH_TYPE_SPNEGO
- && rpc_cli->auth->spnego_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP))) {
- memcpy(nt_hash, auth_ntlmssp_get_nt_hash(rpc_cli->auth->a_u.auth_ntlmssp_state), 16);
+ if (rpc_cli->auth->auth_type == DCERPC_AUTH_TYPE_NTLMSSP) {
+ a = rpc_cli->auth->a_u.auth_ntlmssp_state;
+ } else if (rpc_cli->auth->auth_type == DCERPC_AUTH_TYPE_SPNEGO) {
+ enum dcerpc_AuthType auth_type;
+ void *auth_ctx;
+ NTSTATUS status;
+
+ status = spnego_get_negotiated_mech(
+ rpc_cli->auth->a_u.spnego_state,
+ &auth_type, &auth_ctx);
+ if (!NT_STATUS_IS_OK(status)) {
+ return false;
+ }
+
+ if (auth_type == DCERPC_AUTH_TYPE_NTLMSSP) {
+ a = talloc_get_type(auth_ctx,
+ struct auth_ntlmssp_state);
+ }
+ }
+
+ if (a) {
+ memcpy(nt_hash, auth_ntlmssp_get_nt_hash(a), 16);
return true;
}
@@ -2408,7 +2402,6 @@ static int cli_auth_ntlmssp_data_destructor(struct pipe_auth_data *auth)
static NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
enum dcerpc_AuthType auth_type,
- enum pipe_auth_type_spnego spnego_type,
enum dcerpc_AuthLevel auth_level,
const char *domain,
const char *username,
@@ -2424,7 +2417,6 @@ static NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
}
result->auth_type = auth_type;
- result->spnego_type = spnego_type;
result->auth_level = auth_level;
result->user_name = talloc_strdup(result, username);
@@ -3056,20 +3048,18 @@ NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
****************************************************************************/
-static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
- const struct ndr_syntax_id *interface,
- enum dcerpc_transport_t transport,
- bool use_spnego,
- enum dcerpc_AuthLevel auth_level,
- const char *domain,
- const char *username,
- const char *password,
- struct rpc_pipe_client **presult)
+NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
+ const struct ndr_syntax_id *interface,
+ enum dcerpc_transport_t transport,
+ enum dcerpc_AuthLevel auth_level,
+ const char *domain,
+ const char *username,
+ const char *password,
+ struct rpc_pipe_client **presult)
{
struct rpc_pipe_client *result;
struct pipe_auth_data *auth;
enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
- enum pipe_auth_type_spnego spnego_type = PIPE_AUTH_TYPE_SPNEGO_NONE;
NTSTATUS status;
status = cli_rpc_pipe_open(cli, transport, interface, &result);
@@ -3077,13 +3067,8 @@ static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
return status;
}
- if (use_spnego) {
- auth_type = DCERPC_AUTH_TYPE_SPNEGO;
- spnego_type = PIPE_AUTH_TYPE_SPNEGO_NTLMSSP;
- }
-
status = rpccli_ntlmssp_bind_data(result,
- auth_type, spnego_type, auth_level,
+ auth_type, auth_level,
domain, username, password,
&auth);
if (!NT_STATUS_IS_OK(status)) {
@@ -3114,56 +3099,6 @@ static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
}
/****************************************************************************
- External interface.
- Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
- ****************************************************************************/
-
-NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
- const struct ndr_syntax_id *interface,
- enum dcerpc_transport_t transport,
- enum dcerpc_AuthLevel auth_level,
- const char *domain,
- const char *username,
- const char *password,
- struct rpc_pipe_client **presult)
-{
- return cli_rpc_pipe_open_ntlmssp_internal(cli,
- interface,
- transport,
- false,
- auth_level,
- domain,
- username,
- password,
- presult);
-}
-
-/****************************************************************************
- External interface.
- Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
- ****************************************************************************/
-
-NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
- const struct ndr_syntax_id *interface,
- enum dcerpc_transport_t transport,
- enum dcerpc_AuthLevel auth_level,
- const char *domain,
- const char *username,
- const char *password,
- struct rpc_pipe_client **presult)
-{
- return cli_rpc_pipe_open_ntlmssp_internal(cli,
- interface,
- transport,
- true,
- auth_level,
- domain,
- username,
- password,
- presult);
-}
-
-/****************************************************************************
Get a the schannel session key out of an already opened netlogon pipe.
****************************************************************************/
static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
@@ -3562,6 +3497,74 @@ err_out:
return status;
}
+NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
+ const struct ndr_syntax_id *interface,
+ enum dcerpc_transport_t transport,
+ enum dcerpc_AuthLevel auth_level,
+ const char *domain,
+ const char *username,
+ const char *password,
+ struct rpc_pipe_client **presult)
+{
+ struct rpc_pipe_client *result;
+ struct pipe_auth_data *auth;
+ NTSTATUS status;
+
+ status = cli_rpc_pipe_open(cli, transport, interface, &result);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ auth = talloc(result, struct pipe_auth_data);
+ if (auth == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto err_out;
+ }
+ auth->auth_type = DCERPC_AUTH_TYPE_SPNEGO;
+ auth->auth_level = auth_level;
+
+ if (!username) {
+ username = "";
+ }
+ auth->user_name = talloc_strdup(auth, username);
+ if (!auth->user_name) {
+ status = NT_STATUS_NO_MEMORY;
+ goto err_out;
+ }
+
+ if (!domain) {
+ domain = "";
+ }
+ auth->domain = talloc_strdup(auth, domain);
+ if (!auth->domain) {
+ status = NT_STATUS_NO_MEMORY;
+ goto err_out;
+ }
+
+ status = spnego_ntlmssp_init_client(auth, auth->auth_level,
+ domain, username, password,
+ &auth->a_u.spnego_state);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("spnego_init_client returned %s\n",
+ nt_errstr(status)));
+ goto err_out;
+ }
+
+ status = rpc_pipe_bind(result, auth);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n",
+ nt_errstr(status)));
+ goto err_out;
+ }
+
+ *presult = result;
+ return NT_STATUS_OK;
+
+err_out:
+ TALLOC_FREE(result);
+ return status;
+}
+
NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
struct rpc_pipe_client *cli,
DATA_BLOB *session_key)
@@ -3583,15 +3586,8 @@ NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
16);
break;
case DCERPC_AUTH_TYPE_SPNEGO:
- switch (cli->auth->spnego_type) {
- case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
- sk = auth_ntlmssp_get_session_key(
- a->a_u.auth_ntlmssp_state);
- break;
- case PIPE_AUTH_TYPE_SPNEGO_KRB5:
- sk = gse_get_session_key(a->a_u.gssapi_state);
- break;
- default:
+ sk = spnego_get_session_key(a->a_u.spnego_state);
+ if (sk.length == 0) {
return NT_STATUS_NO_USER_SESSION_KEY;
}
break;