Turns out I had my packet sequences wrong for oplock break code.
authorJeremy Allison <jra@samba.org>
Thu, 7 Aug 2003 02:59:52 +0000 (02:59 +0000)
committerJeremy Allison <jra@samba.org>
Thu, 7 Aug 2003 02:59:52 +0000 (02:59 +0000)
I was storing the mid of the oplock break - I should have been
storing the mid from the open. There are thus 2 types of deferred
packet sequence returns - ones that increment the sequence number
(returns from oplock causing opens) and ones that don't (change notify
returns etc). Running with signing forced on does lead to some
interesting tests :-).
Jeremy.

source/libsmb/smb_signing.c
source/smbd/blocking.c
source/smbd/notify.c
source/smbd/oplock.c
source/smbd/process.c
source/utils/net_rpc_samsync.c

index 174e29fa52889a26ca43fb0d733672243e6042d2..4b12f36eba7607904d1ff132917ce3711bfdf6f8 100644 (file)
@@ -25,6 +25,7 @@
 struct outstanding_packet_lookup {
        uint16 mid;
        uint32 reply_seq_num;
+       BOOL deferred_packet;
        struct outstanding_packet_lookup *prev, *next;
 };
 
@@ -43,7 +44,7 @@ struct smb_basic_signing_context {
 };
 
 static void store_sequence_for_reply(struct outstanding_packet_lookup **list, 
-                                    uint16 mid, uint32 reply_seq_num) 
+                                    uint16 mid, uint32 reply_seq_num, BOOL deferred_pkt
 {
        struct outstanding_packet_lookup *t;
        struct outstanding_packet_lookup *tmp;
@@ -54,19 +55,25 @@ static void store_sequence_for_reply(struct outstanding_packet_lookup **list,
        DLIST_ADD_END(*list, t, tmp);
        t->mid = mid;
        t->reply_seq_num = reply_seq_num;
-       DEBUG(10,("store_sequence_for_reply: stored seq = %u mid = %u\n",
+       t->deferred_packet = deferred_pkt;
+
+       DEBUG(10,("store_sequence_for_reply: stored %sseq = %u mid = %u\n",
+                       deferred_pkt ? "deferred " : "",
                        (unsigned int)reply_seq_num, (unsigned int)mid ));
 }
 
 static BOOL get_sequence_for_reply(struct outstanding_packet_lookup **list,
-                                  uint16 mid, uint32 *reply_seq_num) 
+                                  uint16 mid, uint32 *reply_seq_num, BOOL *def
 {
        struct outstanding_packet_lookup *t;
 
        for (t = *list; t; t = t->next) {
                if (t->mid == mid) {
                        *reply_seq_num = t->reply_seq_num;
-                       DEBUG(10,("get_sequence_for_reply: found seq = %u mid = %u\n",
+                       if (def)
+                               *def = t->deferred_packet;
+                       DEBUG(10,("get_sequence_for_reply: found %sseq = %u mid = %u\n",
+                               (t->deferred_packet) ? "deferred " : "",
                                (unsigned int)t->reply_seq_num, (unsigned int)t->mid ));
                        DLIST_REMOVE(*list, t);
                        SAFE_FREE(t);
@@ -307,7 +314,7 @@ static void client_sign_outgoing_message(char *outbuf, struct smb_sign_info *si)
        data->send_seq_num++;
        store_sequence_for_reply(&data->outstanding_packet_list, 
                                 SVAL(outbuf,smb_mid),
-                                data->send_seq_num);
+                                data->send_seq_num, False);
        data->send_seq_num++;
 }
 
@@ -337,7 +344,7 @@ static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si)
                reply_seq_number = data->trans_info->reply_seq_num;
        } else if (!get_sequence_for_reply(&data->outstanding_packet_list, 
                                    SVAL(inbuf, smb_mid), 
-                                   &reply_seq_number)) {
+                                   &reply_seq_number, NULL)) {
                DEBUG(1, ("client_check_incoming_message: failed to get sequence number %u for reply.\n",
                                        (unsigned int) SVAL(inbuf, smb_mid) ));
                return False;
@@ -587,18 +594,6 @@ BOOL cli_check_sign_mac(struct cli_state *cli)
        return True;
 }
 
-static BOOL packet_is_oplock_break(char *buf)
-{
-       if (CVAL(buf,smb_com) != SMBlockingX)
-               return False;
-
-       if (!(CVAL(buf,smb_vwv3) & LOCKING_ANDX_OPLOCK_RELEASE))
-               return False;
-
-       DEBUG(10,("packet_is_oplock_break = True !\n"));
-       return True;
-}
-
 /***********************************************************
  SMB signing - Server implementation - send the MAC.
 ************************************************************/
@@ -612,25 +607,6 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si)
        uint16 mid;
 
        if (!si->doing_signing) {
-               if (si->allow_smb_signing && si->negotiated_smb_signing) {
-                       mid = SVAL(outbuf, smb_mid);
-
-                       was_deferred_packet = get_sequence_for_reply(&data->outstanding_packet_list, 
-                                                   mid, &send_seq_number);
-                       if (!was_deferred_packet) {
-                               /*
-                                * Is this an outgoing oplock break ? If so, store the
-                                * mid in the outstanding list. 
-                                */
-
-                               if (packet_is_oplock_break(outbuf)) {
-                                       store_sequence_for_reply(&data->outstanding_packet_list, 
-                                                                mid, data->send_seq_num);
-                               }
-
-                               data->send_seq_num++;
-                       }
-               }
                return;
        }
 
@@ -647,7 +623,7 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si)
        mid = SVAL(outbuf, smb_mid);
 
        /* See if this is a reply for a deferred packet. */
-       was_deferred_packet = get_sequence_for_reply(&data->outstanding_packet_list, mid, &send_seq_number);
+       get_sequence_for_reply(&data->outstanding_packet_list, mid, &send_seq_number, &was_deferred_packet);
 
        if (data->trans_info && (data->trans_info->mid == mid)) {
                /* This is a reply in a trans stream. Use the sequence
@@ -666,7 +642,7 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si)
        Uncomment this to test if the remote server actually verifies signatures...*/
 
        if (!was_deferred_packet) {
-               if (!data->trans_info) {
+                       if (!data->trans_info) {
                        /* Always increment if not in a trans stream. */
                        data->send_seq_num++;
                } else if ((data->trans_info->send_seq_num == data->send_seq_num) || (data->trans_info->mid != mid)) {
@@ -674,7 +650,7 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si)
                         * packet that doesn't belong to this stream (different mid). */
                        data->send_seq_num++;
                }
-       }
+       } 
 }
 
 /***********************************************************
@@ -708,9 +684,6 @@ static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si)
        } else {
                /* We always increment the sequence number. */
                data->send_seq_num++;
-               /* Oplock break requests store an outgoing mid in the packet list. */
-               if (packet_is_oplock_break(inbuf))
-                       get_sequence_for_reply(&data->outstanding_packet_list, mid, &reply_seq_number);
        }
 
        saved_seq = reply_seq_number;
@@ -808,7 +781,7 @@ void srv_calculate_sign_mac(char *outbuf)
  Called by server to defer an outgoing packet.
 ************************************************************/
 
-void srv_defer_sign_response(uint16 mid)
+void srv_defer_sign_response(uint16 mid, BOOL deferred_packet)
 {
        struct smb_basic_signing_context *data;
 
@@ -821,7 +794,7 @@ void srv_defer_sign_response(uint16 mid)
                return;
 
        store_sequence_for_reply(&data->outstanding_packet_list, 
-                                mid, data->send_seq_num);
+                                mid, data->send_seq_num, deferred_packet);
        data->send_seq_num++;
 }
 
@@ -845,7 +818,7 @@ void srv_cancel_sign_response(uint16 mid)
 
        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))
+       while (get_sequence_for_reply(&data->outstanding_packet_list, mid, &dummy_seq,NULL))
                ;
 }
 
index fed3a51b8859f0eccfaa679e4cd751ab557db820..8fa2a6494e3cd2ce8022be02f77c13822ac10e21 100644 (file)
@@ -148,7 +148,7 @@ for fnum = %d, name = %s\n", length, (int)blr->expire_time, lock_timeout,
                blr->fsp->fnum, blr->fsp->fsp_name ));
 
        /* Push the MID of this packet on the signing queue. */
-       srv_defer_sign_response(SVAL(inbuf,smb_mid));
+       srv_defer_sign_response(SVAL(inbuf,smb_mid), True);
 
        return True;
 }
index 9adf827c794d79d43fda49c8ea957d2febfec2d5..ca6f2b783f2567c4c3eb80906eefde3c526c2fe6 100644 (file)
@@ -199,7 +199,7 @@ BOOL change_notify_set(char *inbuf, files_struct *fsp, connection_struct *conn,
        DLIST_ADD(change_notify_list, cnbp);
 
        /* Push the MID of this packet on the signing queue. */
-       srv_defer_sign_response(SVAL(inbuf,smb_mid));
+       srv_defer_sign_response(SVAL(inbuf,smb_mid), True);
 
        return True;
 }
index 19e6956d9ef8b06864a86fdc194a84f8a4149264..49a1b7d8cfdb27d047882a20da51bda3f4584f15 100644 (file)
@@ -743,6 +743,10 @@ static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, unsigned long file_id,
        /* Remember if we just sent a break to level II on this file. */
        fsp->sent_oplock_break = using_levelII? LEVEL_II_BREAK_SENT:EXCLUSIVE_BREAK_SENT;
 
+       /* Ensure the reply for the open uses the correct sequence number. */
+       /* This isn't a real deferred packet as it's response will also increment
+        * the sequence. */
+       srv_defer_sign_response(get_current_mid(), False);
        /* Save the server smb signing state. */
        sign_state = srv_oplock_set_signing(False);
 
index dce1c4bc03b51d35e759e53630521c2f8095a4c3..373c2f16ae358e6d686117a4ca1ab4152460a0a5 100644 (file)
@@ -47,6 +47,15 @@ SIG_ATOMIC_T got_sig_term = 0;
 BOOL global_machine_password_needs_changing = False;
 extern int max_send;
 
+/****************************************************************************
+ Function to return the current request mid from Inbuffer.
+****************************************************************************/
+
+uint16 get_current_mid(void)
+{
+       return SVAL(InBuffer,smb_mid);
+}
+
 /****************************************************************************
  structure to hold a linked list of queued messages.
  for processing.
@@ -88,7 +97,7 @@ static BOOL push_message(ubi_slList *list_head, char *buf, int msg_len)
        ubi_slAddTail( list_head, msg);
 
        /* Push the MID of this packet on the signing queue. */
-       srv_defer_sign_response(SVAL(buf,smb_mid));
+       srv_defer_sign_response(SVAL(buf,smb_mid), True);
 
        return True;
 }
index 18e476f3774b0e586cd4cbe8a49c741975e40bcc..ed69f8a326b15850fdc67df1f1f18d707cabbde9 100644 (file)
@@ -550,7 +550,11 @@ fetch_group_info(uint32 rid, SAM_GROUP_INFO *delta)
        map.sid = group_sid;
        map.sid_name_use = SID_NAME_DOM_GRP;
        fstrcpy(map.nt_name, name);
-       fstrcpy(map.comment, comment);
+       if (delta->hdr_grp_desc.buffer) {
+               fstrcpy(map.comment, comment);
+       } else {
+               fstrcpy(map.comment, "");
+       }
 
        if (insert)
                pdb_add_group_mapping_entry(&map);
@@ -911,10 +915,10 @@ fetch_sam_entry(SAM_DELTA_HDR *hdr_delta, SAM_DELTA_CTR *delta,
                fetch_alias_mem(hdr_delta->target_rid,
                                &delta->als_mem_info, dom_sid);
                break;
+       /* The following types are recognised but not handled */
        case SAM_DELTA_DOMAIN_INFO:
                d_printf("SAM_DELTA_DOMAIN_INFO not handled\n");
                break;
-       /* The following types are recognised but not handled */
        case SAM_DELTA_RENAME_GROUP:
                d_printf("SAM_DELTA_RENAME_GROUP not handled\n");
                break;