summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/smbd/proto.h6
-rw-r--r--source3/smbd/service.c88
-rw-r--r--source3/smbd/smb2_tcon.c6
3 files changed, 78 insertions, 22 deletions
diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index 92b1443a98..d4ee4d25ba 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -971,8 +971,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 6d6f9637ed..4d55977ad2 100644
--- a/source3/smbd/service.c
+++ b/source3/smbd/service.c
@@ -527,13 +527,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;
@@ -553,13 +553,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,
@@ -609,7 +602,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;
}
@@ -907,14 +899,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
****************************************************************************/
@@ -977,7 +1031,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);
@@ -1001,7 +1055,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);
@@ -1013,7 +1067,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);
@@ -1061,7 +1115,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 4c0544fba2..b7e5ce0877 100644
--- a/source3/smbd/smb2_tcon.c
+++ b/source3/smbd/smb2_tcon.c
@@ -229,8 +229,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) {
@@ -238,7 +239,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;