diff options
-rw-r--r-- | source3/smbd/proto.h | 6 | ||||
-rw-r--r-- | source3/smbd/service.c | 88 | ||||
-rw-r--r-- | source3/smbd/smb2_tcon.c | 6 |
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; |