diff options
author | Stefan Metzmacher <metze@samba.org> | 2012-07-26 01:54:33 +0200 |
---|---|---|
committer | Stefan Metzmacher <metze@samba.org> | 2012-07-26 10:02:07 +0200 |
commit | 8cb6557d22fef2570156f56a8bad00cac6b7e016 (patch) | |
tree | 79cffc1fb176b16d99e2329609338c4734e78bb3 /libcli | |
parent | fdd98675ac6faa3f4a9cd1d8907796bbbd97b729 (diff) | |
download | samba-8cb6557d22fef2570156f56a8bad00cac6b7e016.tar.gz |
libcli/smb: add basic session->smb2.channel_sequence handling
metze
Diffstat (limited to 'libcli')
-rw-r--r-- | libcli/smb/smbXcli_base.c | 33 | ||||
-rw-r--r-- | libcli/smb/smbXcli_base.h | 1 |
2 files changed, 34 insertions, 0 deletions
diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c index 5ff92c221f..a363b4451c 100644 --- a/libcli/smb/smbXcli_base.c +++ b/libcli/smb/smbXcli_base.c @@ -139,6 +139,7 @@ struct smb2cli_session { DATA_BLOB decryption_key; uint64_t nonce_high; uint64_t nonce_low; + uint16_t channel_sequence; }; struct smbXcli_session { @@ -910,6 +911,8 @@ static bool smbXcli_conn_receive_next(struct smbXcli_conn *conn) void smbXcli_conn_disconnect(struct smbXcli_conn *conn, NTSTATUS status) { + struct smbXcli_session *session; + tevent_queue_stop(conn->outgoing); if (conn->read_fd != -1) { @@ -921,6 +924,18 @@ void smbXcli_conn_disconnect(struct smbXcli_conn *conn, NTSTATUS status) conn->read_fd = -1; conn->write_fd = -1; + session = conn->sessions; + if (talloc_array_length(conn->pending) == 0) { + /* + * if we do not have pending requests + * there is no need to update the channel_sequence + */ + session = NULL; + } + for (; session; session = session->next) { + smb2cli_session_increment_channel_sequence(session); + } + /* * Cancel all pending requests. We do not do a for-loop walking * conn->pending because that array changes in @@ -2441,6 +2456,8 @@ struct tevent_req *smb2cli_req_create(TALLOC_CTX *mem_ctx, uint32_t flags = 0; uint32_t tid = 0; uint64_t uid = 0; + bool use_channel_sequence = false; + uint16_t channel_sequence = 0; req = tevent_req_create(mem_ctx, &state, struct smbXcli_req_state); @@ -2453,9 +2470,19 @@ struct tevent_req *smb2cli_req_create(TALLOC_CTX *mem_ctx, state->session = session; state->tcon = tcon; + if (conn->smb2.server.capabilities & SMB2_CAP_PERSISTENT_HANDLES) { + use_channel_sequence = true; + } else if (conn->smb2.server.capabilities & SMB2_CAP_MULTI_CHANNEL) { + use_channel_sequence = true; + } + if (session) { uid = session->smb2->session_id; + if (use_channel_sequence) { + channel_sequence = session->smb2->channel_sequence; + } + state->smb2.should_sign = session->smb2->should_sign; state->smb2.should_encrypt = session->smb2->should_encrypt; @@ -2504,6 +2531,7 @@ struct tevent_req *smb2cli_req_create(TALLOC_CTX *mem_ctx, SIVAL(state->smb2.hdr, SMB2_HDR_PROTOCOL_ID, SMB2_MAGIC); SSVAL(state->smb2.hdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY); SSVAL(state->smb2.hdr, SMB2_HDR_OPCODE, cmd); + SSVAL(state->smb2.hdr, SMB2_HDR_CHANNEL_SEQUENCE, channel_sequence); SIVAL(state->smb2.hdr, SMB2_HDR_FLAGS, flags); SIVAL(state->smb2.hdr, SMB2_HDR_PID, 0); /* reserved */ SIVAL(state->smb2.hdr, SMB2_HDR_TID, tid); @@ -4329,6 +4357,11 @@ void smb2cli_session_set_id_and_flags(struct smbXcli_session *session, session->smb2->session_flags = session_flags; } +void smb2cli_session_increment_channel_sequence(struct smbXcli_session *session) +{ + session->smb2->channel_sequence += 1; +} + NTSTATUS smb2cli_session_set_session_key(struct smbXcli_session *session, const DATA_BLOB _session_key, const struct iovec *recv_iov) diff --git a/libcli/smb/smbXcli_base.h b/libcli/smb/smbXcli_base.h index 804fe4428a..c55bf53691 100644 --- a/libcli/smb/smbXcli_base.h +++ b/libcli/smb/smbXcli_base.h @@ -260,6 +260,7 @@ NTSTATUS smb2cli_session_application_key(struct smbXcli_session *session, void smb2cli_session_set_id_and_flags(struct smbXcli_session *session, uint64_t session_id, uint16_t session_flags); +void smb2cli_session_increment_channel_sequence(struct smbXcli_session *session); NTSTATUS smb2cli_session_set_session_key(struct smbXcli_session *session, const DATA_BLOB session_key, const struct iovec *recv_iov); |