Make conn_close_all() safe to call from SMB2 sessions (fix crash bug).
authorJeremy Allison <jra@samba.org>
Thu, 25 Feb 2010 02:11:07 +0000 (18:11 -0800)
committerJeremy Allison <jra@samba.org>
Thu, 25 Feb 2010 02:11:07 +0000 (18:11 -0800)
Ensure we don't call close_cnum() with SMB2, also talloc_move the
compat_conn pointer from the NULL context onto the tcon context
in SMB2 as it's conceptually owned by that pointer.

Jeremy.

source3/smbd/conn.c
source3/smbd/smb2_tcon.c

index 959fcd7754de3f6de6bc432c34b5c663135592da..51f880d9df01238bacd1e8ac323323c4a06ad396 100644 (file)
@@ -177,15 +177,26 @@ return true if any were closed
 ****************************************************************************/
 bool conn_close_all(struct smbd_server_connection *sconn)
 {
-       connection_struct *conn, *next;
-       bool ret = false;
-       for (conn=sconn->smb1.tcons.Connections;conn;conn=next) {
-               next=conn->next;
-               set_current_service(conn, 0, True);
-               close_cnum(conn, conn->vuid);
-               ret = true;
+       if (sconn->allow_smb2) {
+               /* SMB2 */
+               if (sconn->smb2.sessions.list &&
+                               sconn->smb2.sessions.list->tcons.list) {
+                       return true;
+               }
+               return false;
+       } else {
+               /* SMB1 */
+               connection_struct *conn, *next;
+               bool ret = false;
+
+               for (conn=sconn->smb1.tcons.Connections;conn;conn=next) {
+                       next=conn->next;
+                       set_current_service(conn, 0, True);
+                       close_cnum(conn, conn->vuid);
+                       ret = true;
+               }
+               return ret;
        }
-       return ret;
 }
 
 /****************************************************************************
index 70c5e8845e5d6c4e9710991b23f095b1c8baa1bb..bd33007c18a58715c9a1a2d7e346de19173795d4 100644 (file)
@@ -150,6 +150,7 @@ static NTSTATUS smbd_smb2_tree_connect(struct smbd_smb2_request *req,
        fstring service;
        int snum = -1;
        struct smbd_smb2_tcon *tcon;
+       connection_struct *compat_conn = NULL;
        int id;
        NTSTATUS status;
 
@@ -196,14 +197,15 @@ static NTSTATUS smbd_smb2_tree_connect(struct smbd_smb2_request *req,
        tcon->session = req->session;
        talloc_set_destructor(tcon, smbd_smb2_tcon_destructor);
 
-       tcon->compat_conn = make_connection_snum(req->sconn,
+       compat_conn = make_connection_snum(req->sconn,
                                        snum, req->session->compat_vuser,
                                        data_blob_null, "???",
                                        &status);
-       if (tcon->compat_conn == NULL) {
+       if (compat_conn == NULL) {
                TALLOC_FREE(tcon);
                return status;
        }
+       tcon->compat_conn = talloc_move(tcon, &compat_conn);
        tcon->compat_conn->cnum = tcon->tid;
 
        *out_share_type = 0x01;