From c16c90a1cb3b0e2ceadd3dea835a4e69acfc2fae Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 9 Mar 2009 09:47:59 +0100 Subject: [PATCH] s3:smbd: use new simplified snb_signing code in the server We keep the seqnum/mid mapping in the smb_request structure. This also moves one global variable into the smbd_server_connection struct. metze --- source3/Makefile.in | 2 +- source3/include/proto.h | 32 ++-- source3/include/smb.h | 2 + source3/libsmb/clisigning.c | 333 ------------------------------------ source3/param/loadparm.c | 11 +- source3/smbd/aio.c | 13 +- source3/smbd/blocking.c | 5 +- source3/smbd/globals.h | 1 + source3/smbd/ipc.c | 4 + source3/smbd/negprot.c | 2 +- source3/smbd/notify.c | 7 +- source3/smbd/nttrans.c | 3 +- source3/smbd/open.c | 9 - source3/smbd/oplock.c | 27 +-- source3/smbd/password.c | 8 +- source3/smbd/pipes.c | 1 + source3/smbd/process.c | 50 ++++-- source3/smbd/reply.c | 24 ++- source3/smbd/service.c | 2 +- source3/smbd/sesssetup.c | 25 --- source3/smbd/signing.c | 158 +++++++++++++++++ source3/smbd/trans2.c | 5 +- 22 files changed, 270 insertions(+), 454 deletions(-) create mode 100644 source3/smbd/signing.c diff --git a/source3/Makefile.in b/source3/Makefile.in index 8dbb7b5d67c..46216c7f085 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -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@ diff --git a/source3/include/proto.h b/source3/include/proto.h index 1ed623c4cb2..356eb4935fd 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -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, diff --git a/source3/include/smb.h b/source3/include/smb.h index 281a218256f..215adba1b4a 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -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; diff --git a/source3/libsmb/clisigning.c b/source3/libsmb/clisigning.c index a3ed0e75729..6644bc0d600 100644 --- a/source3/libsmb/clisigning.c +++ b/source3/libsmb/clisigning.c @@ -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; -} diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index f49a1bc4c94..8460fea5671 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -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); } /******************************************************************* diff --git a/source3/smbd/aio.c b/source3/smbd/aio.c index cfa4b430ebf..77616be48c6 100644 --- a/source3/smbd/aio.c +++ b/source3/smbd/aio.c @@ -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; } diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 42849931f3a..4c61428692d 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -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: " diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h index 6ac92ed3ddb..b646bc30fda 100644 --- a/source3/smbd/globals.h +++ b/source3/smbd/globals.h @@ -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; diff --git a/source3/smbd/ipc.c b/source3/smbd/ipc.c index f20c8512975..d39aab4f471 100644 --- a/source3/smbd/ipc.c +++ b/source3/smbd/ipc.c @@ -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 " diff --git a/source3/smbd/negprot.c b/source3/smbd/negprot.c index a921954c49c..e548c587c15 100644 --- a/source3/smbd/negprot.c +++ b/source3/smbd/negprot.c @@ -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) { diff --git a/source3/smbd/notify.c b/source3/smbd/notify.c index 8ceeaf5f558..fdab2ca8485 100644 --- a/source3/smbd/notify.c +++ b/source3/smbd/notify.c @@ -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; } diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index 9c7fb1914e8..628fc1bd32b 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -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)); diff --git a/source3/smbd/open.c b/source3/smbd/open.c index d529b009d50..52df4fa1431 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -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); } diff --git a/source3/smbd/oplock.c b/source3/smbd/oplock.c index 22870283fa5..ce00397bbde 100644 --- a/source3/smbd/oplock.c +++ b/source3/smbd/oplock.c @@ -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; diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 15d120a79c4..076965e783c 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -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 */ diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 2686cf41d93..7ae74356462 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -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."); diff --git a/source3/smbd/process.c b/source3/smbd/process.c index 6d53bbe929e..65778ab0fc2 100644 --- a/source3/smbd/process.c +++ b/source3/smbd/process.c @@ -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"); diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 8b560bd8ca6..6f19a58178b 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -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."); diff --git a/source3/smbd/service.c b/source3/smbd/service.c index eb16a2601e3..e33f04d971b 100644 --- a/source3/smbd/service.c +++ b/source3/smbd/service.c @@ -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 ); diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 2c29192220b..e8878a29ab3 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -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 index 00000000000..b56eb71f45c --- /dev/null +++ b/source3/smbd/signing.c @@ -0,0 +1,158 @@ +/* + Unix SMB/CIFS implementation. + SMB Signing Code + Copyright (C) Jeremy Allison 2003. + Copyright (C) Andrew Bartlett 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 . +*/ + +#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)); +} + diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index ee1dda98b22..df01a398934 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -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()) { -- 2.34.1