mirror of
https://github.com/samba-team/samba.git
synced 2024-12-23 17:34:34 +03:00
smbd: Move make_connection to smb1_service.c
Signed-off-by: David Mulder <dmulder@suse.com> Reviewed-by: Jeremy Allison <jra@samba.org>
This commit is contained in:
parent
b431ec8da0
commit
0ad4a38a47
@ -1032,11 +1032,11 @@ connection_struct *make_connection_smb2(struct smbd_smb2_request *req,
|
||||
int snum,
|
||||
const char *pdev,
|
||||
NTSTATUS *pstatus);
|
||||
connection_struct *make_connection(struct smb_request *req,
|
||||
NTTIME now,
|
||||
const char *service_in,
|
||||
const char *pdev, uint64_t vuid,
|
||||
NTSTATUS *status);
|
||||
NTSTATUS make_connection_snum(struct smbXsrv_connection *xconn,
|
||||
connection_struct *conn,
|
||||
int snum,
|
||||
struct smbXsrv_session *session,
|
||||
const char *pdev);
|
||||
void close_cnum(connection_struct *conn, uint64_t vuid);
|
||||
|
||||
/* The following definitions come from smbd/session.c */
|
||||
|
@ -507,11 +507,11 @@ static NTSTATUS notify_init_sconn(struct smbd_server_connection *sconn)
|
||||
connecting user if appropriate.
|
||||
****************************************************************************/
|
||||
|
||||
static NTSTATUS make_connection_snum(struct smbXsrv_connection *xconn,
|
||||
connection_struct *conn,
|
||||
int snum,
|
||||
struct smbXsrv_session *session,
|
||||
const char *pdev)
|
||||
NTSTATUS make_connection_snum(struct smbXsrv_connection *xconn,
|
||||
connection_struct *conn,
|
||||
int snum,
|
||||
struct smbXsrv_session *session,
|
||||
const char *pdev)
|
||||
{
|
||||
struct smbd_server_connection *sconn = xconn->client->sconn;
|
||||
const struct loadparm_substitution *lp_sub =
|
||||
@ -893,75 +893,6 @@ static NTSTATUS make_connection_snum(struct smbXsrv_connection *xconn,
|
||||
return status;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Make a connection to a service from SMB1. Internal interface.
|
||||
****************************************************************************/
|
||||
|
||||
static connection_struct *make_connection_smb1(struct smb_request *req,
|
||||
NTTIME now,
|
||||
int snum,
|
||||
const char *pdev,
|
||||
NTSTATUS *pstatus)
|
||||
{
|
||||
const struct loadparm_substitution *lp_sub =
|
||||
loadparm_s3_global_substitution();
|
||||
struct smbXsrv_tcon *tcon;
|
||||
NTSTATUS status;
|
||||
struct connection_struct *conn;
|
||||
|
||||
status = smb1srv_tcon_create(req->xconn, now, &tcon);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
DEBUG(0,("make_connection_smb1: Couldn't find free tcon %s.\n",
|
||||
nt_errstr(status)));
|
||||
*pstatus = status;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
conn = conn_new(req->sconn);
|
||||
if (!conn) {
|
||||
TALLOC_FREE(tcon);
|
||||
|
||||
DEBUG(0,("make_connection_smb1: Couldn't find free connection.\n"));
|
||||
*pstatus = NT_STATUS_INSUFFICIENT_RESOURCES;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
conn->cnum = tcon->global->tcon_wire_id;
|
||||
conn->tcon = tcon;
|
||||
|
||||
*pstatus = make_connection_snum(req->xconn,
|
||||
conn,
|
||||
snum,
|
||||
req->session,
|
||||
pdev);
|
||||
if (!NT_STATUS_IS_OK(*pstatus)) {
|
||||
conn_free(conn);
|
||||
TALLOC_FREE(tcon);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tcon->global->share_name = lp_servicename(tcon->global, lp_sub, SNUM(conn));
|
||||
if (tcon->global->share_name == NULL) {
|
||||
conn_free(conn);
|
||||
TALLOC_FREE(tcon);
|
||||
*pstatus = NT_STATUS_NO_MEMORY;
|
||||
return NULL;
|
||||
}
|
||||
tcon->global->session_global_id =
|
||||
req->session->global->session_global_id;
|
||||
|
||||
tcon->compat = talloc_move(tcon, &conn);
|
||||
tcon->status = NT_STATUS_OK;
|
||||
|
||||
*pstatus = smbXsrv_tcon_update(tcon);
|
||||
if (!NT_STATUS_IS_OK(*pstatus)) {
|
||||
TALLOC_FREE(tcon);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return tcon->compat;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Make a connection to a service from SMB2. External SMB2 interface.
|
||||
We must set cnum before claiming connection.
|
||||
@ -996,129 +927,6 @@ connection_struct *make_connection_smb2(struct smbd_smb2_request *req,
|
||||
return conn;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Make a connection to a service. External SMB1 interface.
|
||||
*
|
||||
* @param service
|
||||
****************************************************************************/
|
||||
|
||||
connection_struct *make_connection(struct smb_request *req,
|
||||
NTTIME now,
|
||||
const char *service_in,
|
||||
const char *pdev, uint64_t vuid,
|
||||
NTSTATUS *status)
|
||||
{
|
||||
struct smbd_server_connection *sconn = req->sconn;
|
||||
struct smbXsrv_session *session = req->session;
|
||||
const struct loadparm_substitution *lp_sub =
|
||||
loadparm_s3_global_substitution();
|
||||
uid_t euid;
|
||||
char *service = NULL;
|
||||
fstring dev;
|
||||
int snum = -1;
|
||||
|
||||
fstrcpy(dev, pdev);
|
||||
|
||||
/* This must ONLY BE CALLED AS ROOT. As it exits this function as
|
||||
* root. */
|
||||
if (!non_root_mode() && (euid = geteuid()) != 0) {
|
||||
DEBUG(0,("make_connection: PANIC ERROR. Called as nonroot "
|
||||
"(%u)\n", (unsigned int)euid ));
|
||||
smb_panic("make_connection: PANIC ERROR. Called as nonroot\n");
|
||||
}
|
||||
|
||||
if (conn_num_open(sconn) > 2047) {
|
||||
*status = NT_STATUS_INSUFF_SERVER_RESOURCES;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (session == NULL) {
|
||||
DEBUG(1,("make_connection: refusing to connect with "
|
||||
"no session setup\n"));
|
||||
*status = NT_STATUS_ACCESS_DENIED;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Logic to try and connect to the correct [homes] share, preferably
|
||||
without too many getpwnam() lookups. This is particulary nasty for
|
||||
winbind usernames, where the share name isn't the same as unix
|
||||
username.
|
||||
*/
|
||||
|
||||
if (strequal(service_in,HOMES_NAME)) {
|
||||
if (session->homes_snum == -1) {
|
||||
DEBUG(2, ("[homes] share not available for "
|
||||
"this user because it was not found "
|
||||
"or created at session setup "
|
||||
"time\n"));
|
||||
*status = NT_STATUS_BAD_NETWORK_NAME;
|
||||
return NULL;
|
||||
}
|
||||
DEBUG(5, ("making a connection to [homes] service "
|
||||
"created at session setup time\n"));
|
||||
return make_connection_smb1(req, now,
|
||||
session->homes_snum,
|
||||
dev, status);
|
||||
} else if ((session->homes_snum != -1)
|
||||
&& strequal(service_in,
|
||||
lp_const_servicename(session->homes_snum))) {
|
||||
DEBUG(5, ("making a connection to 'homes' service [%s] "
|
||||
"created at session setup time\n", service_in));
|
||||
return make_connection_smb1(req, now,
|
||||
session->homes_snum,
|
||||
dev, status);
|
||||
}
|
||||
|
||||
service = talloc_strdup(talloc_tos(), service_in);
|
||||
if (!service) {
|
||||
*status = NT_STATUS_NO_MEMORY;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!strlower_m(service)) {
|
||||
DEBUG(2, ("strlower_m %s failed\n", service));
|
||||
*status = NT_STATUS_INVALID_PARAMETER;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
snum = find_service(talloc_tos(), service, &service);
|
||||
if (!service) {
|
||||
*status = NT_STATUS_NO_MEMORY;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (snum < 0) {
|
||||
if (strequal(service,"IPC$") ||
|
||||
(lp_enable_asu_support() && strequal(service,"ADMIN$"))) {
|
||||
DEBUG(3,("refusing IPC connection to %s\n", service));
|
||||
*status = NT_STATUS_ACCESS_DENIED;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DEBUG(3,("%s (%s) couldn't find service %s\n",
|
||||
get_remote_machine_name(),
|
||||
tsocket_address_string(
|
||||
sconn->remote_address, talloc_tos()),
|
||||
service));
|
||||
*status = NT_STATUS_BAD_NETWORK_NAME;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Handle non-Dfs clients attempting connections to msdfs proxy */
|
||||
if (lp_host_msdfs() && (*lp_msdfs_proxy(talloc_tos(), lp_sub, snum) != '\0')) {
|
||||
DEBUG(3, ("refusing connection to dfs proxy share '%s' "
|
||||
"(pointing to %s)\n",
|
||||
service, lp_msdfs_proxy(talloc_tos(), lp_sub, snum)));
|
||||
*status = NT_STATUS_BAD_NETWORK_NAME;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DEBUG(5, ("making a connection to 'normal' service %s\n", service));
|
||||
|
||||
return make_connection_smb1(req, now, snum,
|
||||
dev, status);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Close a cnum.
|
||||
****************************************************************************/
|
||||
|
229
source3/smbd/smb1_service.c
Normal file
229
source3/smbd/smb1_service.c
Normal file
@ -0,0 +1,229 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
service (connection) opening and closing
|
||||
Copyright (C) Andrew Tridgell 1992-1998
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "system/filesys.h"
|
||||
#include "system/passwd.h" /* uid_wrapper */
|
||||
#include "../lib/tsocket/tsocket.h"
|
||||
#include "smbd/smbd.h"
|
||||
#include "smbd/globals.h"
|
||||
#include "../librpc/gen_ndr/netlogon.h"
|
||||
#include "../libcli/security/security.h"
|
||||
#include "printing/pcap.h"
|
||||
#include "passdb/lookup_sid.h"
|
||||
#include "auth.h"
|
||||
#include "../auth/auth_util.h"
|
||||
#include "lib/param/loadparm.h"
|
||||
#include "messages.h"
|
||||
#include "lib/afs/afs_funcs.h"
|
||||
#include "lib/util_path.h"
|
||||
#include "lib/util/string_wrappers.h"
|
||||
#include "source3/lib/substitute.h"
|
||||
|
||||
/****************************************************************************
|
||||
Make a connection to a service from SMB1. Internal interface.
|
||||
****************************************************************************/
|
||||
|
||||
static connection_struct *make_connection_smb1(struct smb_request *req,
|
||||
NTTIME now,
|
||||
int snum,
|
||||
const char *pdev,
|
||||
NTSTATUS *pstatus)
|
||||
{
|
||||
const struct loadparm_substitution *lp_sub =
|
||||
loadparm_s3_global_substitution();
|
||||
struct smbXsrv_tcon *tcon;
|
||||
NTSTATUS status;
|
||||
struct connection_struct *conn;
|
||||
|
||||
status = smb1srv_tcon_create(req->xconn, now, &tcon);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
DEBUG(0,("make_connection_smb1: Couldn't find free tcon %s.\n",
|
||||
nt_errstr(status)));
|
||||
*pstatus = status;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
conn = conn_new(req->sconn);
|
||||
if (!conn) {
|
||||
TALLOC_FREE(tcon);
|
||||
|
||||
DEBUG(0,("make_connection_smb1: Couldn't find free connection.\n"));
|
||||
*pstatus = NT_STATUS_INSUFFICIENT_RESOURCES;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
conn->cnum = tcon->global->tcon_wire_id;
|
||||
conn->tcon = tcon;
|
||||
|
||||
*pstatus = make_connection_snum(req->xconn,
|
||||
conn,
|
||||
snum,
|
||||
req->session,
|
||||
pdev);
|
||||
if (!NT_STATUS_IS_OK(*pstatus)) {
|
||||
conn_free(conn);
|
||||
TALLOC_FREE(tcon);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tcon->global->share_name = lp_servicename(tcon->global, lp_sub, SNUM(conn));
|
||||
if (tcon->global->share_name == NULL) {
|
||||
conn_free(conn);
|
||||
TALLOC_FREE(tcon);
|
||||
*pstatus = NT_STATUS_NO_MEMORY;
|
||||
return NULL;
|
||||
}
|
||||
tcon->global->session_global_id =
|
||||
req->session->global->session_global_id;
|
||||
|
||||
tcon->compat = talloc_move(tcon, &conn);
|
||||
tcon->status = NT_STATUS_OK;
|
||||
|
||||
*pstatus = smbXsrv_tcon_update(tcon);
|
||||
if (!NT_STATUS_IS_OK(*pstatus)) {
|
||||
TALLOC_FREE(tcon);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return tcon->compat;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Make a connection to a service. External SMB1 interface.
|
||||
*
|
||||
* @param service
|
||||
****************************************************************************/
|
||||
|
||||
connection_struct *make_connection(struct smb_request *req,
|
||||
NTTIME now,
|
||||
const char *service_in,
|
||||
const char *pdev, uint64_t vuid,
|
||||
NTSTATUS *status)
|
||||
{
|
||||
struct smbd_server_connection *sconn = req->sconn;
|
||||
struct smbXsrv_session *session = req->session;
|
||||
const struct loadparm_substitution *lp_sub =
|
||||
loadparm_s3_global_substitution();
|
||||
uid_t euid;
|
||||
char *service = NULL;
|
||||
fstring dev;
|
||||
int snum = -1;
|
||||
|
||||
fstrcpy(dev, pdev);
|
||||
|
||||
/* This must ONLY BE CALLED AS ROOT. As it exits this function as
|
||||
* root. */
|
||||
if (!non_root_mode() && (euid = geteuid()) != 0) {
|
||||
DEBUG(0,("make_connection: PANIC ERROR. Called as nonroot "
|
||||
"(%u)\n", (unsigned int)euid ));
|
||||
smb_panic("make_connection: PANIC ERROR. Called as nonroot\n");
|
||||
}
|
||||
|
||||
if (conn_num_open(sconn) > 2047) {
|
||||
*status = NT_STATUS_INSUFF_SERVER_RESOURCES;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (session == NULL) {
|
||||
DEBUG(1,("make_connection: refusing to connect with "
|
||||
"no session setup\n"));
|
||||
*status = NT_STATUS_ACCESS_DENIED;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Logic to try and connect to the correct [homes] share, preferably
|
||||
without too many getpwnam() lookups. This is particulary nasty for
|
||||
winbind usernames, where the share name isn't the same as unix
|
||||
username.
|
||||
*/
|
||||
|
||||
if (strequal(service_in,HOMES_NAME)) {
|
||||
if (session->homes_snum == -1) {
|
||||
DEBUG(2, ("[homes] share not available for "
|
||||
"this user because it was not found "
|
||||
"or created at session setup "
|
||||
"time\n"));
|
||||
*status = NT_STATUS_BAD_NETWORK_NAME;
|
||||
return NULL;
|
||||
}
|
||||
DEBUG(5, ("making a connection to [homes] service "
|
||||
"created at session setup time\n"));
|
||||
return make_connection_smb1(req, now,
|
||||
session->homes_snum,
|
||||
dev, status);
|
||||
} else if ((session->homes_snum != -1)
|
||||
&& strequal(service_in,
|
||||
lp_const_servicename(session->homes_snum))) {
|
||||
DEBUG(5, ("making a connection to 'homes' service [%s] "
|
||||
"created at session setup time\n", service_in));
|
||||
return make_connection_smb1(req, now,
|
||||
session->homes_snum,
|
||||
dev, status);
|
||||
}
|
||||
|
||||
service = talloc_strdup(talloc_tos(), service_in);
|
||||
if (!service) {
|
||||
*status = NT_STATUS_NO_MEMORY;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!strlower_m(service)) {
|
||||
DEBUG(2, ("strlower_m %s failed\n", service));
|
||||
*status = NT_STATUS_INVALID_PARAMETER;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
snum = find_service(talloc_tos(), service, &service);
|
||||
if (!service) {
|
||||
*status = NT_STATUS_NO_MEMORY;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (snum < 0) {
|
||||
if (strequal(service,"IPC$") ||
|
||||
(lp_enable_asu_support() && strequal(service,"ADMIN$"))) {
|
||||
DEBUG(3,("refusing IPC connection to %s\n", service));
|
||||
*status = NT_STATUS_ACCESS_DENIED;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DEBUG(3,("%s (%s) couldn't find service %s\n",
|
||||
get_remote_machine_name(),
|
||||
tsocket_address_string(
|
||||
sconn->remote_address, talloc_tos()),
|
||||
service));
|
||||
*status = NT_STATUS_BAD_NETWORK_NAME;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Handle non-Dfs clients attempting connections to msdfs proxy */
|
||||
if (lp_host_msdfs() && (*lp_msdfs_proxy(talloc_tos(), lp_sub, snum) != '\0')) {
|
||||
DEBUG(3, ("refusing connection to dfs proxy share '%s' "
|
||||
"(pointing to %s)\n",
|
||||
service, lp_msdfs_proxy(talloc_tos(), lp_sub, snum)));
|
||||
*status = NT_STATUS_BAD_NETWORK_NAME;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DEBUG(5, ("making a connection to 'normal' service %s\n", service));
|
||||
|
||||
return make_connection_smb1(req, now, snum,
|
||||
dev, status);
|
||||
}
|
24
source3/smbd/smb1_service.h
Normal file
24
source3/smbd/smb1_service.h
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
service (connection) opening and closing
|
||||
Copyright (C) Andrew Tridgell 1992-1998
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
connection_struct *make_connection(struct smb_request *req,
|
||||
NTTIME now,
|
||||
const char *service_in,
|
||||
const char *pdev, uint64_t vuid,
|
||||
NTSTATUS *status);
|
@ -37,6 +37,7 @@ struct dptr_struct;
|
||||
#include "smbd/smb1_oplock.h"
|
||||
#include "smbd/smb1_pipes.h"
|
||||
#include "smbd/smb1_reply.h"
|
||||
#include "smbd/smb1_service.h"
|
||||
#endif
|
||||
|
||||
struct trans_state {
|
||||
|
@ -610,6 +610,7 @@ if bld.CONFIG_SET('WITH_SMB1SERVER'):
|
||||
smbd/smb1_oplock.c
|
||||
smbd/smb1_pipes.c
|
||||
smbd/smb1_reply.c
|
||||
smbd/smb1_service.c
|
||||
'''
|
||||
else:
|
||||
SMB1_SOURCES = ''
|
||||
|
Loading…
Reference in New Issue
Block a user