#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"
-static bool canonicalize_connect_path(connection_struct *conn)
+bool canonicalize_connect_path(connection_struct *conn)
{
bool ret;
struct smb_filename con_fname = { .base_name = conn->connectpath };
return false;
}
- DEBUG(10,("set_conn_connectpath: service %s, connectpath = %s\n",
- lp_servicename(talloc_tos(), SNUM(conn)), destname ));
+ DBG_DEBUG("service %s, connectpath = %s\n",
+ lp_const_servicename(SNUM(conn)), destname);
talloc_free(conn->connectpath);
conn->connectpath = destname;
/*
- * Ensure conn->cwd_fname is initialized.
+ * Ensure conn->cwd_fsp->fsp_name is initialized.
* start as conn->connectpath.
*/
- TALLOC_FREE(conn->cwd_fname);
- conn->cwd_fname = synthetic_smb_fname(conn,
+ TALLOC_FREE(conn->cwd_fsp->fsp_name);
+ conn->cwd_fsp->fsp_name = synthetic_smb_fname(conn,
conn->connectpath,
NULL,
NULL,
+ 0,
0);
- if (conn->cwd_fname == NULL) {
+ if (conn->cwd_fsp->fsp_name == NULL) {
return false;
}
return true;
const struct smb_filename origpath_fname = {
.base_name = conn->origpath,
};
+ int saved_errno = 0;
+ char *utok_str = NULL;
int ret;
conn->lastused_count++;
ret = vfs_ChDir(conn, &connectpath_fname);
- if (ret != 0) {
- DEBUG(((errno!=EACCES)?0:3),
- ("chdir (%s) failed, reason: %s\n",
- conn->connectpath, strerror(errno)));
- return false;
+ if (ret == 0) {
+ return true;
}
+ saved_errno = errno;
- ret = vfs_ChDir(conn, &origpath_fname);
- if (ret != 0) {
- DEBUG(((errno!=EACCES)?0:3),
- ("chdir (%s) failed, reason: %s\n",
- conn->origpath, strerror(errno)));
+ utok_str = utok_string(talloc_tos(),
+ conn->session_info->unix_token);
+ if (utok_str == NULL) {
+ errno = saved_errno;
return false;
}
- return true;
-}
-
-bool set_current_service(connection_struct *conn, uint16_t flags, bool do_chdir)
-{
- bool ok;
+ DBG_ERR("vfs_ChDir(%s) failed: %s. Current token: %s\n",
+ conn->connectpath,
+ strerror(saved_errno),
+ utok_str);
- if (conn == NULL) {
- return false;
+ ret = vfs_ChDir(conn, &origpath_fname);
+ if (ret == 0) {
+ TALLOC_FREE(utok_str);
+ return true;
}
+ saved_errno = errno;
- set_current_case_sensitive(conn, flags);
+ DBG_ERR("vfs_ChDir(%s) failed: %s. Current token: %s\n",
+ conn->origpath,
+ strerror(saved_errno),
+ utok_str);
- if (do_chdir) {
- ok = chdir_current_service(conn);
- if (!ok) {
- return false;
- }
+ if (saved_errno != 0) {
+ errno = saved_errno;
}
-
- return true;
+ return false;
}
/****************************************************************************
{
NTSTATUS result = NT_STATUS_NO_SUCH_GROUP;
TALLOC_CTX *frame = talloc_stackframe();
+ const struct loadparm_substitution *lp_sub =
+ loadparm_s3_global_substitution();
struct dom_sid group_sid;
enum lsa_SidType type;
char *groupname;
bool user_must_be_member = False;
gid_t gid;
- groupname = lp_force_group(talloc_tos(), snum);
+ groupname = lp_force_group(talloc_tos(), lp_sub, snum);
if (groupname == NULL) {
DEBUG(1, ("talloc_strdup failed\n"));
result = NT_STATUS_NO_MEMORY;
}
groupname = talloc_string_sub(talloc_tos(), groupname,
- "%S", lp_servicename(talloc_tos(), snum));
+ "%S", lp_const_servicename(snum));
if (groupname == NULL) {
DEBUG(1, ("talloc_string_sub failed\n"));
result = NT_STATUS_NO_MEMORY;
}
if (!sid_to_gid(&group_sid, &gid)) {
+ struct dom_sid_buf buf;
DEBUG(10, ("sid_to_gid(%s) for %s failed\n",
- sid_string_dbg(&group_sid), groupname));
+ dom_sid_str_buf(&group_sid, &buf), groupname));
goto done;
}
if (security_session_user_level(session_info, NULL) < SECURITY_USER) {
if (!lp_guest_ok(snum)) {
- DEBUG(2, ("guest user (from session setup) "
+ DBG_WARNING("guest user (from session setup) "
"not permitted to access this share "
- "(%s)\n", lp_servicename(talloc_tos(), snum)));
+ "(%s)\n", lp_const_servicename(snum));
return NT_STATUS_ACCESS_DENIED;
}
} else {
if (!user_ok_token(session_info->unix_info->unix_name,
session_info->info->domain_name,
session_info->security_token, snum)) {
- DEBUG(2, ("user '%s' (from session setup) not "
+ DBG_WARNING("user '%s' (from session setup) not "
"permitted to access this share "
"(%s)\n",
session_info->unix_info->unix_name,
- lp_servicename(talloc_tos(), snum)));
+ lp_const_servicename(snum));
return NT_STATUS_ACCESS_DENIED;
}
}
NTSTATUS set_conn_force_user_group(connection_struct *conn, int snum)
{
+ const struct loadparm_substitution *lp_sub =
+ loadparm_s3_global_substitution();
NTSTATUS status;
- if (*lp_force_user(talloc_tos(), snum)) {
+ if (*lp_force_user(talloc_tos(), lp_sub, snum)) {
/*
* Replace conn->session_info with a completely faked up one
struct auth_session_info *forced_serverinfo;
bool guest;
- fuser = talloc_string_sub(conn, lp_force_user(talloc_tos(), snum), "%S",
+ fuser = talloc_string_sub(conn, lp_force_user(talloc_tos(), lp_sub, snum), "%S",
lp_const_servicename(snum));
if (fuser == NULL) {
return NT_STATUS_NO_MEMORY;
* any groupid stored for the connecting user.
*/
- if (*lp_force_group(talloc_tos(), snum)) {
+ if (*lp_force_group(talloc_tos(), lp_sub, snum)) {
status = find_forced_group(
conn->force_user, snum, conn->session_info->unix_info->unix_name,
return NT_STATUS_OK;
}
- sconn->notify_ctx = notify_init(sconn, sconn->msg_ctx, sconn->ev_ctx,
+ sconn->notify_ctx = notify_init(sconn, sconn->msg_ctx,
sconn, notify_callback);
if (sconn->notify_ctx == NULL) {
return NT_STATUS_NO_MEMORY;
static NTSTATUS make_connection_snum(struct smbXsrv_connection *xconn,
connection_struct *conn,
- int snum, struct user_struct *vuser,
+ int snum,
+ struct smbXsrv_session *session,
const char *pdev)
{
struct smbd_server_connection *sconn = xconn->client->sconn;
+ const struct loadparm_substitution *lp_sub =
+ loadparm_s3_global_substitution();
struct smb_filename *smb_fname_cpath = NULL;
fstring dev;
int ret;
uid_t effuid;
gid_t effgid;
NTSTATUS status;
+ bool ok;
fstrcpy(dev, pdev);
conn->params->service = snum;
status = create_connection_session_info(sconn,
- conn, snum, vuser->session_info,
+ conn, snum, session->global->auth_session_info,
&conn->session_info);
if (!NT_STATUS_IS_OK(status)) {
if (conn->encrypt_level == SMB_SIGNING_REQUIRED) {
DBG_ERR("Service [%s] requires encryption, but "
"it is disabled globally!\n",
- lp_servicename(talloc_tos(), snum));
+ lp_const_servicename(snum));
status = NT_STATUS_ACCESS_DENIED;
goto err_root_exit;
}
goto err_root_exit;
}
- conn->vuid = vuser->vuid;
+ conn->vuid = session->global->session_wire_id;
{
- char *s = talloc_sub_advanced(talloc_tos(),
- lp_servicename(talloc_tos(), SNUM(conn)),
+ char *s = talloc_sub_full(talloc_tos(),
+ lp_const_servicename(SNUM(conn)),
conn->session_info->unix_info->unix_name,
conn->connectpath,
conn->session_info->unix_token->gid,
conn->session_info->unix_info->sanitized_username,
conn->session_info->info->domain_name,
- lp_path(talloc_tos(), snum));
+ lp_path(talloc_tos(), lp_sub, snum));
if (!s) {
status = NT_STATUS_NO_MEMORY;
goto err_root_exit;
status = NT_STATUS_NO_MEMORY;
goto err_root_exit;
}
- DEBUG(3,("Connect path is '%s' for service [%s]\n",s,
- lp_servicename(talloc_tos(), snum)));
+ DBG_NOTICE("Connect path is '%s' for service [%s]\n", s,
+ lp_const_servicename(snum));
TALLOC_FREE(s);
}
*/
status = check_user_share_access(conn,
- vuser->session_info,
+ session->global->auth_session_info,
&conn->share_access,
&conn->read_only);
if (!NT_STATUS_IS_OK(status)) {
/* Initialise VFS function pointers */
if (!smbd_vfs_init(conn)) {
- DEBUG(0, ("vfs_init failed for service %s\n",
- lp_servicename(talloc_tos(), snum)));
+ DBG_ERR("vfs_init failed for service %s\n",
+ lp_const_servicename(snum));
status = NT_STATUS_BAD_NETWORK_NAME;
goto err_root_exit;
}
*/
if ((lp_max_connections(snum) > 0)
- && (count_current_connections(lp_servicename(talloc_tos(), SNUM(conn)), True) >=
+ && (count_current_connections(lp_const_servicename(SNUM(conn)), true) >=
lp_max_connections(snum))) {
- DEBUG(1, ("Max connections (%d) exceeded for %s\n",
+ DBG_WARNING("Max connections (%d) exceeded for %s\n",
lp_max_connections(snum),
- lp_servicename(talloc_tos(), snum)));
+ lp_const_servicename(snum));
status = NT_STATUS_INSUFFICIENT_RESOURCES;
goto err_root_exit;
}
/* Invoke VFS make connection hook - this must be the first
filesystem operation that we do. */
- if (SMB_VFS_CONNECT(conn, lp_servicename(talloc_tos(), snum),
+ if (SMB_VFS_CONNECT(conn, lp_const_servicename(snum),
conn->session_info->unix_info->unix_name) < 0) {
DBG_WARNING("SMB_VFS_CONNECT for service '%s' at '%s' failed: %s\n",
- lp_servicename(talloc_tos(), snum), conn->connectpath,
+ lp_const_servicename(snum), conn->connectpath,
strerror(errno));
status = NT_STATUS_UNSUCCESSFUL;
goto err_root_exit;
/* Preexecs are done here as they might make the dir we are to ChDir
* to below */
/* execute any "root preexec = " line */
- if (*lp_root_preexec(talloc_tos(), snum)) {
- char *cmd = talloc_sub_advanced(talloc_tos(),
- lp_servicename(talloc_tos(), SNUM(conn)),
+ if (*lp_root_preexec(talloc_tos(), lp_sub, snum)) {
+ char *cmd = talloc_sub_full(talloc_tos(),
+ lp_const_servicename(SNUM(conn)),
conn->session_info->unix_info->unix_name,
conn->connectpath,
conn->session_info->unix_token->gid,
conn->session_info->unix_info->sanitized_username,
conn->session_info->info->domain_name,
- lp_root_preexec(talloc_tos(), snum));
+ lp_root_preexec(talloc_tos(), lp_sub, snum));
DEBUG(5,("cmd=%s\n",cmd));
ret = smbrun(cmd, NULL, NULL);
TALLOC_FREE(cmd);
}
/* USER Activites: */
- if (!change_to_user(conn, conn->vuid)) {
+ if (!change_to_user_and_service(conn, conn->vuid)) {
/* No point continuing if they fail the basic checks */
DEBUG(0,("Can't become connected user!\n"));
status = NT_STATUS_LOGON_FAILURE;
* to below */
/* execute any "preexec = " line */
- if (*lp_preexec(talloc_tos(), snum)) {
- char *cmd = talloc_sub_advanced(talloc_tos(),
- lp_servicename(talloc_tos(), SNUM(conn)),
+ if (*lp_preexec(talloc_tos(), lp_sub, snum)) {
+ char *cmd = talloc_sub_full(talloc_tos(),
+ lp_const_servicename(SNUM(conn)),
conn->session_info->unix_info->unix_name,
conn->connectpath,
conn->session_info->unix_token->gid,
conn->session_info->unix_info->sanitized_username,
conn->session_info->info->domain_name,
- lp_preexec(talloc_tos(), snum));
+ lp_preexec(talloc_tos(), lp_sub, snum));
ret = smbrun(cmd, NULL, NULL);
TALLOC_FREE(cmd);
if (ret != 0 && lp_preexec_close(snum)) {
/* ROOT Activites: */
/*
- * If widelinks are disallowed we need to canonicalise the connect
+ * Canonicalise the connect
* path here to ensure we don't have any symlinks in the
* connectpath. We will be checking all paths on this connection are
* below this directory. We must do this after the VFS init as we
* depend on the realpath() pointer in the vfs table. JRA.
*/
- if (!lp_widelinks(snum)) {
- if (!canonicalize_connect_path(conn)) {
- DEBUG(0, ("canonicalize_connect_path failed "
- "for service %s, path %s\n",
- lp_servicename(talloc_tos(), snum),
- conn->connectpath));
- status = NT_STATUS_BAD_NETWORK_NAME;
- goto err_root_exit;
- }
+ ok = canonicalize_connect_path(conn);
+ if (!ok) {
+ DBG_ERR("canonicalize_connect_path failed "
+ "for service %s, path %s\n",
+ lp_const_servicename(snum),
+ conn->connectpath);
+ status = NT_STATUS_BAD_NETWORK_NAME;
+ goto err_root_exit;
}
/* Add veto/hide lists */
if (!IS_IPC(conn) && !IS_PRINT(conn)) {
set_namearray( &conn->veto_list,
- lp_veto_files(talloc_tos(), snum));
+ lp_veto_files(talloc_tos(), lp_sub, snum));
set_namearray( &conn->hide_list,
- lp_hide_files(talloc_tos(), snum));
+ lp_hide_files(talloc_tos(), lp_sub, snum));
set_namearray( &conn->veto_oplock_list,
- lp_veto_oplock_files(talloc_tos(), snum));
+ lp_veto_oplock_files(talloc_tos(), lp_sub, snum));
set_namearray( &conn->aio_write_behind_list,
- lp_aio_write_behind(talloc_tos(), snum));
+ lp_aio_write_behind(talloc_tos(), lp_sub, snum));
}
smb_fname_cpath = synthetic_smb_fname(talloc_tos(),
conn->connectpath,
NULL,
NULL,
+ 0,
0);
if (smb_fname_cpath == NULL) {
status = NT_STATUS_NO_MEMORY;
if ((ret = SMB_VFS_STAT(conn, smb_fname_cpath)) != 0 ||
!S_ISDIR(smb_fname_cpath->st.st_ex_mode)) {
if (ret == 0 && !S_ISDIR(smb_fname_cpath->st.st_ex_mode)) {
- DEBUG(0,("'%s' is not a directory, when connecting to "
+ DBG_ERR("'%s' is not a directory, when connecting to "
"[%s]\n", conn->connectpath,
- lp_servicename(talloc_tos(), snum)));
+ lp_const_servicename(snum));
} else {
- DEBUG(0,("'%s' does not exist or permission denied "
+ DBG_ERR("'%s' does not exist or permission denied "
"when connecting to [%s] Error was %s\n",
conn->connectpath,
- lp_servicename(talloc_tos(), snum),
- strerror(errno) ));
+ lp_const_servicename(snum),
+ strerror(errno));
}
status = NT_STATUS_BAD_NETWORK_NAME;
goto err_root_exit;
conn->origpath = talloc_strdup(conn, conn->connectpath);
/* Figure out the characteristics of the underlying filesystem. This
- * assumes that all the filesystem mounted withing a share path have
+ * assumes that all the filesystem mounted within a share path have
* the same characteristics, which is likely but not guaranteed.
*/
talloc_tos()) );
dbgtext( "%s", srv_is_signing_active(xconn) ? "signed " : "");
dbgtext( "connect to service %s ",
- lp_servicename(talloc_tos(), snum) );
+ lp_const_servicename(snum) );
dbgtext( "initially as user %s ",
conn->session_info->unix_info->unix_name );
dbgtext( "(uid=%d, gid=%d) ", (int)effuid, (int)effgid );
dbgtext( "(pid %d)\n", (int)getpid() );
}
- return status;
+ conn->tcon_done = true;
+ return NT_STATUS_OK;
err_root_exit:
static connection_struct *make_connection_smb1(struct smb_request *req,
NTTIME now,
- int snum, struct user_struct *vuser,
+ 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;
*pstatus = make_connection_snum(req->xconn,
conn,
snum,
- vuser,
+ req->session,
pdev);
if (!NT_STATUS_IS_OK(*pstatus)) {
conn_free(conn);
return NULL;
}
- tcon->global->share_name = lp_servicename(tcon->global, SNUM(conn));
+ tcon->global->share_name = lp_servicename(tcon->global, lp_sub, SNUM(conn));
if (tcon->global->share_name == NULL) {
conn_free(conn);
TALLOC_FREE(tcon);
return NULL;
}
tcon->global->session_global_id =
- vuser->session->global->session_global_id;
+ req->session->global->session_global_id;
tcon->compat = talloc_move(tcon, &conn);
tcon->status = NT_STATUS_OK;
connection_struct *make_connection_smb2(struct smbd_smb2_request *req,
struct smbXsrv_tcon *tcon,
int snum,
- struct user_struct *vuser,
const char *pdev,
NTSTATUS *pstatus)
{
*pstatus = make_connection_snum(req->xconn,
conn,
snum,
- vuser,
+ req->session,
pdev);
if (!NT_STATUS_IS_OK(*pstatus)) {
conn_free(conn);
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;
- struct user_struct *vuser = NULL;
char *service = NULL;
fstring dev;
int snum = -1;
return NULL;
}
- vuser = get_valid_user_struct(sconn, vuid);
- if (!vuser) {
+ if (session == NULL) {
DEBUG(1,("make_connection: refusing to connect with "
"no session setup\n"));
*status = NT_STATUS_ACCESS_DENIED;
without too many getpwnam() lookups. This is particulary nasty for
winbind usernames, where the share name isn't the same as unix
username.
-
- The snum of the homes share is stored on the vuser at session setup
- time.
*/
if (strequal(service_in,HOMES_NAME)) {
- if (vuser->homes_snum == -1) {
+ if (session->homes_snum == -1) {
DEBUG(2, ("[homes] share not available for "
"this user because it was not found "
"or created at session setup "
DEBUG(5, ("making a connection to [homes] service "
"created at session setup time\n"));
return make_connection_smb1(req, now,
- vuser->homes_snum,
- vuser,
+ session->homes_snum,
dev, status);
- } else if ((vuser->homes_snum != -1)
+ } else if ((session->homes_snum != -1)
&& strequal(service_in,
- lp_servicename(talloc_tos(), vuser->homes_snum))) {
+ 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,
- vuser->homes_snum,
- vuser,
+ session->homes_snum,
dev, status);
}
}
/* Handle non-Dfs clients attempting connections to msdfs proxy */
- if (lp_host_msdfs() && (*lp_msdfs_proxy(talloc_tos(), snum) != '\0')) {
+ 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(), snum)));
+ 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, vuser,
+ return make_connection_smb1(req, now, snum,
dev, status);
}
{
char rootpath[2] = { '/', '\0'};
struct smb_filename root_fname = { .base_name = rootpath };
+ const struct loadparm_substitution *lp_sub =
+ loadparm_s3_global_substitution();
file_close_conn(conn);
- if (!IS_IPC(conn)) {
- dptr_closecnum(conn);
- }
-
change_to_root_user();
DEBUG(IS_IPC(conn)?3:2, ("%s (%s) closed connection to service %s\n",
get_remote_machine_name(),
tsocket_address_string(conn->sconn->remote_address,
talloc_tos()),
- lp_servicename(talloc_tos(), SNUM(conn))));
+ lp_const_servicename(SNUM(conn))));
/* make sure we leave the directory available for unmount */
vfs_ChDir(conn, &root_fname);
SMB_VFS_DISCONNECT(conn);
/* execute any "postexec = " line */
- if (*lp_postexec(talloc_tos(), SNUM(conn)) &&
- change_to_user(conn, vuid)) {
- char *cmd = talloc_sub_advanced(talloc_tos(),
- lp_servicename(talloc_tos(), SNUM(conn)),
+ if (*lp_postexec(talloc_tos(), lp_sub, SNUM(conn)) &&
+ change_to_user_and_service(conn, vuid)) {
+ char *cmd = talloc_sub_full(talloc_tos(),
+ lp_const_servicename(SNUM(conn)),
conn->session_info->unix_info->unix_name,
conn->connectpath,
conn->session_info->unix_token->gid,
conn->session_info->unix_info->sanitized_username,
conn->session_info->info->domain_name,
- lp_postexec(talloc_tos(), SNUM(conn)));
+ lp_postexec(talloc_tos(), lp_sub, SNUM(conn)));
smbrun(cmd, NULL, NULL);
TALLOC_FREE(cmd);
change_to_root_user();
change_to_root_user();
/* execute any "root postexec = " line */
- if (*lp_root_postexec(talloc_tos(), SNUM(conn))) {
- char *cmd = talloc_sub_advanced(talloc_tos(),
- lp_servicename(talloc_tos(), SNUM(conn)),
+ if (*lp_root_postexec(talloc_tos(), lp_sub, SNUM(conn))) {
+ char *cmd = talloc_sub_full(talloc_tos(),
+ lp_const_servicename(SNUM(conn)),
conn->session_info->unix_info->unix_name,
conn->connectpath,
conn->session_info->unix_token->gid,
conn->session_info->unix_info->sanitized_username,
conn->session_info->info->domain_name,
- lp_root_postexec(talloc_tos(), SNUM(conn)));
+ lp_root_postexec(talloc_tos(), lp_sub, SNUM(conn)));
smbrun(cmd, NULL, NULL);
TALLOC_FREE(cmd);
}