s3:smbd: use new simplified snb_signing code in the server
authorStefan Metzmacher <metze@samba.org>
Mon, 9 Mar 2009 08:47:59 +0000 (09:47 +0100)
committerStefan Metzmacher <metze@samba.org>
Mon, 23 Mar 2009 11:21:13 +0000 (12:21 +0100)
We keep the seqnum/mid mapping in the smb_request structure.

This also moves one global variable into the
smbd_server_connection struct.

metze

22 files changed:
source3/Makefile.in
source3/include/proto.h
source3/include/smb.h
source3/libsmb/clisigning.c
source3/param/loadparm.c
source3/smbd/aio.c
source3/smbd/blocking.c
source3/smbd/globals.h
source3/smbd/ipc.c
source3/smbd/negprot.c
source3/smbd/notify.c
source3/smbd/nttrans.c
source3/smbd/open.c
source3/smbd/oplock.c
source3/smbd/password.c
source3/smbd/pipes.c
source3/smbd/process.c
source3/smbd/reply.c
source3/smbd/service.c
source3/smbd/sesssetup.c
source3/smbd/signing.c [new file with mode: 0644]
source3/smbd/trans2.c

index 8dbb7b5d67c4186c089c35ab99c0ccd0f005b930..46216c7f08577d3369f98c8aed7140b852f2a5d6 100644 (file)
@@ -733,7 +733,7 @@ SMBD_OBJ_SRV = smbd/files.o smbd/chgpasswd.o smbd/connection.o \
               smbd/change_trust_pw.o smbd/fake_file.o \
               smbd/quotas.o smbd/ntquotas.o $(AFS_OBJ) smbd/msdfs.o \
               $(AFS_SETTOKEN_OBJ) smbd/aio.o smbd/statvfs.o \
-              smbd/dmapi.o \
+              smbd/dmapi.o smbd/signing.o \
               smbd/file_access.o \
               smbd/dnsregister.o smbd/globals.o \
               $(MANGLE_OBJ) @VFS_STATIC@
index 1ed623c4cb2f18e8131bffd27147afcfbbd0930a..356eb4935fdd6c48c47a57b5a6a03377aae1bf3b 100644 (file)
@@ -3194,16 +3194,22 @@ bool cli_check_sign_mac(struct cli_state *cli, char *buf);
 bool client_set_trans_sign_state_on(struct cli_state *cli, uint16 mid);
 bool client_set_trans_sign_state_off(struct cli_state *cli, uint16 mid);
 bool client_is_signing_on(struct cli_state *cli);
-bool srv_oplock_set_signing(bool onoff);
-bool srv_check_sign_mac(const char *inbuf, bool must_be_ok);
-void srv_calculate_sign_mac(char *outbuf);
-void srv_defer_sign_response(uint16 mid);
-void srv_cancel_sign_response(uint16 mid, bool cancel);
-void srv_set_signing_negotiated(void);
-bool srv_is_signing_active(void);
-bool srv_is_signing_negotiated(void);
-bool srv_signing_started(void);
-void srv_set_signing(const DATA_BLOB user_session_key, const DATA_BLOB response);
+
+/* The following definitions come from smbd/signing.c  */
+
+struct smbd_server_connection;
+bool srv_check_sign_mac(struct smbd_server_connection *conn,
+                       const char *inbuf, uint32_t *seqnum);
+void srv_calculate_sign_mac(struct smbd_server_connection *conn,
+                           char *outbuf, uint32_t seqnum);
+void srv_cancel_sign_response(struct smbd_server_connection *conn);
+bool srv_init_signing(struct smbd_server_connection *conn);
+void srv_set_signing_negotiated(struct smbd_server_connection *conn);
+bool srv_is_signing_active(struct smbd_server_connection *conn);
+bool srv_is_signing_negotiated(struct smbd_server_connection *conn);
+void srv_set_signing(struct smbd_server_connection *conn,
+                    const DATA_BLOB user_session_key,
+                    const DATA_BLOB response);
 
 /* The following definitions come from libsmb/smbdes.c  */
 
@@ -4347,7 +4353,7 @@ const char *lp_printcapname(void);
 bool lp_disable_spoolss( void );
 void lp_set_spoolss_state( uint32 state );
 uint32 lp_get_spoolss_state( void );
-bool lp_use_sendfile(int snum);
+bool lp_use_sendfile(int snum, struct smb_signing_state *signing_state);
 void set_use_sendfile(int snum, bool val);
 void set_store_dos_attributes(int snum, bool val);
 void lp_set_mangling_method(const char *new_method);
@@ -6722,7 +6728,9 @@ SEC_DESC *get_nt_acl_no_snum( TALLOC_CTX *ctx, const char *fname);
 
 void smbd_setup_sig_term_handler(void);
 void smbd_setup_sig_hup_handler(void);
-bool srv_send_smb(int fd, char *buffer, bool do_encrypt,
+bool srv_send_smb(int fd, char *buffer,
+                 bool no_signing, uint32_t seqnum,
+                 bool do_encrypt,
                  struct smb_perfcount_data *pcd);
 int srv_set_message(char *buf,
                         int num_words,
index 281a218256f5d83fa1089cff2a0297e4b7dddd99..215adba1b4a1861ae0d56231f7f352d47a23e5bd 100644 (file)
@@ -621,6 +621,7 @@ struct smb_request {
        uint16 flags2;
        uint16 smbpid;
        uint16 mid;
+       uint32_t seqnum;
        uint16 vuid;
        uint16 tid;
        uint8  wct;
@@ -722,6 +723,7 @@ struct pending_message_list {
        struct timeval request_time; /* When was this first issued? */
        struct timed_event *te;
        struct smb_perfcount_data pcd;
+       uint32_t seqnum;
        bool encrypted;
        DATA_BLOB buf;
        DATA_BLOB private_data;
index a3ed0e75729523619d259c6990b3545a37433b0b..6644bc0d6005aac121e62cef656b4b9059609a51 100644 (file)
@@ -671,336 +671,3 @@ bool client_is_signing_on(struct cli_state *cli)
        struct smb_sign_info *si = &cli->sign_info;
        return si->doing_signing;
 }
-
-/***********************************************************
- SMB signing - Server implementation - send the MAC.
-************************************************************/
-
-static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si)
-{
-       unsigned char calc_md5_mac[16];
-       struct smb_basic_signing_context *data =
-               (struct smb_basic_signing_context *)si->signing_context;
-       uint32 send_seq_number = data->send_seq_num-1;
-       uint16 mid;
-
-       if (!si->doing_signing) {
-               return;
-       }
-
-       /* JRA Paranioa test - we should be able to get rid of this... */
-       if (smb_len(outbuf) < (smb_ss_field + 8 - 4)) {
-               DEBUG(1, ("srv_sign_outgoing_message: Logic error. Can't send signature on short packet! smb_len = %u\n",
-                                       smb_len(outbuf) ));
-               abort();
-       }
-
-       /* mark the packet as signed - BEFORE we sign it...*/
-       mark_packet_signed(outbuf);
-
-       mid = SVAL(outbuf, smb_mid);
-
-       /* See if this is a reply for a deferred packet. */
-       get_sequence_for_reply(&data->outstanding_packet_list, mid, &send_seq_number);
-
-       simple_packet_signature(data, (const unsigned char *)outbuf, send_seq_number, calc_md5_mac);
-
-       DEBUG(10, ("srv_sign_outgoing_message: seq %u: sent SMB signature of\n", (unsigned int)send_seq_number));
-       dump_data(10, calc_md5_mac, 8);
-
-       memcpy(&outbuf[smb_ss_field], calc_md5_mac, 8);
-
-/*     cli->outbuf[smb_ss_field+2]=0; 
-       Uncomment this to test if the remote client actually verifies signatures...*/
-}
-
-/***********************************************************
- SMB signing - Server implementation - check a MAC sent by server.
-************************************************************/
-
-static bool srv_check_incoming_message(const char *inbuf,
-                                      struct smb_sign_info *si,
-                                      bool must_be_ok)
-{
-       bool good;
-       struct smb_basic_signing_context *data =
-               (struct smb_basic_signing_context *)si->signing_context;
-       uint32 reply_seq_number = data->send_seq_num;
-       uint32 saved_seq;
-       unsigned char calc_md5_mac[16];
-       unsigned char *server_sent_mac;
-
-       if (!si->doing_signing)
-               return True;
-
-       if (smb_len(inbuf) < (smb_ss_field + 8 - 4)) {
-               DEBUG(1, ("srv_check_incoming_message: Can't check signature on short packet! smb_len = %u\n", smb_len(inbuf)));
-               return False;
-       }
-
-       /* We always increment the sequence number. */
-       data->send_seq_num += 2;
-
-       saved_seq = reply_seq_number;
-       simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number, calc_md5_mac);
-
-       server_sent_mac = (unsigned char *)&inbuf[smb_ss_field];
-       good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0);
-
-       if (!good) {
-
-               if (saved_seq) {
-                       DEBUG(0, ("srv_check_incoming_message: BAD SIG: seq %u wanted SMB signature of\n",
-                                       (unsigned int)saved_seq));
-                       dump_data(5, calc_md5_mac, 8);
-
-                       DEBUG(0, ("srv_check_incoming_message: BAD SIG: seq %u got SMB signature of\n",
-                                               (unsigned int)reply_seq_number));
-                       dump_data(5, server_sent_mac, 8);
-               }
-
-#if 1 /* JRATEST */
-               {
-                       int i;
-                       reply_seq_number -= 5;
-                       for (i = 0; i < 10; i++, reply_seq_number++) {
-                               simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number, calc_md5_mac);
-                               if (memcmp(server_sent_mac, calc_md5_mac, 8) == 0) {
-                                       DEBUG(0,("srv_check_incoming_message: out of seq. seq num %u matches. \
-We were expecting seq %u\n", reply_seq_number, saved_seq ));
-                                       break;
-                               }
-                       }
-               }
-#endif /* JRATEST */
-
-       } else {
-               DEBUG(10, ("srv_check_incoming_message: seq %u: (current is %u) got good SMB signature of\n", (unsigned int)reply_seq_number, (unsigned int)data->send_seq_num));
-               dump_data(10, server_sent_mac, 8);
-       }
-
-       return (signing_good(inbuf, si, good, saved_seq, must_be_ok));
-}
-
-/***********************************************************
- SMB signing - server API's.
-************************************************************/
-
-static struct smb_sign_info srv_sign_info = {
-       null_sign_outgoing_message,
-       null_check_incoming_message,
-       null_free_signing_context,
-       NULL,
-       False,
-       False,
-       False,
-       False
-};
-
-/***********************************************************
- Turn signing off or on for oplock break code.
-************************************************************/
-
-bool srv_oplock_set_signing(bool onoff)
-{
-       bool ret = srv_sign_info.doing_signing;
-       srv_sign_info.doing_signing = onoff;
-       return ret;
-}
-
-/***********************************************************
- Called to validate an incoming packet from the client.
-************************************************************/
-
-bool srv_check_sign_mac(const char *inbuf, bool must_be_ok)
-{
-       /* Check if it's a non-session message. */
-       if(CVAL(inbuf,0)) {
-               return True;
-       }
-
-       return srv_sign_info.check_incoming_message(inbuf, &srv_sign_info, must_be_ok);
-}
-
-/***********************************************************
- Called to sign an outgoing packet to the client.
-************************************************************/
-
-void srv_calculate_sign_mac(char *outbuf)
-{
-       /* Check if it's a non-session message. */
-       if(CVAL(outbuf,0)) {
-               return;
-       }
-
-       srv_sign_info.sign_outgoing_message(outbuf, &srv_sign_info);
-}
-
-/***********************************************************
- Called by server to defer an outgoing packet.
-************************************************************/
-
-void srv_defer_sign_response(uint16 mid)
-{
-       struct smb_basic_signing_context *data;
-
-       if (!srv_sign_info.doing_signing)
-               return;
-
-       data = (struct smb_basic_signing_context *)srv_sign_info.signing_context;
-
-       if (!data)
-               return;
-
-       /*
-        * Ensure we only store this mid reply once...
-        */
-
-       store_sequence_for_reply(&data->outstanding_packet_list, mid,
-                                data->send_seq_num-1);
-}
-
-/***********************************************************
- Called to remove sequence records when a deferred packet is
- cancelled by mid. This should never find one....
-************************************************************/
-
-void srv_cancel_sign_response(uint16 mid, bool cancel)
-{
-       struct smb_basic_signing_context *data;
-       uint32 dummy_seq;
-
-       if (!srv_sign_info.doing_signing)
-               return;
-
-       data = (struct smb_basic_signing_context *)srv_sign_info.signing_context;
-
-       if (!data)
-               return;
-
-       DEBUG(10,("srv_cancel_sign_response: for mid %u\n", (unsigned int)mid ));
-
-       while (get_sequence_for_reply(&data->outstanding_packet_list, mid, &dummy_seq))
-               ;
-
-       /* cancel doesn't send a reply so doesn't burn a sequence number. */
-       if (cancel) {
-               data->send_seq_num -= 1;
-       }
-}
-
-/***********************************************************
- Called by server negprot when signing has been negotiated.
-************************************************************/
-
-void srv_set_signing_negotiated(void)
-{
-       srv_sign_info.allow_smb_signing = True;
-       srv_sign_info.negotiated_smb_signing = True;
-       if (lp_server_signing() == Required)
-               srv_sign_info.mandatory_signing = True;
-
-       srv_sign_info.sign_outgoing_message = temp_sign_outgoing_message;
-       srv_sign_info.check_incoming_message = temp_check_incoming_message;
-       srv_sign_info.free_signing_context = temp_free_signing_context;
-}
-
-/***********************************************************
- Returns whether signing is active. We can't use sendfile or raw
- reads/writes if it is.
-************************************************************/
-
-bool srv_is_signing_active(void)
-{
-       return srv_sign_info.doing_signing;
-}
-
-
-/***********************************************************
- Returns whether signing is negotiated. We can't use it unless it was
- in the negprot.  
-************************************************************/
-
-bool srv_is_signing_negotiated(void)
-{
-       return srv_sign_info.negotiated_smb_signing;
-}
-
-/***********************************************************
- Returns whether signing is actually happening
-************************************************************/
-
-bool srv_signing_started(void)
-{
-       struct smb_basic_signing_context *data;
-
-       if (!srv_sign_info.doing_signing) {
-               return False;
-       }
-
-       data = (struct smb_basic_signing_context *)srv_sign_info.signing_context;
-       if (!data)
-               return False;
-
-       if (data->send_seq_num == 0) {
-               return False;
-       }
-
-       return True;
-}
-
-/***********************************************************
- Turn on signing from this packet onwards. 
-************************************************************/
-
-void srv_set_signing(const DATA_BLOB user_session_key, const DATA_BLOB response)
-{
-       struct smb_basic_signing_context *data;
-
-       if (!user_session_key.length)
-               return;
-
-       if (!srv_sign_info.negotiated_smb_signing && !srv_sign_info.mandatory_signing) {
-               DEBUG(5,("srv_set_signing: signing negotiated = %u, mandatory_signing = %u. Not allowing smb signing.\n",
-                       (unsigned int)srv_sign_info.negotiated_smb_signing,
-                       (unsigned int)srv_sign_info.mandatory_signing ));
-               return;
-       }
-
-       /* Once we've turned on, ignore any more sessionsetups. */
-       if (srv_sign_info.doing_signing) {
-               return;
-       }
-
-       if (srv_sign_info.free_signing_context)
-               srv_sign_info.free_signing_context(&srv_sign_info);
-
-       srv_sign_info.doing_signing = True;
-
-       data = SMB_XMALLOC_P(struct smb_basic_signing_context);
-       memset(data, '\0', sizeof(*data));
-
-       srv_sign_info.signing_context = data;
-
-       data->mac_key = data_blob(NULL, response.length + user_session_key.length);
-
-       memcpy(&data->mac_key.data[0], user_session_key.data, user_session_key.length);
-       if (response.length)
-               memcpy(&data->mac_key.data[user_session_key.length],response.data, response.length);
-
-       dump_data_pw("MAC ssession key is:\n", data->mac_key.data, data->mac_key.length);
-
-       DEBUG(3,("srv_set_signing: turning on SMB signing: signing negotiated = %s, mandatory_signing = %s.\n",
-                               BOOLSTR(srv_sign_info.negotiated_smb_signing),
-                               BOOLSTR(srv_sign_info.mandatory_signing) ));
-
-       /* Initialise the sequence number */
-       data->send_seq_num = 0;
-
-       /* Initialise the list of outstanding packets */
-       data->outstanding_packet_list = NULL;
-
-       srv_sign_info.sign_outgoing_message = srv_sign_outgoing_message;
-       srv_sign_info.check_incoming_message = srv_check_incoming_message;
-       srv_sign_info.free_signing_context = simple_free_signing_context;
-}
index f49a1bc4c948311dc507a378628ad48353974496..8460fea56713fd5f6056a002ee3fbb035ec79285 100644 (file)
@@ -9572,15 +9572,20 @@ uint32 lp_get_spoolss_state( void )
  Ensure we don't use sendfile if server smb signing is active.
 ********************************************************************/
 
-bool lp_use_sendfile(int snum)
+bool lp_use_sendfile(int snum, struct smb_signing_state *signing_state)
 {
+       bool sign_active = false;
+
        /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
        if (Protocol < PROTOCOL_NT1) {
-               return False;
+               return false;
+       }
+       if (signing_state) {
+               sign_active = smb_signing_is_active(signing_state);
        }
        return (_lp_use_sendfile(snum) &&
                        (get_remote_arch() != RA_WIN95) &&
-                       !srv_is_signing_active());
+                       !sign_active);
 }
 
 /*******************************************************************
index cfa4b430ebf271aafd654004c541f4bdc766ecc2..77616be48c669ab4a7ab58fda11dae2bdd8cc1bc 100644 (file)
@@ -197,7 +197,6 @@ bool schedule_aio_read_and_X(connection_struct *conn,
                  fsp->fsp_name, (double)startpos, (unsigned int)smb_maxcnt,
                  (unsigned int)aio_ex->req->mid ));
 
-       srv_defer_sign_response(aio_ex->req->mid);
        outstanding_aio_calls++;
        return True;
 }
@@ -303,6 +302,7 @@ bool schedule_aio_write_and_X(connection_struct *conn,
                 SSVAL(aio_ex->outbuf,smb_vwv4,(numtowrite>>16)&1);
                show_msg(aio_ex->outbuf);
                if (!srv_send_smb(smbd_server_fd(),aio_ex->outbuf,
+                               true, aio_ex->req->seqnum+1,
                                IS_CONN_ENCRYPTED(fsp->conn),
                                &req->pcd)) {
                        exit_server_cleanly("handle_aio_write: srv_send_smb "
@@ -310,8 +310,6 @@ bool schedule_aio_write_and_X(connection_struct *conn,
                }
                DEBUG(10,("schedule_aio_write_and_X: scheduled aio_write "
                          "behind for file %s\n", fsp->fsp_name ));
-       } else {
-               srv_defer_sign_response(aio_ex->req->mid);
        }
        outstanding_aio_calls++;
 
@@ -347,7 +345,6 @@ static int handle_aio_read_complete(struct aio_extra *aio_ex)
                /* If errno is ECANCELED then don't return anything to the
                 * client. */
                if (errno == ECANCELED) {
-                       srv_cancel_sign_response(aio_ex->req->mid, false);
                        return 0;
                }
 
@@ -378,6 +375,7 @@ static int handle_aio_read_complete(struct aio_extra *aio_ex)
        smb_setlen(outbuf,outsize - 4);
        show_msg(outbuf);
        if (!srv_send_smb(smbd_server_fd(),outbuf,
+                       true, aio_ex->req->seqnum+1,
                        IS_CONN_ENCRYPTED(aio_ex->fsp->conn), NULL)) {
                exit_server_cleanly("handle_aio_read_complete: srv_send_smb "
                                    "failed.");
@@ -441,7 +439,6 @@ static int handle_aio_write_complete(struct aio_extra *aio_ex)
                /* If errno is ECANCELED then don't return anything to the
                 * client. */
                if (errno == ECANCELED) {
-                       srv_cancel_sign_response(aio_ex->req->mid, false);
                        return 0;
                }
 
@@ -475,7 +472,9 @@ static int handle_aio_write_complete(struct aio_extra *aio_ex)
        }
 
        show_msg(outbuf);
-       if (!srv_send_smb(smbd_server_fd(),outbuf,IS_CONN_ENCRYPTED(fsp->conn),
+       if (!srv_send_smb(smbd_server_fd(),outbuf,
+                         true, aio_ex->req->seqnum+1,
+                         IS_CONN_ENCRYPTED(fsp->conn),
                          NULL)) {
                exit_server_cleanly("handle_aio_write: srv_send_smb failed.");
        }
@@ -534,7 +533,6 @@ void smbd_aio_complete_mid(unsigned int mid)
        if (!aio_ex) {
                DEBUG(3,("smbd_aio_complete_mid: Can't find record to "
                         "match mid %u.\n", mid));
-               srv_cancel_sign_response(mid, false);
                return;
        }
 
@@ -544,7 +542,6 @@ void smbd_aio_complete_mid(unsigned int mid)
                 * ignore. */
                DEBUG( 3,( "smbd_aio_complete_mid: file closed whilst "
                           "aio outstanding (mid[%u]).\n", mid));
-               srv_cancel_sign_response(mid, false);
                return;
        }
 
index 42849931f3ab5dd4b65de58a8964cd44b27aca5d..4c61428692dc48d45ca76600d2e5cddd140f73b8 100644 (file)
@@ -204,9 +204,6 @@ bool push_blocking_lock_request( struct byte_range_lock *br_lck,
                (unsigned int)blr->expire_time.tv_usec, lock_timeout,
                blr->fsp->fnum, blr->fsp->fsp_name ));
 
-       /* Push the MID of this packet on the signing queue. */
-       srv_defer_sign_response(blr->req->mid);
-
        return True;
 }
 
@@ -260,6 +257,7 @@ static void generic_blocking_lock_error(struct blocking_lock_record *blr, NTSTAT
 
        reply_nterror(blr->req, status);
        if (!srv_send_smb(smbd_server_fd(), (char *)blr->req->outbuf,
+                         true, blr->req->seqnum+1,
                          blr->req->encrypted, NULL)) {
                exit_server_cleanly("generic_blocking_lock_error: srv_send_smb failed.");
        }
@@ -343,6 +341,7 @@ static void blocking_lock_reply_error(struct blocking_lock_record *blr, NTSTATUS
 
                if (!srv_send_smb(smbd_server_fd(),
                                  (char *)blr->req->outbuf,
+                                 true, blr->req->seqnum+1,
                                  IS_CONN_ENCRYPTED(blr->fsp->conn),
                                  NULL)) {
                        exit_server_cleanly("blocking_lock_reply_error: "
index 6ac92ed3ddbf82c2413149dfca5bc9f88c84ef98..b646bc30fda3be8d878bb6afd39101e2aaf90ae0 100644 (file)
@@ -202,6 +202,7 @@ extern int num_children;
 struct smbd_server_connection {
        struct fd_event *fde;
        uint64_t num_requests;
+       struct smb_signing_state *signing_state;
 };
 extern struct smbd_server_connection *smbd_server_conn;
 
index f20c8512975c573c6987896ce42fb36630aba271..d39aab4f471ab66938da3aa1c7c3c0acf78a1187 100644 (file)
@@ -134,6 +134,7 @@ void send_trans_reply(connection_struct *conn,
 
        show_msg((char *)req->outbuf);
        if (!srv_send_smb(smbd_server_fd(), (char *)req->outbuf,
+                         true, req->seqnum+1,
                          IS_CONN_ENCRYPTED(conn), &req->pcd)) {
                exit_server_cleanly("send_trans_reply: srv_send_smb failed.");
        }
@@ -190,6 +191,7 @@ void send_trans_reply(connection_struct *conn,
 
                show_msg((char *)req->outbuf);
                if (!srv_send_smb(smbd_server_fd(), (char *)req->outbuf,
+                                 true, req->seqnum+1,
                                  IS_CONN_ENCRYPTED(conn), &req->pcd))
                        exit_server_cleanly("send_trans_reply: srv_send_smb "
                                            "failed.");
@@ -296,6 +298,7 @@ static void api_dcerpc_cmd_write_done(struct tevent_req *subreq)
  send:
        if (!srv_send_smb(
                    smbd_server_fd(), (char *)req->outbuf,
+                   true, req->seqnum+1,
                    IS_CONN_ENCRYPTED(req->conn) || req->encrypted,
                    &req->pcd)) {
                exit_server_cleanly("construct_reply: srv_send_smb failed.");
@@ -322,6 +325,7 @@ static void api_dcerpc_cmd_read_done(struct tevent_req *subreq)
                reply_nterror(req, status);
 
                if (!srv_send_smb(smbd_server_fd(), (char *)req->outbuf,
+                                 true, req->seqnum+1,
                                  IS_CONN_ENCRYPTED(req->conn)
                                  ||req->encrypted, &req->pcd)) {
                        exit_server_cleanly("construct_reply: srv_send_smb "
index a921954c49c4f162645b79991d6845a844bbb007..e548c587c15e7df326e9e22a4a4d678450dbaae2 100644 (file)
@@ -316,7 +316,7 @@ static void reply_nt1(struct smb_request *req, uint16 choice)
                        capabilities &= ~CAP_RAW_MODE;
                        if (lp_server_signing() == Required)
                                secword |=NEGOTIATE_SECURITY_SIGNATURES_REQUIRED;
-                       srv_set_signing_negotiated();
+                       srv_set_signing_negotiated(smbd_server_conn);
                } else {
                        DEBUG(0,("reply_nt1: smb signing is incompatible with share level security !\n"));
                        if (lp_server_signing() == Required) {
index 8ceeaf5f5588ae4e5d5c091a3379ce944c00bc88..fdab2ca848537b6fc38a6fcb5ea364f1810fc22f 100644 (file)
@@ -143,7 +143,9 @@ static void change_notify_reply_packet(connection_struct *conn,
        }
 
        show_msg((char *)req->outbuf);
-       if (!srv_send_smb(smbd_server_fd(), (char *)req->outbuf,
+       if (!srv_send_smb(smbd_server_fd(),
+                         (char *)req->outbuf,
+                         true, req->seqnum+1,
                          req->encrypted, &req->pcd)) {
                exit_server_cleanly("change_notify_reply_packet: srv_send_smb "
                                    "failed.");
@@ -260,9 +262,6 @@ NTSTATUS change_notify_add_request(struct smb_request *req,
        map->mid = request->req->mid;
        DLIST_ADD(notify_changes_by_mid, map);
 
-       /* Push the MID of this packet on the signing queue. */
-       srv_defer_sign_response(request->req->mid);
-
        return NT_STATUS_OK;
 }
 
index 9c7fb1914e8716c6f27b90d1f2dd1878871fea26..628fc1bd32bc0da07b6ddf036909603e29c4ecf6 100644 (file)
@@ -230,6 +230,7 @@ void send_nt_replies(connection_struct *conn,
                show_msg((char *)req->outbuf);
                if (!srv_send_smb(smbd_server_fd(),
                                (char *)req->outbuf,
+                               true, req->seqnum+1,
                                IS_CONN_ENCRYPTED(conn),
                                &req->pcd)) {
                        exit_server_cleanly("send_nt_replies: srv_send_smb failed.");
@@ -1129,9 +1130,9 @@ void reply_ntcancel(struct smb_request *req)
         */
 
        START_PROFILE(SMBntcancel);
+       srv_cancel_sign_response(smbd_server_conn);
        remove_pending_change_notify_requests_by_mid(req->mid);
        remove_pending_lock_requests_by_mid(req->mid);
-       srv_cancel_sign_response(req->mid, true);
 
        DEBUG(3,("reply_ntcancel: cancel called on mid = %d.\n", req->mid));
 
index d529b009d5086484c5a3727c19412fba4651ca8f..52df4fa1431bc91436e9c0e005afb9f8164976e8 100644 (file)
@@ -1033,15 +1033,6 @@ static void defer_open(struct share_mode_lock *lck,
                exit_server("push_deferred_smb_message failed");
        }
        add_deferred_open(lck, req->mid, request_time, state->id);
-
-       /*
-        * Push the MID of this packet on the signing queue.
-        * We only do this once, the first time we push the packet
-        * onto the deferred open queue, as this has a side effect
-        * of incrementing the response sequence number.
-        */
-
-       srv_defer_sign_response(req->mid);
 }
 
 
index 22870283fa5996d2e519096ca8ba319d7ea7f144..ce00397bbde6f61d5fcfb9430210bc89be80db7b 100644 (file)
@@ -361,7 +361,6 @@ void process_oplock_async_level2_break_message(struct messaging_context *msg_ctx
        struct share_mode_entry msg;
        files_struct *fsp;
        char *break_msg;
-       bool sign_state;
 
        if (data->data == NULL) {
                DEBUG(0, ("Got NULL buffer\n"));
@@ -423,20 +422,14 @@ void process_oplock_async_level2_break_message(struct messaging_context *msg_ctx
                wait_before_sending_break();
        }
 
-       /* Save the server smb signing state. */
-       sign_state = srv_oplock_set_signing(False);
-
        show_msg(break_msg);
        if (!srv_send_smb(smbd_server_fd(),
-                       break_msg,
+                       break_msg, false, 0,
                        IS_CONN_ENCRYPTED(fsp->conn),
                        NULL)) {
                exit_server_cleanly("oplock_break: srv_send_smb failed.");
        }
 
-       /* Restore the sign state to what it was. */
-       srv_oplock_set_signing(sign_state);
-
        TALLOC_FREE(break_msg);
 
        /* Async level2 request, don't send a reply, just remove the oplock. */
@@ -457,7 +450,6 @@ static void process_oplock_break_message(struct messaging_context *msg_ctx,
        files_struct *fsp;
        char *break_msg;
        bool break_to_level2 = False;
-       bool sign_state;
 
        if (data->data == NULL) {
                DEBUG(0, ("Got NULL buffer\n"));
@@ -530,20 +522,14 @@ static void process_oplock_break_message(struct messaging_context *msg_ctx,
                wait_before_sending_break();
        }
 
-       /* Save the server smb signing state. */
-       sign_state = srv_oplock_set_signing(False);
-
        show_msg(break_msg);
        if (!srv_send_smb(smbd_server_fd(),
-                       break_msg,
+                       break_msg, false, 0,
                        IS_CONN_ENCRYPTED(fsp->conn),
                        NULL)) {
                exit_server_cleanly("oplock_break: srv_send_smb failed.");
        }
 
-       /* Restore the sign state to what it was. */
-       srv_oplock_set_signing(sign_state);
-
        TALLOC_FREE(break_msg);
 
        fsp->sent_oplock_break = break_to_level2 ? LEVEL_II_BREAK_SENT:BREAK_TO_NONE_SENT;
@@ -570,7 +556,6 @@ static void process_kernel_oplock_break(struct messaging_context *msg_ctx,
        unsigned long file_id;
        files_struct *fsp;
        char *break_msg;
-       bool sign_state;
 
        if (data->data == NULL) {
                DEBUG(0, ("Got NULL buffer\n"));
@@ -610,20 +595,14 @@ static void process_kernel_oplock_break(struct messaging_context *msg_ctx,
                exit_server("Could not talloc break_msg\n");
        }
 
-       /* Save the server smb signing state. */
-       sign_state = srv_oplock_set_signing(False);
-
        show_msg(break_msg);
        if (!srv_send_smb(smbd_server_fd(),
-                       break_msg,
+                       break_msg, false, 0,
                        IS_CONN_ENCRYPTED(fsp->conn),
                        NULL)) {
                exit_server_cleanly("oplock_break: srv_send_smb failed.");
        }
 
-       /* Restore the sign state to what it was. */
-       srv_oplock_set_signing(sign_state);
-
        TALLOC_FREE(break_msg);
 
        fsp->sent_oplock_break = BREAK_TO_NONE_SENT;
index 15d120a79c4fba298d926679faa8d71adc4011cb..076965e783c472a4dc9058e74b74f2fe3933eb50 100644 (file)
@@ -298,11 +298,13 @@ int register_existing_vuid(uint16 vuid,
                        vuser->server_info->unix_name);
        }
 
-       if (srv_is_signing_negotiated() && !vuser->server_info->guest &&
-                       !srv_signing_started()) {
+       if (srv_is_signing_negotiated(smbd_server_conn) &&
+           !vuser->server_info->guest) {
                /* Try and turn on server signing on the first non-guest
                 * sessionsetup. */
-               srv_set_signing(vuser->server_info->user_session_key, response_blob);
+               srv_set_signing(smbd_server_conn,
+                               vuser->server_info->user_session_key,
+                               response_blob);
        }
 
        /* fill in the current_user_info struct */
index 2686cf41d93a30137e44c260270a49f66bf323bd..7ae74356462217a1b3baecf0486280f5eda18c38 100644 (file)
@@ -216,6 +216,7 @@ static void pipe_write_done(struct tevent_req *subreq)
 
  send:
        if (!srv_send_smb(smbd_server_fd(), (char *)req->outbuf,
+                         true, req->seqnum+1,
                          IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
                          &req->pcd)) {
                exit_server_cleanly("construct_reply: srv_send_smb failed.");
index 6d53bbe929e6054e4dd5a8aefeb40a9608ad4c92..65778ab0fc21c67b18970f40a1dac838a327904f 100644 (file)
@@ -32,16 +32,20 @@ static void construct_reply_common(struct smb_request *req, const char *inbuf,
  Send an smb to a fd.
 ****************************************************************************/
 
-bool srv_send_smb(int fd, char *buffer, bool do_encrypt,
-                 struct smb_perfcount_data *pcd)
+bool srv_send_smb(int fd, char *buffer,
+                 bool do_signing, uint32_t seqnum,
+                 bool do_encrypt,
+                 struct smb_perfcount_data *pcd)
 {
        size_t len = 0;
        size_t nwritten=0;
        ssize_t ret;
        char *buf_out = buffer;
 
-       /* Sign the outgoing packet if required. */
-       srv_calculate_sign_mac(buf_out);
+       if (do_signing) {
+               /* Sign the outgoing packet if required. */
+               srv_calculate_sign_mac(smbd_server_conn, buf_out, seqnum);
+       }
 
        if (do_encrypt) {
                NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out);
@@ -275,7 +279,7 @@ static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx, int fd,
        if (CVAL(lenbuf,0) == 0 && min_recv_size &&
            (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
                (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
-           !srv_is_signing_active()) {
+           !srv_is_signing_active(smbd_server_conn)) {
 
                return receive_smb_raw_talloc_partial_read(
                        mem_ctx, lenbuf, fd, buffer, timeout, p_unread, plen);
@@ -311,7 +315,8 @@ static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx, int fd,
 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,        int fd,
                                   char **buffer, unsigned int timeout,
                                   size_t *p_unread, bool *p_encrypted,
-                                  size_t *p_len)
+                                  size_t *p_len,
+                                  uint32_t *seqnum)
 {
        size_t len = 0;
        NTSTATUS status;
@@ -336,7 +341,7 @@ static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,     int fd,
        }
 
        /* Check the incoming SMB signature. */
-       if (!srv_check_sign_mac(*buffer, true)) {
+       if (!srv_check_sign_mac(smbd_server_conn, *buffer, seqnum)) {
                DEBUG(0, ("receive_smb: SMB Signature verification failed on "
                          "incoming packet!\n"));
                return NT_STATUS_INVALID_NETWORK_RESPONSE;
@@ -366,6 +371,7 @@ void init_smb_request(struct smb_request *req,
        req->flags2 = SVAL(inbuf, smb_flg2);
        req->smbpid = SVAL(inbuf, smb_pid);
        req->mid    = SVAL(inbuf, smb_mid);
+       req->seqnum = 0;
        req->vuid   = SVAL(inbuf, smb_uid);
        req->tid    = SVAL(inbuf, smb_tid);
        req->wct    = CVAL(inbuf, smb_wct);
@@ -401,7 +407,8 @@ void init_smb_request(struct smb_request *req,
 
 static void process_smb(struct smbd_server_connection *conn,
                        uint8_t *inbuf, size_t nread, size_t unread_bytes,
-                       bool encrypted, struct smb_perfcount_data *deferred_pcd);
+                       uint32_t seqnum, bool encrypted,
+                       struct smb_perfcount_data *deferred_pcd);
 
 static void smbd_deferred_open_timer(struct event_context *ev,
                                     struct timed_event *te,
@@ -427,7 +434,7 @@ static void smbd_deferred_open_timer(struct event_context *ev,
 
        process_smb(smbd_server_conn, inbuf,
                    msg->buf.length, 0,
-                   msg->encrypted, &msg->pcd);
+                   msg->seqnum, msg->encrypted, &msg->pcd);
 }
 
 /****************************************************************************
@@ -458,6 +465,7 @@ static bool push_queued_message(struct smb_request *req,
        }
 
        msg->request_time = request_time;
+       msg->seqnum = req->seqnum;
        msg->encrypted = req->encrypted;
        SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
 
@@ -1362,7 +1370,7 @@ static connection_struct *switch_message(uint8 type, struct smb_request *req, in
 ****************************************************************************/
 
 static void construct_reply(char *inbuf, int size, size_t unread_bytes,
-                           bool encrypted,
+                           uint32_t seqnum, bool encrypted,
                            struct smb_perfcount_data *deferred_pcd)
 {
        connection_struct *conn;
@@ -1374,6 +1382,7 @@ static void construct_reply(char *inbuf, int size, size_t unread_bytes,
 
        init_smb_request(req, (uint8 *)inbuf, unread_bytes, encrypted);
        req->inbuf  = (uint8_t *)talloc_move(req, &inbuf);
+       req->seqnum = seqnum;
 
        /* we popped this message off the queue - keep original perf data */
        if (deferred_pcd)
@@ -1405,6 +1414,7 @@ static void construct_reply(char *inbuf, int size, size_t unread_bytes,
 
        if (!srv_send_smb(smbd_server_fd(),
                        (char *)req->outbuf,
+                       true, req->seqnum+1,
                        IS_CONN_ENCRYPTED(conn)||req->encrypted,
                        &req->pcd)) {
                exit_server_cleanly("construct_reply: srv_send_smb failed.");
@@ -1420,7 +1430,8 @@ static void construct_reply(char *inbuf, int size, size_t unread_bytes,
 ****************************************************************************/
 static void process_smb(struct smbd_server_connection *conn,
                        uint8_t *inbuf, size_t nread, size_t unread_bytes,
-                       bool encrypted, struct smb_perfcount_data *deferred_pcd)
+                       uint32_t seqnum, bool encrypted,
+                       struct smb_perfcount_data *deferred_pcd)
 {
        int msg_type = CVAL(inbuf,0);
 
@@ -1442,7 +1453,7 @@ static void process_smb(struct smbd_server_connection *conn,
 
        show_msg((char *)inbuf);
 
-       construct_reply((char *)inbuf,nread,unread_bytes,encrypted,deferred_pcd);
+       construct_reply((char *)inbuf,nread,unread_bytes,seqnum,encrypted,deferred_pcd);
        trans_num++;
 
 done:
@@ -1637,6 +1648,7 @@ void chain_reply(struct smb_request *req)
                           talloc_get_size(req->chain_outbuf) - 4);
 
                if (!srv_send_smb(smbd_server_fd(), (char *)req->chain_outbuf,
+                                 true, req->seqnum+1,
                                  IS_CONN_ENCRYPTED(req->conn)
                                  ||req->encrypted,
                                  &req->pcd)) {
@@ -1761,6 +1773,7 @@ void chain_reply(struct smb_request *req)
        show_msg((char *)(req->chain_outbuf));
 
        if (!srv_send_smb(smbd_server_fd(), (char *)req->chain_outbuf,
+                         true, req->seqnum+1,
                          IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
                          &req->pcd)) {
                exit_server_cleanly("construct_reply: srv_send_smb failed.");
@@ -1830,6 +1843,7 @@ static void smbd_server_connection_read_handler(struct smbd_server_connection *c
        bool encrypted = false;
        TALLOC_CTX *mem_ctx = talloc_tos();
        NTSTATUS status;
+       uint32_t seqnum;
 
        /* TODO: make this completely nonblocking */
 
@@ -1838,7 +1852,7 @@ static void smbd_server_connection_read_handler(struct smbd_server_connection *c
                                    0, /* timeout */
                                    &unread_bytes,
                                    &encrypted,
-                                   &inbuf_len);
+                                   &inbuf_len, &seqnum);
        if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
                goto process;
        }
@@ -1850,7 +1864,8 @@ static void smbd_server_connection_read_handler(struct smbd_server_connection *c
        }
 
 process:
-       process_smb(conn, inbuf, inbuf_len, unread_bytes, encrypted, NULL);
+       process_smb(conn, inbuf, inbuf_len, unread_bytes,
+                   seqnum, encrypted, NULL);
 }
 
 static void smbd_server_connection_handler(struct event_context *ev,
@@ -2015,7 +2030,8 @@ void smbd_process(void)
                unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
                DEBUG( 1, ("Connection denied from %s\n",
                           client_addr(get_client_fd(),addr,sizeof(addr)) ) );
-               (void)srv_send_smb(smbd_server_fd(),(char *)buf,false, NULL);
+               (void)srv_send_smb(smbd_server_fd(),(char *)buf, false,
+                                  0, false, NULL);
                exit_server_cleanly("connection denied");
        }
 
@@ -2041,6 +2057,10 @@ void smbd_process(void)
                DEBUG(0,("Changed root to %s\n", lp_rootdir()));
        }
 
+       if (!srv_init_signing(smbd_server_conn)) {
+               exit_server("Failed to init smb_signing");
+       }
+
        /* Setup oplocks */
        if (!init_oplocks(smbd_messaging_context()))
                exit_server("Failed to init oplocks");
index 8b560bd8ca64b87dd098e3bc1b274cfd19859fb6..6f19a58178bafe4eefe4a898b13c89c46e974c6a 100644 (file)
@@ -497,7 +497,7 @@ void reply_special(char *inbuf)
        DEBUG(5,("init msg_type=0x%x msg_flags=0x%x\n",
                    msg_type, msg_flags));
 
-       srv_send_smb(smbd_server_fd(), outbuf, false, NULL);
+       srv_send_smb(smbd_server_fd(), outbuf, false, 0, false, NULL);
        return;
 }
 
@@ -2766,7 +2766,8 @@ static void send_file_readbraw(connection_struct *conn,
         */
 
        if ( !req_is_in_chain(req) && (nread > 0) && (fsp->base_fsp == NULL) &&
-           (fsp->wcp == NULL) && lp_use_sendfile(SNUM(conn)) ) {
+           (fsp->wcp == NULL) &&
+           lp_use_sendfile(SNUM(conn), smbd_server_conn->signing_state) ) {
                ssize_t sendfile_read = -1;
                char header[4];
                DATA_BLOB header_blob;
@@ -2870,7 +2871,8 @@ void reply_readbraw(struct smb_request *req)
 
        START_PROFILE(SMBreadbraw);
 
-       if (srv_is_signing_active() || is_encrypted_packet(req->inbuf)) {
+       if (srv_is_signing_active(smbd_server_conn) ||
+           is_encrypted_packet(req->inbuf)) {
                exit_server_cleanly("reply_readbraw: SMB signing/sealing is active - "
                        "raw reads/writes are disallowed.");
        }
@@ -3274,7 +3276,8 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req,
 
        if (!req_is_in_chain(req) &&
            !is_encrypted_packet(req->inbuf) && (fsp->base_fsp == NULL) &&
-           lp_use_sendfile(SNUM(conn)) && (fsp->wcp == NULL) ) {
+           (fsp->wcp == NULL) &&
+           lp_use_sendfile(SNUM(conn), smbd_server_conn->signing_state) ) {
                uint8 headerbuf[smb_size + 12 * 2];
                DATA_BLOB header;
 
@@ -3450,7 +3453,8 @@ void reply_read_and_X(struct smb_request *req)
                                return;
                        }
                        /* We currently don't do this on signed or sealed data. */
-                       if (srv_is_signing_active() || is_encrypted_packet(req->inbuf)) {
+                       if (srv_is_signing_active(smbd_server_conn) ||
+                           is_encrypted_packet(req->inbuf)) {
                                reply_nterror(req, NT_STATUS_NOT_SUPPORTED);
                                END_PROFILE(SMBreadX);
                                return;
@@ -3558,7 +3562,7 @@ void reply_writebraw(struct smb_request *req)
         */
        SCVAL(req->inbuf,smb_com,SMBwritec);
 
-       if (srv_is_signing_active()) {
+       if (srv_is_signing_active(smbd_server_conn)) {
                END_PROFILE(SMBwritebraw);
                exit_server_cleanly("reply_writebraw: SMB signing is active - "
                                "raw reads/writes are disallowed.");
@@ -3653,9 +3657,10 @@ void reply_writebraw(struct smb_request *req)
        SSVALS(buf,smb_vwv0,0xFFFF);
        show_msg(buf);
        if (!srv_send_smb(smbd_server_fd(),
-                       buf,
-                       IS_CONN_ENCRYPTED(conn),
-                       &req->pcd)) {
+                         buf,
+                         false, 0, /* no signing */
+                         IS_CONN_ENCRYPTED(conn),
+                         &req->pcd)) {
                exit_server_cleanly("reply_writebraw: srv_send_smb "
                        "failed.");
        }
@@ -4757,6 +4762,7 @@ void reply_echo(struct smb_request *req)
                show_msg((char *)req->outbuf);
                if (!srv_send_smb(smbd_server_fd(),
                                (char *)req->outbuf,
+                               true, req->seqnum+1,
                                IS_CONN_ENCRYPTED(conn)||req->encrypted,
                                cur_pcd))
                        exit_server_cleanly("reply_echo: srv_send_smb failed.");
index eb16a2601e312e76d90e63f3401fe781cf42c356..e33f04d971bfee5c8ab498a58e7dbce46b19db53 100644 (file)
@@ -1110,7 +1110,7 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
        if( DEBUGLVL( IS_IPC(conn) ? 3 : 1 ) ) {
                dbgtext( "%s (%s) ", get_remote_machine_name(),
                         conn->client_address );
-               dbgtext( "%s", srv_is_signing_active() ? "signed " : "");
+               dbgtext( "%s", srv_is_signing_active(smbd_server_conn) ? "signed " : "");
                dbgtext( "connect to service %s ", lp_servicename(snum) );
                dbgtext( "initially as user %s ",
                         conn->server_info->unix_name );
index 2c29192220b1958d0c47ae1eb51faac6bfb0d147..e8878a29ab32f9a18c2b2c77835a7f4e32820cae 100644 (file)
@@ -90,25 +90,6 @@ static int push_signature(uint8 **outbuf)
        return result;
 }
 
-/****************************************************************************
- Start the signing engine if needed. Don't fail signing here.
-****************************************************************************/
-
-static void sessionsetup_start_signing_engine(
-                       const auth_serversupplied_info *server_info,
-                       const uint8 *inbuf)
-{
-       if (!server_info->guest && !srv_signing_started()) {
-               /* We need to start the signing engine
-                * here but a W2K client sends the old
-                * "BSRSPYL " signature instead of the
-                * correct one. Subsequent packets will
-                * be correct.
-                */
-               srv_check_sign_mac((char *)inbuf, False);
-       }
-}
-
 /****************************************************************************
  Send a security blob via a session setup reply.
 ****************************************************************************/
@@ -579,7 +560,6 @@ static void reply_spnego_kerberos(struct smb_request *req,
 
                SSVAL(req->outbuf, smb_uid, sess_vuid);
 
-               sessionsetup_start_signing_engine(server_info, req->inbuf);
                /* Successful logon. Keep this vuid. */
                *p_invalidate_vuid = False;
        }
@@ -668,9 +648,6 @@ static void reply_spnego_ntlmssp(struct smb_request *req,
                if (server_info->guest) {
                        SSVAL(req->outbuf,smb_vwv2,1);
                }
-
-               sessionsetup_start_signing_engine(server_info,
-                                                 (uint8 *)req->inbuf);
        }
 
   out:
@@ -1804,8 +1781,6 @@ void reply_sesssetup_and_X(struct smb_request *req)
 
                /* current_user_info is changed on new vuid */
                reload_services( True );
-
-               sessionsetup_start_signing_engine(server_info, req->inbuf);
        }
 
        data_blob_free(&nt_resp);
diff --git a/source3/smbd/signing.c b/source3/smbd/signing.c
new file mode 100644 (file)
index 0000000..b56eb71
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+   Unix SMB/CIFS implementation.
+   SMB Signing Code
+   Copyright (C) Jeremy Allison 2003.
+   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2002-2003
+   Copyright (C) Stefan Metzmacher 2009
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "smbd/globals.h"
+
+
+/***********************************************************
+ Called to validate an incoming packet from the client.
+************************************************************/
+
+bool srv_check_sign_mac(struct smbd_server_connection *conn,
+                       const char *inbuf, uint32_t *seqnum)
+{
+       /* Check if it's a non-session message. */
+       if(CVAL(inbuf,0)) {
+               return true;
+       }
+
+       *seqnum = smb_signing_next_seqnum(conn->signing_state, false);
+       return smb_signing_check_pdu(conn->signing_state,
+                                    (const uint8_t *)inbuf,
+                                    *seqnum);
+}
+
+/***********************************************************
+ Called to sign an outgoing packet to the client.
+************************************************************/
+
+void srv_calculate_sign_mac(struct smbd_server_connection *conn,
+                           char *outbuf, uint32_t seqnum)
+{
+       /* Check if it's a non-session message. */
+       if(CVAL(outbuf,0)) {
+               return;
+       }
+
+       smb_signing_sign_pdu(conn->signing_state, (uint8_t *)outbuf, seqnum);
+}
+
+
+/***********************************************************
+ Called to indicate a oneway request
+************************************************************/
+void srv_cancel_sign_response(struct smbd_server_connection *conn)
+{
+       smb_signing_cancel_reply(conn->signing_state, true);
+}
+
+/***********************************************************
+ Called by server negprot when signing has been negotiated.
+************************************************************/
+
+bool srv_init_signing(struct smbd_server_connection *conn)
+{
+       bool allowed = true;
+       bool mandatory = false;
+
+       switch (lp_server_signing()) {
+       case Required:
+               mandatory = true;
+               break;
+       case Auto:
+               break;
+       case True:
+               break;
+       case False:
+               allowed = false;
+               break;
+       }
+
+       conn->signing_state = smb_signing_init(smbd_event_context(),
+                                              allowed, mandatory);
+       if (!conn->signing_state) {
+               return false;
+       }
+
+       return true;
+}
+
+void srv_set_signing_negotiated(struct smbd_server_connection *conn)
+{
+       smb_signing_set_negotiated(conn->signing_state);
+}
+
+/***********************************************************
+ Returns whether signing is active. We can't use sendfile or raw
+ reads/writes if it is.
+************************************************************/
+
+bool srv_is_signing_active(struct smbd_server_connection *conn)
+{
+       return smb_signing_is_active(conn->signing_state);
+}
+
+
+/***********************************************************
+ Returns whether signing is negotiated. We can't use it unless it was
+ in the negprot.
+************************************************************/
+
+bool srv_is_signing_negotiated(struct smbd_server_connection *conn)
+{
+       return smb_signing_is_negotiated(conn->signing_state);
+}
+
+/***********************************************************
+ Turn on signing from this packet onwards.
+************************************************************/
+
+void srv_set_signing(struct smbd_server_connection *conn,
+                    const DATA_BLOB user_session_key,
+                    const DATA_BLOB response)
+{
+       bool negotiated;
+       bool mandatory;
+
+       if (!user_session_key.length)
+               return;
+
+       negotiated = smb_signing_is_negotiated(conn->signing_state);
+       mandatory = smb_signing_is_mandatory(conn->signing_state);
+
+       if (!negotiated && !mandatory) {
+               DEBUG(5,("srv_set_signing: signing negotiated = %u, "
+                        "mandatory_signing = %u. Not allowing smb signing.\n",
+                        negotiated, mandatory));
+               return;
+       }
+
+       if (!smb_signing_activate(conn->signing_state,
+                                 user_session_key, response)) {
+               return;
+       }
+
+       DEBUG(3,("srv_set_signing: turning on SMB signing: "
+                "signing negotiated = %u, mandatory_signing = %u.\n",
+                negotiated, mandatory));
+}
+
index ee1dda98b22c3ca3d982e60ddc71dadd49921447..df01a398934967ad9989ef9002c0abe20dc01b90 100644 (file)
@@ -832,6 +832,7 @@ void send_trans2_replies(connection_struct *conn,
                show_msg((char *)req->outbuf);
                if (!srv_send_smb(smbd_server_fd(),
                                (char *)req->outbuf,
+                               true, req->seqnum+1,
                                IS_CONN_ENCRYPTED(conn),
                                &req->pcd))
                        exit_server_cleanly("send_trans2_replies: srv_send_smb failed.");
@@ -2892,8 +2893,8 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
                case SMB_QUERY_CIFS_UNIX_INFO:
                {
                        bool large_write = lp_min_receive_file_size() &&
-                                               !srv_is_signing_active();
-                       bool large_read = !srv_is_signing_active();
+                                       !srv_is_signing_active(smbd_server_conn);
+                       bool large_read = !srv_is_signing_active(smbd_server_conn);
                        int encrypt_caps = 0;
 
                        if (!lp_unix_extensions()) {