#include "libsmb/libsmb.h"
#include "../lib/util/tevent_ntstatus.h"
#include "async_smb.h"
-#include "../libcli/smb/smb_seal.h"
#include "trans2.h"
#include "auth_generic.h"
#include "auth/gensec/gensec.h"
return NT_STATUS_OK;
}
-
-/******************************************************************************
- Send/receive the request encryption blob.
-******************************************************************************/
-
-static NTSTATUS enc_blob_send_receive(struct cli_state *cli, DATA_BLOB *in, DATA_BLOB *out, DATA_BLOB *param_out)
-{
- uint16_t setup[1];
- uint8_t param[4];
- uint8_t *rparam=NULL, *rdata=NULL;
- uint32_t num_rparam, num_rdata;
- NTSTATUS status;
-
- SSVAL(setup+0, 0, TRANSACT2_SETFSINFO);
- SSVAL(param,0,0);
- SSVAL(param,2,SMB_REQUEST_TRANSPORT_ENCRYPTION);
-
- status = cli_trans(talloc_tos(), cli, SMBtrans2, NULL, 0, 0, 0,
- setup, 1, 0,
- param, 4, 2,
- (uint8_t *)in->data, in->length, CLI_BUFFER_SIZE,
- NULL, /* recv_flags */
- NULL, 0, NULL, /* rsetup */
- &rparam, 0, &num_rparam,
- &rdata, 0, &num_rdata);
-
- if (!NT_STATUS_IS_OK(status) &&
- !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
- return status;
- }
-
- *out = data_blob(rdata, num_rdata);
- *param_out = data_blob(rparam, num_rparam);
-
- TALLOC_FREE(rparam);
- TALLOC_FREE(rdata);
- return status;
-}
-
-/******************************************************************************
- Start a raw ntlmssp encryption.
-******************************************************************************/
-
-NTSTATUS cli_raw_ntlm_smb_encryption_start(struct cli_state *cli,
- const char *user,
- const char *pass,
- const char *domain)
-{
- DATA_BLOB blob_in = data_blob_null;
- DATA_BLOB blob_out = data_blob_null;
- DATA_BLOB param_out = data_blob_null;
- NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
- struct auth_generic_state *auth_generic_state;
- struct smb_trans_enc_state *es = talloc_zero(NULL, struct smb_trans_enc_state);
- if (!es) {
- return NT_STATUS_NO_MEMORY;
- }
- status = auth_generic_client_prepare(es,
- &auth_generic_state);
- if (!NT_STATUS_IS_OK(status)) {
- goto fail;
- }
-
- gensec_want_feature(auth_generic_state->gensec_security, GENSEC_FEATURE_SESSION_KEY);
- gensec_want_feature(auth_generic_state->gensec_security, GENSEC_FEATURE_SEAL);
-
- if (!NT_STATUS_IS_OK(status = auth_generic_set_username(auth_generic_state, user))) {
- goto fail;
- }
- if (!NT_STATUS_IS_OK(status = auth_generic_set_domain(auth_generic_state, domain))) {
- goto fail;
- }
- if (!NT_STATUS_IS_OK(status = auth_generic_set_password(auth_generic_state, pass))) {
- goto fail;
- }
-
- if (!NT_STATUS_IS_OK(status = auth_generic_client_start(auth_generic_state, GENSEC_OID_NTLMSSP))) {
- goto fail;
- }
-
- do {
- status = gensec_update(auth_generic_state->gensec_security, auth_generic_state,
- blob_in, &blob_out);
- data_blob_free(&blob_in);
- data_blob_free(¶m_out);
- if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) || NT_STATUS_IS_OK(status)) {
- NTSTATUS trans_status = enc_blob_send_receive(cli,
- &blob_out,
- &blob_in,
- ¶m_out);
- if (!NT_STATUS_EQUAL(trans_status,
- NT_STATUS_MORE_PROCESSING_REQUIRED) &&
- !NT_STATUS_IS_OK(trans_status)) {
- status = trans_status;
- } else {
- if (param_out.length == 2) {
- es->enc_ctx_num = SVAL(param_out.data, 0);
- }
- }
- }
- data_blob_free(&blob_out);
- } while (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED));
-
- data_blob_free(&blob_in);
-
- if (NT_STATUS_IS_OK(status)) {
- es->enc_on = true;
- /*
- * Replace the old state, if any.
- * We only need the gensec_security part from here.
- */
- es->gensec_security = talloc_move(es,
- &auth_generic_state->gensec_security);
- smb1cli_conn_set_encryption(cli->conn, es);
- es = NULL;
- }
-
- fail:
- TALLOC_FREE(es);
- return status;
-}
-
-/******************************************************************************
- Start a SPNEGO gssapi encryption context.
-******************************************************************************/
-
-NTSTATUS cli_gss_smb_encryption_start(struct cli_state *cli)
-{
- DATA_BLOB blob_recv = data_blob_null;
- DATA_BLOB blob_send = data_blob_null;
- DATA_BLOB param_out = data_blob_null;
- NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
- struct auth_generic_state *auth_generic_state;
- struct smb_trans_enc_state *es = talloc_zero(NULL, struct smb_trans_enc_state);
-
- if (!es) {
- return NT_STATUS_NO_MEMORY;
- }
-
- status = auth_generic_client_prepare(es,
- &auth_generic_state);
- if (!NT_STATUS_IS_OK(status)) {
- goto fail;
- }
-
- gensec_want_feature(auth_generic_state->gensec_security, GENSEC_FEATURE_SESSION_KEY);
- gensec_want_feature(auth_generic_state->gensec_security, GENSEC_FEATURE_SEAL);
-
- cli_credentials_set_kerberos_state(auth_generic_state->credentials,
- CRED_MUST_USE_KERBEROS);
-
- status = gensec_set_target_service(auth_generic_state->gensec_security, "cifs");
- if (!NT_STATUS_IS_OK(status)) {
- goto fail;
- }
-
- status = gensec_set_target_hostname(auth_generic_state->gensec_security,
- smbXcli_conn_remote_name(cli->conn));
- if (!NT_STATUS_IS_OK(status)) {
- goto fail;
- }
-
- if (!NT_STATUS_IS_OK(status = auth_generic_client_start(auth_generic_state, GENSEC_OID_SPNEGO))) {
- goto fail;
- }
-
- status = gensec_update(auth_generic_state->gensec_security, talloc_tos(),
- blob_recv, &blob_send);
-
- do {
- data_blob_free(&blob_recv);
- status = enc_blob_send_receive(cli, &blob_send, &blob_recv, ¶m_out);
- if (param_out.length == 2) {
- es->enc_ctx_num = SVAL(param_out.data, 0);
- }
- data_blob_free(&blob_send);
- status = gensec_update(auth_generic_state->gensec_security, talloc_tos(),
- blob_recv, &blob_send);
- } while (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED));
- data_blob_free(&blob_recv);
-
- if (NT_STATUS_IS_OK(status)) {
- if (!gensec_have_feature(auth_generic_state->gensec_security,
- GENSEC_FEATURE_SIGN) ||
- !gensec_have_feature(auth_generic_state->gensec_security,
- GENSEC_FEATURE_SEAL)) {
- status = NT_STATUS_ACCESS_DENIED;
- }
- }
-
- if (NT_STATUS_IS_OK(status)) {
- es->enc_on = true;
- /*
- * Replace the old state, if any.
- * We only need the gensec_security part from here.
- */
- es->gensec_security = talloc_move(es,
- &auth_generic_state->gensec_security);
- smb1cli_conn_set_encryption(cli->conn, es);
- es = NULL;
- }
-fail:
- TALLOC_FREE(es);
- return status;
-}
-
-/********************************************************************
- Ensure a connection is encrypted.
-********************************************************************/
-
-NTSTATUS cli_force_encryption(struct cli_state *c,
- const char *username,
- const char *password,
- const char *domain)
-{
- uint16_t major, minor;
- uint32_t caplow, caphigh;
- NTSTATUS status;
-
- if (!SERVER_HAS_UNIX_CIFS(c)) {
- return NT_STATUS_NOT_SUPPORTED;
- }
-
- status = cli_unix_extensions_version(c, &major, &minor, &caplow,
- &caphigh);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(10, ("cli_force_encryption: cli_unix_extensions_version "
- "returned %s\n", nt_errstr(status)));
- return NT_STATUS_UNKNOWN_REVISION;
- }
-
- if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
- return NT_STATUS_UNSUPPORTED_COMPRESSION;
- }
-
- if (c->use_kerberos) {
- return cli_gss_smb_encryption_start(c);
- }
- return cli_raw_ntlm_smb_encryption_start(c,
- username,
- password,
- domain);
-}
-
/****************************************************************************
Do a UNIX extensions SMB_QUERY_POSIX_WHOAMI call.
****************************************************************************/