smbXcli: add smbXcli_session infrastructure
authorStefan Metzmacher <metze@samba.org>
Sat, 3 Sep 2011 08:18:17 +0000 (10:18 +0200)
committerStefan Metzmacher <metze@samba.org>
Thu, 24 Nov 2011 18:02:31 +0000 (19:02 +0100)
metze

libcli/smb/smbXcli_base.c
libcli/smb/smbXcli_base.h

index e792247727eeb689c17f2bd3cb5ecbc280e9a6a4..2cb5d449d94ea15dd47f24eb0ca7b50959da121a 100644 (file)
@@ -24,6 +24,7 @@
 #include "../lib/util/tevent_ntstatus.h"
 #include "../lib/util/tevent_unix.h"
 #include "lib/util/util_net.h"
+#include "lib/util/dlinklist.h"
 #include "../libcli/smb/smb_common.h"
 #include "../libcli/smb/smb_seal.h"
 #include "../libcli/smb/smb_signing.h"
 #include "smbXcli_base.h"
 #include "librpc/ndr/libndr.h"
 
+struct smbXcli_conn;
+struct smbXcli_req;
+struct smbXcli_session;
+
 struct smbXcli_conn {
        int fd;
        struct sockaddr_storage local_ss;
@@ -114,6 +119,21 @@ struct smbXcli_conn {
                uint16_t cur_credits;
                uint16_t max_credits;
        } smb2;
+
+       struct smbXcli_session *sessions;
+};
+
+struct smbXcli_session {
+       struct smbXcli_session *prev, *next;
+       struct smbXcli_conn *conn;
+
+       struct {
+               uint64_t session_id;
+               uint16_t session_flags;
+               DATA_BLOB signing_key;
+               DATA_BLOB session_key;
+               bool should_sign;
+       } smb2;
 };
 
 struct smbXcli_req_state {
@@ -178,6 +198,11 @@ static int smbXcli_conn_destructor(struct smbXcli_conn *conn)
         */
        smbXcli_conn_disconnect(conn, NT_STATUS_OK);
 
+       while (conn->sessions) {
+               conn->sessions->conn = NULL;
+               DLIST_REMOVE(conn->sessions, conn->sessions);
+       }
+
        if (conn->smb1.trans_enc) {
                common_free_encryption_state(&conn->smb1.trans_enc);
        }
@@ -3391,3 +3416,118 @@ NTSTATUS smbXcli_negprot(struct smbXcli_conn *conn,
        TALLOC_FREE(frame);
        return status;
 }
+
+static int smbXcli_session_destructor(struct smbXcli_session *session)
+{
+       if (session->conn == NULL) {
+               return 0;
+       }
+
+       DLIST_REMOVE(session->conn->sessions, session);
+       return 0;
+}
+
+struct smbXcli_session *smbXcli_session_create(TALLOC_CTX *mem_ctx,
+                                              struct smbXcli_conn *conn)
+{
+       struct smbXcli_session *session;
+
+       session = talloc_zero(mem_ctx, struct smbXcli_session);
+       if (session == NULL) {
+               return NULL;
+       }
+       talloc_set_destructor(session, smbXcli_session_destructor);
+
+       DLIST_ADD_END(conn->sessions, session, struct smbXcli_session *);
+       session->conn = conn;
+
+       return session;
+}
+
+uint8_t smb2cli_session_security_mode(struct smbXcli_session *session)
+{
+       struct smbXcli_conn *conn = session->conn;
+       uint8_t security_mode = 0;
+
+       if (conn == NULL) {
+               return security_mode;
+       }
+
+       security_mode = SMB2_NEGOTIATE_SIGNING_ENABLED;
+       if (conn->mandatory_signing) {
+               security_mode |= SMB2_NEGOTIATE_SIGNING_REQUIRED;
+       }
+
+       return security_mode;
+}
+
+uint64_t smb2cli_session_current_id(struct smbXcli_session *session)
+{
+       return session->smb2.session_id;
+}
+
+void smb2cli_session_set_id_and_flags(struct smbXcli_session *session,
+                                     uint64_t session_id,
+                                     uint16_t session_flags)
+{
+       session->smb2.session_id = session_id;
+       session->smb2.session_flags = session_flags;
+}
+
+NTSTATUS smb2cli_session_update_session_key(struct smbXcli_session *session,
+                                           const DATA_BLOB session_key,
+                                           const struct iovec *recv_iov)
+{
+       struct smbXcli_conn *conn = session->conn;
+       uint16_t no_sign_flags;
+       DATA_BLOB signing_key;
+       NTSTATUS status;
+
+       if (conn == NULL) {
+               return NT_STATUS_INVALID_PARAMETER_MIX;
+       }
+
+       no_sign_flags = SMB2_SESSION_FLAG_IS_GUEST | SMB2_SESSION_FLAG_IS_NULL;
+
+       if (session->smb2.session_flags & no_sign_flags) {
+               session->smb2.should_sign = false;
+               return NT_STATUS_OK;
+       }
+
+       if (session->smb2.signing_key.length > 0) {
+               signing_key = session->smb2.signing_key;
+       } else {
+               signing_key = session_key;
+       }
+
+       status = smb2_signing_check_pdu(signing_key, recv_iov, 3);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       session->smb2.session_key = data_blob_dup_talloc(session, session_key);
+       if (session->smb2.session_key.data == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       if (session->smb2.signing_key.length > 0) {
+               return NT_STATUS_OK;
+       }
+
+       session->smb2.signing_key = data_blob_dup_talloc(session, signing_key);
+       if (session->smb2.signing_key.data == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       session->smb2.should_sign = false;
+
+       if (conn->desire_signing) {
+               session->smb2.should_sign = true;
+       }
+
+       if (conn->smb2.server.security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) {
+               session->smb2.should_sign = true;
+       }
+
+       return NT_STATUS_OK;
+}
index df34d6c89448dd8b3a0027f1fd5b1570d6c85cbc..c64e3bad2fb23f66bb05c49fd79272669945d3df 100644 (file)
@@ -22,6 +22,7 @@
 #define _SMBXCLI_BASE_H_
 
 struct smbXcli_conn;
+struct smbXcli_session;
 struct smb_trans_enc_state;
 struct GUID;
 
@@ -193,4 +194,15 @@ NTSTATUS smbXcli_negprot(struct smbXcli_conn *conn,
                         enum protocol_types min_protocol,
                         enum protocol_types max_protocol);
 
+struct smbXcli_session *smbXcli_session_create(TALLOC_CTX *mem_ctx,
+                                              struct smbXcli_conn *conn);
+uint8_t smb2cli_session_security_mode(struct smbXcli_session *session);
+uint64_t smb2cli_session_current_id(struct smbXcli_session *session);
+void smb2cli_session_set_id_and_flags(struct smbXcli_session *session,
+                                     uint64_t session_id,
+                                     uint16_t session_flags);
+NTSTATUS smb2cli_session_update_session_key(struct smbXcli_session *session,
+                                           const DATA_BLOB session_key,
+                                           const struct iovec *recv_iov);
+
 #endif /* _SMBXCLI_BASE_H_ */