uint8_t io_priority;
+ bool force_channel_sequence;
+
uint8_t preauth_sha512[64];
} smb2;
return false;
}
+bool smbXcli_conn_signing_mandatory(struct smbXcli_conn *conn)
+{
+ return conn->mandatory_signing;
+}
+
+/*
+ * [MS-SMB] 2.2.2.3.5 - SMB1 support for passing through
+ * query/set commands to the file system
+ */
+bool smbXcli_conn_support_passthrough(struct smbXcli_conn *conn)
+{
+ if (conn->protocol >= PROTOCOL_SMB2_02) {
+ return true;
+ }
+
+ if (conn->smb1.capabilities & CAP_W2K_SMBS) {
+ return true;
+ }
+
+ return false;
+}
+
void smbXcli_conn_set_sockopt(struct smbXcli_conn *conn, const char *options)
{
set_socket_options(conn->sock_fd, options);
return &conn->smb1.server.guid;
}
+bool smbXcli_conn_get_force_channel_sequence(struct smbXcli_conn *conn)
+{
+ return conn->smb2.force_channel_sequence;
+}
+
+void smbXcli_conn_set_force_channel_sequence(struct smbXcli_conn *conn,
+ bool v)
+{
+ conn->smb2.force_channel_sequence = v;
+}
+
struct smbXcli_conn_samba_suicide_state {
struct smbXcli_conn *conn;
struct iovec iov;
/*
* Check if it's possible to cancel the request.
- * If the result is true it's not to late.
+ * If the result is true it's not too late.
* See writev_cancel().
*/
ok = tevent_req_cancel(state->write_req);
return ret;
}
-static uint8_t *smbXcli_iov_concat(TALLOC_CTX *mem_ctx,
- const struct iovec *iov,
- int count)
-{
- ssize_t buflen;
- uint8_t *buf;
-
- buflen = iov_buflen(iov, count);
- if (buflen == -1) {
- return NULL;
- }
-
- buf = talloc_array(mem_ctx, uint8_t, buflen);
- if (buf == NULL) {
- return NULL;
- }
-
- iov_buf(iov, count, buf, buflen);
-
- return buf;
-}
-
static void smb1cli_req_flags(enum protocol_types protocol,
uint32_t smb1_capabilities,
uint8_t smb_command,
frame = talloc_stackframe();
- buf = smbXcli_iov_concat(frame, &iov[1], iov_count - 1);
+ buf = iov_concat(frame, &iov[1], iov_count - 1);
if (buf == NULL) {
return NT_STATUS_NO_MEMORY;
}
}
if (state->conn->protocol > PROTOCOL_NT1) {
+ DBG_ERR("called for dialect[%s] server[%s]\n",
+ smb_protocol_types_string(state->conn->protocol),
+ smbXcli_conn_remote_name(state->conn));
return NT_STATUS_REVISION_MISMATCH;
}
if (common_encryption_on(state->conn->smb1.trans_enc)) {
char *buf, *enc_buf;
- buf = (char *)smbXcli_iov_concat(talloc_tos(), iov, iov_count);
+ buf = (char *)iov_concat(talloc_tos(), iov, iov_count);
if (buf == NULL) {
return NT_STATUS_NO_MEMORY;
}
conn->smb2.max_credits = max_credits;
}
+uint16_t smb2cli_conn_get_cur_credits(struct smbXcli_conn *conn)
+{
+ return conn->smb2.cur_credits;
+}
+
uint8_t smb2cli_conn_get_io_priority(struct smbXcli_conn *conn)
{
if (conn->protocol < PROTOCOL_SMB3_11) {
uint32_t flags = 0;
uint32_t tid = 0;
uint64_t uid = 0;
- bool use_channel_sequence = false;
+ bool use_channel_sequence = conn->smb2.force_channel_sequence;
uint16_t channel_sequence = 0;
bool use_replay_flag = false;
return;
}
+ /*
+ * Here we are now at SMB3_11, so encryption should be
+ * negotiated via context, not capabilities.
+ */
+
if (conn->smb2.server.capabilities & SMB2_CAP_ENCRYPTION) {
- tevent_req_nterror(req,
- NT_STATUS_INVALID_NETWORK_RESPONSE);
- return;
+ /*
+ * Server set SMB2_CAP_ENCRYPTION capability,
+ * but *SHOULD* not, not *MUST* not. Just mask it off.
+ * NetApp seems to do this:
+ * BUG: https://bugzilla.samba.org/show_bug.cgi?id=13009
+ */
+ conn->smb2.server.capabilities &= ~SMB2_CAP_ENCRYPTION;
}
negotiate_context_offset = IVAL(body, 60);
tevent_req_done(req);
return;
}
+ if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
+ /*
+ * The response was signed, but not supported
+ *
+ * This might be returned by older Windows versions or by
+ * NetApp SMB server implementations.
+ *
+ * See
+ *
+ * https://blogs.msdn.microsoft.com/openspecification/2012/06/28/smb3-secure-dialect-negotiation/
+ *
+ */
+ tevent_req_done(req);
+ return;
+ }
if (tevent_req_nterror(req, status)) {
return;
}
return tcon;
}
+/*
+ * Return a deep structure copy of a struct smbXcli_tcon *
+ */
+
+struct smbXcli_tcon *smbXcli_tcon_copy(TALLOC_CTX *mem_ctx,
+ const struct smbXcli_tcon *tcon_in)
+{
+ struct smbXcli_tcon *tcon;
+
+ tcon = talloc_memdup(mem_ctx, tcon_in, sizeof(struct smbXcli_tcon));
+ if (tcon == NULL) {
+ return NULL;
+ }
+
+ /* Deal with the SMB1 strings. */
+ if (tcon_in->smb1.service != NULL) {
+ tcon->smb1.service = talloc_strdup(tcon, tcon_in->smb1.service);
+ if (tcon->smb1.service == NULL) {
+ TALLOC_FREE(tcon);
+ return NULL;
+ }
+ }
+ if (tcon->smb1.fs_type != NULL) {
+ tcon->smb1.fs_type = talloc_strdup(tcon, tcon_in->smb1.fs_type);
+ if (tcon->smb1.fs_type == NULL) {
+ TALLOC_FREE(tcon);
+ return NULL;
+ }
+ }
+ return tcon;
+}
+
void smbXcli_tcon_set_fs_attributes(struct smbXcli_tcon *tcon,
uint32_t fs_attributes)
{
return tcon->smb2.tcon_id;
}
+void smb2cli_tcon_set_id(struct smbXcli_tcon *tcon, uint32_t tcon_id)
+{
+ tcon->smb2.tcon_id = tcon_id;
+}
+
uint32_t smb2cli_tcon_capabilities(struct smbXcli_tcon *tcon)
{
return tcon->smb2.capabilities;
{
return tcon->smb2.should_encrypt;
}
+
+void smb2cli_conn_set_mid(struct smbXcli_conn *conn, uint64_t mid)
+{
+ conn->smb2.mid = mid;
+}
+
+uint64_t smb2cli_conn_get_mid(struct smbXcli_conn *conn)
+{
+ return conn->smb2.mid;
+}