mirror of
https://github.com/samba-team/samba.git
synced 2025-02-23 09:57:40 +03:00
s3-dcerpc: use common spengo wrapper code for client SPNEGO/NTLMSSP
This commit is contained in:
parent
984438ca15
commit
186f93633b
@ -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 {
|
||||
|
@ -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;
|
||||
if (auth->spnego_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
|
||||
/* compat for server code */
|
||||
DEBUG(10, ("NTLMSSP auth\n"));
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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"));
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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_ */
|
||||
|
@ -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)) {
|
||||
@ -3113,56 +3098,6 @@ static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
|
||||
return status;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
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.
|
||||
****************************************************************************/
|
||||
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user