The branch, v3-6-test has been updated
       via  a455a63 Fix bug 8710 - connections.tdb - major leak with SMB2.
      from  6e77eac Fix bug #8664 - Renaming a symlink fails if the symlink 
target is outside of the share.

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-6-test


- Log -----------------------------------------------------------------
commit a455a63eaf84024f79922e95a740bf3443f37954
Author: Jeremy Allison <j...@samba.org>
Date:   Wed Jan 18 12:38:14 2012 -0800

    Fix bug 8710 - connections.tdb - major leak with SMB2.
    
    Ensure the cnum used to claim the connection for SMB2 is the
    id that will be used for the SMB2 tcon. Based on code from
    Ira Cooper <i...@wakeful.net>.
    
    Autobuild-User: Jeremy Allison <j...@samba.org>
    Autobuild-Date: Wed Jan 18 23:14:32 CET 2012 on sn-devel-104
    (cherry picked from commit 39c627b60754bd89c419b2d7e32d32c7a9af5a11)

-----------------------------------------------------------------------

Summary of changes:
 source3/smbd/proto.h     |    6 ++-
 source3/smbd/service.c   |   88 +++++++++++++++++++++++++++++++++++++---------
 source3/smbd/smb2_tcon.c |    6 ++--
 3 files changed, 78 insertions(+), 22 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index 02b5e40..aadad4b 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -981,8 +981,10 @@ bool set_current_service(connection_struct *conn, uint16 
flags, bool do_chdir);
 void load_registry_shares(void);
 int add_home_service(const char *service, const char *username, const char 
*homedir);
 int find_service(TALLOC_CTX *ctx, const char *service, char **p_service_out);
-connection_struct *make_connection_snum(struct smbd_server_connection *sconn,
-                                       int snum, user_struct *vuser,
+struct smbd_smb2_tcon;
+connection_struct *make_connection_smb2(struct smbd_server_connection *sconn,
+                                       struct smbd_smb2_tcon *tcon,
+                                       user_struct *vuser,
                                        DATA_BLOB password,
                                        const char *pdev,
                                        NTSTATUS *pstatus);
diff --git a/source3/smbd/service.c b/source3/smbd/service.c
index d88c02c..34b24f3 100644
--- a/source3/smbd/service.c
+++ b/source3/smbd/service.c
@@ -736,13 +736,13 @@ NTSTATUS set_conn_force_user_group(connection_struct 
*conn, int snum)
   connecting user if appropriate.
 ****************************************************************************/
 
-connection_struct *make_connection_snum(struct smbd_server_connection *sconn,
+static connection_struct *make_connection_snum(struct smbd_server_connection 
*sconn,
+                                       connection_struct *conn,
                                        int snum, user_struct *vuser,
                                        DATA_BLOB password,
                                        const char *pdev,
                                        NTSTATUS *pstatus)
 {
-       connection_struct *conn = NULL;
        struct smb_filename *smb_fname_cpath = NULL;
        fstring dev;
        int ret;
@@ -759,13 +759,6 @@ connection_struct *make_connection_snum(struct 
smbd_server_connection *sconn,
                goto err_root_exit;
        }
 
-       conn = conn_new(sconn);
-       if (!conn) {
-               DEBUG(0,("Couldn't find free connection.\n"));
-               *pstatus = NT_STATUS_INSUFFICIENT_RESOURCES;
-               goto err_root_exit;
-       }
-
        conn->params->service = snum;
 
        status = create_connection_session_info(sconn,
@@ -815,7 +808,6 @@ connection_struct *make_connection_snum(struct 
smbd_server_connection *sconn,
 
        status = set_conn_force_user_group(conn, snum);
        if (!NT_STATUS_IS_OK(status)) {
-               conn_free(conn);
                *pstatus = status;
                return NULL;
        }
@@ -1112,14 +1104,76 @@ connection_struct *make_connection_snum(struct 
smbd_server_connection *sconn,
        if (claimed_connection) {
                yield_connection(conn, lp_servicename(snum));
        }
-       if (conn) {
+       return NULL;
+}
+
+/****************************************************************************
+ Make a connection to a service from SMB1. Internal interface.
+****************************************************************************/
+
+static connection_struct *make_connection_smb1(struct smbd_server_connection 
*sconn,
+                                       int snum, user_struct *vuser,
+                                       DATA_BLOB password,
+                                       const char *pdev,
+                                       NTSTATUS *pstatus)
+{
+       connection_struct *ret_conn = NULL;
+       connection_struct *conn = conn_new(sconn);
+       if (!conn) {
+               DEBUG(0,("make_connection_smb1: Couldn't find free 
connection.\n"));
+               *pstatus = NT_STATUS_INSUFFICIENT_RESOURCES;
+               return NULL;
+       }
+       ret_conn = make_connection_snum(sconn,
+                                       conn,
+                                       snum,
+                                       vuser,
+                                        password,
+                                       pdev,
+                                       pstatus);
+       if (ret_conn != conn) {
                conn_free(conn);
+               return NULL;
        }
-       return NULL;
+       return conn;
+}
+
+/****************************************************************************
+ Make a connection to a service from SMB2. External SMB2 interface.
+ We must set cnum before claiming connection.
+****************************************************************************/
+
+connection_struct *make_connection_smb2(struct smbd_server_connection *sconn,
+                                       struct smbd_smb2_tcon *tcon,
+                                       user_struct *vuser,
+                                       DATA_BLOB password,
+                                       const char *pdev,
+                                       NTSTATUS *pstatus)
+{
+       connection_struct *ret_conn = NULL;
+       connection_struct *conn = conn_new(sconn);
+       if (!conn) {
+               DEBUG(0,("make_connection_smb2: Couldn't find free 
connection.\n"));
+               *pstatus = NT_STATUS_INSUFFICIENT_RESOURCES;
+               return NULL;
+       }
+       conn->cnum = tcon->tid;
+       ret_conn = make_connection_snum(sconn,
+                                       conn,
+                                       tcon->snum,
+                                       vuser,
+                                        password,
+                                       pdev,
+                                       pstatus);
+       if (ret_conn != conn) {
+               conn_free(conn);
+               return NULL;
+       }
+       return conn;
 }
 
 /****************************************************************************
- Make a connection to a service.
+ Make a connection to a service. External SMB1 interface.
  *
  * @param service 
 ****************************************************************************/
@@ -1182,7 +1236,7 @@ connection_struct *make_connection(struct 
smbd_server_connection *sconn,
                        }
                        DEBUG(5, ("making a connection to [homes] service "
                                  "created at session setup time\n"));
-                       return make_connection_snum(sconn,
+                       return make_connection_smb1(sconn,
                                                    vuser->homes_snum,
                                                    vuser, no_pw, 
                                                    dev, status);
@@ -1206,7 +1260,7 @@ connection_struct *make_connection(struct 
smbd_server_connection *sconn,
                                DEBUG(5, ("making a connection to 'homes' "
                                          "service %s based on "
                                          "security=share\n", service_in));
-                               return make_connection_snum(sconn,
+                               return make_connection_smb1(sconn,
                                                            snum, NULL,
                                                            password,
                                                            dev, status);
@@ -1218,7 +1272,7 @@ connection_struct *make_connection(struct 
smbd_server_connection *sconn,
                DATA_BLOB no_pw = data_blob_null;
                DEBUG(5, ("making a connection to 'homes' service [%s] "
                          "created at session setup time\n", service_in));
-               return make_connection_snum(sconn,
+               return make_connection_smb1(sconn,
                                            vuser->homes_snum,
                                            vuser, no_pw, 
                                            dev, status);
@@ -1266,7 +1320,7 @@ connection_struct *make_connection(struct 
smbd_server_connection *sconn,
 
        DEBUG(5, ("making a connection to 'normal' service %s\n", service));
 
-       return make_connection_snum(sconn, snum, vuser,
+       return make_connection_smb1(sconn, snum, vuser,
                                    password,
                                    dev, status);
 }
diff --git a/source3/smbd/smb2_tcon.c b/source3/smbd/smb2_tcon.c
index f1f03e8..5ca303e 100644
--- a/source3/smbd/smb2_tcon.c
+++ b/source3/smbd/smb2_tcon.c
@@ -228,8 +228,9 @@ static NTSTATUS smbd_smb2_tree_connect(struct 
smbd_smb2_request *req,
        tcon->session->sconn->num_tcons_open++;
        talloc_set_destructor(tcon, smbd_smb2_tcon_destructor);
 
-       compat_conn = make_connection_snum(req->sconn,
-                                       snum, req->session->compat_vuser,
+       compat_conn = make_connection_smb2(req->sconn,
+                                       tcon,
+                                       req->session->compat_vuser,
                                        data_blob_null, "???",
                                        &status);
        if (compat_conn == NULL) {
@@ -237,7 +238,6 @@ static NTSTATUS smbd_smb2_tree_connect(struct 
smbd_smb2_request *req,
                return status;
        }
        tcon->compat_conn = talloc_move(tcon, &compat_conn);
-       tcon->compat_conn->cnum = tcon->tid;
 
        if (IS_PRINT(tcon->compat_conn)) {
                *out_share_type = SMB2_SHARE_TYPE_PRINT;


-- 
Samba Shared Repository

Reply via email to