The branch, master has been updated via 94799db s3-auth move the s3 auth context onto gensec_ntlmssp once we start via fa12756 s3-libsmb Use a gensec module to provide the ntlmssp client in ntlmssp_wrap.c via f9b0426 s3-ntlmssp split auth_ntlmssp_client_start() into two parts via f3333bd s3-rpc_client remove cli_auth_ntlmssp_data_destructor from 56328a4 s3/doc: add man page for aio_fork vfs module
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 94799db9b5d33ded34ad3e934da673a44d48094a Author: Andrew Bartlett <abart...@samba.org> Date: Tue Oct 18 16:34:27 2011 +1100 s3-auth move the s3 auth context onto gensec_ntlmssp once we start We do not need it on the auth_ntlmssp_state any longer. Andrew Bartlett Autobuild-User: Andrew Bartlett <abart...@samba.org> Autobuild-Date: Tue Oct 18 13:54:36 CEST 2011 on sn-devel-104 commit fa1275610b3c7cad75b5b86ae4b32d8781d1acc0 Author: Andrew Bartlett <abart...@samba.org> Date: Tue Oct 18 16:16:02 2011 +1100 s3-libsmb Use a gensec module to provide the ntlmssp client in ntlmssp_wrap.c This removes the need to have if (ans->gensec_security) everywhere. Andrew Bartlett commit f9b042641f9c6615f6a4b102f0182de545d6a19a Author: Andrew Bartlett <abart...@samba.org> Date: Mon Oct 17 20:19:11 2011 +1100 s3-ntlmssp split auth_ntlmssp_client_start() into two parts This will allow it to be a wrapper around a gensec module, which requires that they options be set on a context, but before the mechanism is started. This also simplfies the callers, by moving the lp_*() calls into one place. Andrew Bartlett commit f3333bdade7d54b19bfcdc2addc685abd165eddf Author: Andrew Bartlett <abart...@samba.org> Date: Mon Oct 17 20:00:02 2011 +1100 s3-rpc_client remove cli_auth_ntlmssp_data_destructor This can be an ordinary talloc child without causing any problem. This seems to have been inherited from a time when ntlmssp_client_start() returned malloc() based memory. Andrew Bartlett ----------------------------------------------------------------------- Summary of changes: source3/auth/auth_ntlmssp.c | 4 +- source3/include/ntlmssp_wrap.h | 17 ++- source3/librpc/crypto/cli_spnego.c | 11 +- source3/libsmb/clifsinfo.c | 11 +- source3/libsmb/ntlmssp_wrap.c | 281 +++++++++++++++++++++++++----------- source3/rpc_client/cli_pipe.c | 20 +-- 6 files changed, 229 insertions(+), 115 deletions(-) Changeset truncated at 500 lines: diff --git a/source3/auth/auth_ntlmssp.c b/source3/auth/auth_ntlmssp.c index 7509840..e22db82 100644 --- a/source3/auth/auth_ntlmssp.c +++ b/source3/auth/auth_ntlmssp.c @@ -406,7 +406,7 @@ NTSTATUS auth_generic_start(struct auth_ntlmssp_state *auth_ntlmssp_state, const talloc_get_type_abort(auth_ntlmssp_state->gensec_security->private_data, struct gensec_ntlmssp_context); - gensec_ntlmssp->auth_context = auth_ntlmssp_state->auth_context; + gensec_ntlmssp->auth_context = talloc_move(gensec_ntlmssp, &auth_ntlmssp_state->auth_context); return NT_STATUS_OK; } @@ -464,7 +464,7 @@ NTSTATUS auth_generic_authtype_start(struct auth_ntlmssp_state *auth_ntlmssp_sta talloc_get_type_abort(auth_ntlmssp_state->gensec_security->private_data, struct gensec_ntlmssp_context); - gensec_ntlmssp->auth_context = auth_ntlmssp_state->auth_context; + gensec_ntlmssp->auth_context = talloc_move(gensec_ntlmssp, &auth_ntlmssp_state->auth_context); return NT_STATUS_OK; } diff --git a/source3/include/ntlmssp_wrap.h b/source3/include/ntlmssp_wrap.h index 863c359..bfbfdeb 100644 --- a/source3/include/ntlmssp_wrap.h +++ b/source3/include/ntlmssp_wrap.h @@ -26,10 +26,12 @@ struct gensec_security; struct auth_ntlmssp_state { /* used only by server implementation */ struct auth_context *auth_context; - struct gensec_security *gensec_security; - + /* used only by the client implementation */ - struct ntlmssp_state *ntlmssp_state; + struct cli_credentials *credentials; + + /* used by both */ + struct gensec_security *gensec_security; }; NTSTATUS auth_ntlmssp_sign_packet(struct auth_ntlmssp_state *ans, @@ -74,9 +76,8 @@ NTSTATUS auth_ntlmssp_update(struct auth_ntlmssp_state *ans, TALLOC_CTX *mem_ctx, const DATA_BLOB request, DATA_BLOB *reply); -NTSTATUS auth_ntlmssp_client_start(TALLOC_CTX *mem_ctx, - const char *netbios_name, - const char *netbios_domain, - bool use_ntlmv2, - struct auth_ntlmssp_state **_ans); +NTSTATUS auth_ntlmssp_client_prepare(TALLOC_CTX *mem_ctx, + struct auth_ntlmssp_state **_ans); +NTSTATUS auth_ntlmssp_client_start(struct auth_ntlmssp_state *ans); + #endif /* _NTLMSSP_WRAP_ */ diff --git a/source3/librpc/crypto/cli_spnego.c b/source3/librpc/crypto/cli_spnego.c index 3420e20..4742158 100644 --- a/source3/librpc/crypto/cli_spnego.c +++ b/source3/librpc/crypto/cli_spnego.c @@ -99,10 +99,7 @@ NTSTATUS spnego_ntlmssp_init_client(TALLOC_CTX *mem_ctx, } sp_ctx->mech = SPNEGO_NTLMSSP; - status = auth_ntlmssp_client_start(sp_ctx, - lp_netbios_name(), - lp_workgroup(), - lp_client_ntlmv2_auth(), + status = auth_ntlmssp_client_prepare(sp_ctx, &sp_ctx->mech_ctx.ntlmssp_state); if (!NT_STATUS_IS_OK(status)) { TALLOC_FREE(sp_ctx); @@ -138,6 +135,12 @@ NTSTATUS spnego_ntlmssp_init_client(TALLOC_CTX *mem_ctx, NTLMSSP_FEATURE_SEAL); } + status = auth_ntlmssp_client_start(sp_ctx->mech_ctx.ntlmssp_state); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(sp_ctx); + return status; + } + *spnego_ctx = sp_ctx; return NT_STATUS_OK; } diff --git a/source3/libsmb/clifsinfo.c b/source3/libsmb/clifsinfo.c index 12961c9..b312cfb 100644 --- a/source3/libsmb/clifsinfo.c +++ b/source3/libsmb/clifsinfo.c @@ -613,11 +613,8 @@ NTSTATUS cli_raw_ntlm_smb_encryption_start(struct cli_state *cli, if (!es) { return NT_STATUS_NO_MEMORY; } - status = auth_ntlmssp_client_start(NULL, - lp_netbios_name(), - lp_workgroup(), - lp_client_ntlmv2_auth(), - &es->s.auth_ntlmssp_state); + status = auth_ntlmssp_client_prepare(NULL, + &es->s.auth_ntlmssp_state); if (!NT_STATUS_IS_OK(status)) { goto fail; } @@ -635,6 +632,10 @@ NTSTATUS cli_raw_ntlm_smb_encryption_start(struct cli_state *cli, goto fail; } + if (!NT_STATUS_IS_OK(status = auth_ntlmssp_client_start(es->s.auth_ntlmssp_state))) { + goto fail; + } + do { status = auth_ntlmssp_update(es->s.auth_ntlmssp_state, es->s.auth_ntlmssp_state, blob_in, &blob_out); diff --git a/source3/libsmb/ntlmssp_wrap.c b/source3/libsmb/ntlmssp_wrap.c index 6f854f2..3d1d099 100644 --- a/source3/libsmb/ntlmssp_wrap.c +++ b/source3/libsmb/ntlmssp_wrap.c @@ -22,6 +22,9 @@ #include "auth/ntlmssp/ntlmssp.h" #include "ntlmssp_wrap.h" #include "auth/gensec/gensec.h" +#include "auth/credentials/credentials.h" +#include "librpc/rpc/dcerpc.h" +#include "lib/param/param.h" NTSTATUS auth_ntlmssp_sign_packet(struct auth_ntlmssp_state *ans, TALLOC_CTX *sig_mem_ctx, @@ -31,15 +34,8 @@ NTSTATUS auth_ntlmssp_sign_packet(struct auth_ntlmssp_state *ans, size_t pdu_length, DATA_BLOB *sig) { - if (ans->gensec_security) { - return gensec_sign_packet(ans->gensec_security, - sig_mem_ctx, data, length, whole_pdu, pdu_length, sig); - } - return ntlmssp_sign_packet(ans->ntlmssp_state, - sig_mem_ctx, - data, length, - whole_pdu, pdu_length, - sig); + return gensec_sign_packet(ans->gensec_security, + sig_mem_ctx, data, length, whole_pdu, pdu_length, sig); } NTSTATUS auth_ntlmssp_check_packet(struct auth_ntlmssp_state *ans, @@ -49,14 +45,8 @@ NTSTATUS auth_ntlmssp_check_packet(struct auth_ntlmssp_state *ans, size_t pdu_length, const DATA_BLOB *sig) { - if (ans->gensec_security) { - return gensec_check_packet(ans->gensec_security, - data, length, whole_pdu, pdu_length, sig); - } - return ntlmssp_check_packet(ans->ntlmssp_state, - data, length, - whole_pdu, pdu_length, - sig); + return gensec_check_packet(ans->gensec_security, + data, length, whole_pdu, pdu_length, sig); } NTSTATUS auth_ntlmssp_seal_packet(struct auth_ntlmssp_state *ans, @@ -67,15 +57,8 @@ NTSTATUS auth_ntlmssp_seal_packet(struct auth_ntlmssp_state *ans, size_t pdu_length, DATA_BLOB *sig) { - if (ans->gensec_security) { - return gensec_seal_packet(ans->gensec_security, - sig_mem_ctx, data, length, whole_pdu, pdu_length, sig); - } - return ntlmssp_seal_packet(ans->ntlmssp_state, - sig_mem_ctx, - data, length, - whole_pdu, pdu_length, - sig); + return gensec_seal_packet(ans->gensec_security, + sig_mem_ctx, data, length, whole_pdu, pdu_length, sig); } NTSTATUS auth_ntlmssp_unseal_packet(struct auth_ntlmssp_state *ans, @@ -85,115 +68,247 @@ NTSTATUS auth_ntlmssp_unseal_packet(struct auth_ntlmssp_state *ans, size_t pdu_length, const DATA_BLOB *sig) { - if (ans->gensec_security) { - return gensec_unseal_packet(ans->gensec_security, - data, length, whole_pdu, pdu_length, sig); - } - return ntlmssp_unseal_packet(ans->ntlmssp_state, - data, length, - whole_pdu, pdu_length, - sig); + return gensec_unseal_packet(ans->gensec_security, + data, length, whole_pdu, pdu_length, sig); } bool auth_ntlmssp_negotiated_sign(struct auth_ntlmssp_state *ans) { - if (ans->gensec_security) { - return gensec_have_feature(ans->gensec_security, GENSEC_FEATURE_SIGN); - } - return ans->ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN; + return gensec_have_feature(ans->gensec_security, GENSEC_FEATURE_SIGN); } bool auth_ntlmssp_negotiated_seal(struct auth_ntlmssp_state *ans) { - if (ans->gensec_security) { - return gensec_have_feature(ans->gensec_security, GENSEC_FEATURE_SEAL); - } - return ans->ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL; + return gensec_have_feature(ans->gensec_security, GENSEC_FEATURE_SEAL); } NTSTATUS auth_ntlmssp_set_username(struct auth_ntlmssp_state *ans, const char *user) { - return ntlmssp_set_username(ans->ntlmssp_state, user); + cli_credentials_set_username(ans->credentials, user, CRED_SPECIFIED); + return NT_STATUS_OK; } NTSTATUS auth_ntlmssp_set_domain(struct auth_ntlmssp_state *ans, const char *domain) { - return ntlmssp_set_domain(ans->ntlmssp_state, domain); + cli_credentials_set_domain(ans->credentials, domain, CRED_SPECIFIED); + return NT_STATUS_OK; } NTSTATUS auth_ntlmssp_set_password(struct auth_ntlmssp_state *ans, const char *password) { - return ntlmssp_set_password(ans->ntlmssp_state, password); + cli_credentials_set_password(ans->credentials, password, CRED_SPECIFIED); + return NT_STATUS_OK; } void auth_ntlmssp_want_feature(struct auth_ntlmssp_state *ans, uint32_t feature) { - if (ans->gensec_security) { - if (feature & NTLMSSP_FEATURE_SESSION_KEY) { - gensec_want_feature(ans->gensec_security, GENSEC_FEATURE_SESSION_KEY); - } - if (feature & NTLMSSP_FEATURE_SIGN) { - gensec_want_feature(ans->gensec_security, GENSEC_FEATURE_SIGN); - } - if (feature & NTLMSSP_FEATURE_SEAL) { - gensec_want_feature(ans->gensec_security, GENSEC_FEATURE_SEAL); - } - } else { - ntlmssp_want_feature(ans->ntlmssp_state, feature); + if (feature & NTLMSSP_FEATURE_SESSION_KEY) { + gensec_want_feature(ans->gensec_security, GENSEC_FEATURE_SESSION_KEY); + } + if (feature & NTLMSSP_FEATURE_SIGN) { + gensec_want_feature(ans->gensec_security, GENSEC_FEATURE_SIGN); + } + if (feature & NTLMSSP_FEATURE_SEAL) { + gensec_want_feature(ans->gensec_security, GENSEC_FEATURE_SEAL); } } DATA_BLOB auth_ntlmssp_get_session_key(struct auth_ntlmssp_state *ans, TALLOC_CTX *mem_ctx) { - if (ans->gensec_security) { - DATA_BLOB session_key; - NTSTATUS status = gensec_session_key(ans->gensec_security, mem_ctx, &session_key); - if (NT_STATUS_IS_OK(status)) { - return session_key; - } else { - return data_blob_null; - } + DATA_BLOB session_key; + NTSTATUS status = gensec_session_key(ans->gensec_security, mem_ctx, &session_key); + if (NT_STATUS_IS_OK(status)) { + return session_key; + } else { + return data_blob_null; } - return data_blob_talloc(mem_ctx, ans->ntlmssp_state->session_key.data, ans->ntlmssp_state->session_key.length); } NTSTATUS auth_ntlmssp_update(struct auth_ntlmssp_state *ans, TALLOC_CTX *mem_ctx, const DATA_BLOB request, DATA_BLOB *reply) { + return gensec_update(ans->gensec_security, mem_ctx, NULL, request, reply); +} + +static NTSTATUS gensec_ntlmssp3_client_update(struct gensec_security *gensec_security, + TALLOC_CTX *out_mem_ctx, + struct tevent_context *ev, + const DATA_BLOB request, + DATA_BLOB *reply) +{ NTSTATUS status; - if (ans->gensec_security) { - return gensec_update(ans->gensec_security, mem_ctx, NULL, request, reply); - } - status = ntlmssp_update(ans->ntlmssp_state, request, reply); - if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - return status; + struct gensec_ntlmssp_context *gensec_ntlmssp = + talloc_get_type_abort(gensec_security->private_data, + struct gensec_ntlmssp_context); + + status = ntlmssp_update(gensec_ntlmssp->ntlmssp_state, request, reply); + if (NT_STATUS_IS_OK(status) || + NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + talloc_steal(out_mem_ctx, reply->data); } - talloc_steal(mem_ctx, reply->data); + return status; } -NTSTATUS auth_ntlmssp_client_start(TALLOC_CTX *mem_ctx, - const char *netbios_name, - const char *netbios_domain, - bool use_ntlmv2, - struct auth_ntlmssp_state **_ans) +static NTSTATUS gensec_ntlmssp3_client_start(struct gensec_security *gensec_security) +{ + NTSTATUS nt_status; + struct gensec_ntlmssp_context *gensec_ntlmssp; + const char *user, *domain; + const char *password; + + nt_status = gensec_ntlmssp_start(gensec_security); + NT_STATUS_NOT_OK_RETURN(nt_status); + + gensec_ntlmssp = + talloc_get_type_abort(gensec_security->private_data, + struct gensec_ntlmssp_context); + + nt_status = ntlmssp_client_start(gensec_ntlmssp, + lp_netbios_name(), lp_workgroup(), + lp_client_ntlmv2_auth(), &gensec_ntlmssp->ntlmssp_state); + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; + } + + cli_credentials_get_ntlm_username_domain(gensec_security->credentials, gensec_ntlmssp, &user, &domain); + if (!user || !domain) { + return NT_STATUS_NO_MEMORY; + } + + nt_status = ntlmssp_set_username(gensec_ntlmssp->ntlmssp_state, user); + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; + } + + nt_status = ntlmssp_set_domain(gensec_ntlmssp->ntlmssp_state, domain); + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; + } + + password = cli_credentials_get_password(gensec_security->credentials); + if (!password) { + return NT_STATUS_NO_MEMORY; + } + + nt_status = ntlmssp_set_password(gensec_ntlmssp->ntlmssp_state, password); + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; + } + + if (gensec_ntlmssp->gensec_security->want_features & GENSEC_FEATURE_SESSION_KEY) { + gensec_ntlmssp->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; + } + if (gensec_ntlmssp->gensec_security->want_features & GENSEC_FEATURE_SIGN) { + gensec_ntlmssp->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; + } + if (gensec_ntlmssp->gensec_security->want_features & GENSEC_FEATURE_SEAL) { + gensec_ntlmssp->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; + gensec_ntlmssp->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL; + } + + return NT_STATUS_OK; +} + +static const char *gensec_ntlmssp3_client_oids[] = { + GENSEC_OID_NTLMSSP, + NULL +}; + +static const struct gensec_security_ops gensec_ntlmssp3_client_ops = { + .name = "ntlmssp3_client", + .sasl_name = GENSEC_SASL_NAME_NTLMSSP, /* "NTLM" */ + .auth_type = DCERPC_AUTH_TYPE_NTLMSSP, + .oid = gensec_ntlmssp3_client_oids, + .client_start = gensec_ntlmssp3_client_start, + .magic = gensec_ntlmssp_magic, + .update = gensec_ntlmssp3_client_update, + .sig_size = gensec_ntlmssp_sig_size, + .sign_packet = gensec_ntlmssp_sign_packet, + .check_packet = gensec_ntlmssp_check_packet, + .seal_packet = gensec_ntlmssp_seal_packet, + .unseal_packet = gensec_ntlmssp_unseal_packet, + .wrap = gensec_ntlmssp_wrap, + .unwrap = gensec_ntlmssp_unwrap, + .session_key = gensec_ntlmssp_session_key, + .have_feature = gensec_ntlmssp_have_feature, + .enabled = true, + .priority = GENSEC_NTLMSSP +}; + +NTSTATUS auth_ntlmssp_client_prepare(TALLOC_CTX *mem_ctx, struct auth_ntlmssp_state **auth_ntlmssp_state) { struct auth_ntlmssp_state *ans; - NTSTATUS status; + NTSTATUS nt_status; + + struct gensec_settings *gensec_settings; + struct loadparm_context *lp_ctx; ans = talloc_zero(mem_ctx, struct auth_ntlmssp_state); + if (!ans) { + DEBUG(0,("auth_ntlmssp_start: talloc failed!\n")); + return NT_STATUS_NO_MEMORY; + } + + lp_ctx = loadparm_init_s3(ans, loadparm_s3_context()); + if (lp_ctx == NULL) { + DEBUG(10, ("loadparm_init_s3 failed\n")); + TALLOC_FREE(ans); + return NT_STATUS_INVALID_SERVER_STATE; + } + + gensec_settings = lpcfg_gensec_settings(ans, lp_ctx); + if (lp_ctx == NULL) { + DEBUG(10, ("lpcfg_gensec_settings failed\n")); + TALLOC_FREE(ans); + return NT_STATUS_NO_MEMORY; + } + + nt_status = gensec_client_start(ans, &ans->gensec_security, gensec_settings); + + if (!NT_STATUS_IS_OK(nt_status)) { + TALLOC_FREE(ans); + return nt_status; + } + + ans->credentials = cli_credentials_init(ans); + if (!ans->credentials) { + TALLOC_FREE(ans); + return NT_STATUS_NO_MEMORY; + } + + cli_credentials_guess(ans->credentials, lp_ctx); + + talloc_unlink(ans, lp_ctx); + talloc_unlink(ans, gensec_settings); + + *auth_ntlmssp_state = ans; + return NT_STATUS_OK; +} + +NTSTATUS auth_ntlmssp_client_start(struct auth_ntlmssp_state *ans) +{ + NTSTATUS status; + + /* Transfer the credentials to gensec */ + status = gensec_set_credentials(ans->gensec_security, ans->credentials); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to set GENSEC credentials: %s\n", + nt_errstr(status))); + return status; + } + talloc_unlink(ans, ans->credentials); + ans->credentials = NULL; - status = ntlmssp_client_start(ans, - netbios_name, netbios_domain, - use_ntlmv2, &ans->ntlmssp_state); + status = gensec_start_mech_by_ops(ans->gensec_security, + &gensec_ntlmssp3_client_ops); if (!NT_STATUS_IS_OK(status)) { return status; } - *_ans = ans; return NT_STATUS_OK; } diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 65bc028..94e4a51 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2256,12 +2256,6 @@ NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx, return NT_STATUS_OK; } -static int cli_auth_ntlmssp_data_destructor(struct pipe_auth_data *auth) -{ - TALLOC_FREE(auth->auth_ctx); - return 0; -} - -- Samba Shared Repository