1
0
mirror of https://github.com/samba-team/samba.git synced 2025-02-02 09:47:23 +03:00

smbd: add create_conn_struct_tos[_cwd]() helper functions

This makes it more obvious that the returned connection_struct
is only temporary (and allocated on talloc_tos()!)
It will never allow async requests on a long term
tevent context! So we create a short term event context.

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
This commit is contained in:
Stefan Metzmacher 2018-05-24 15:59:43 +02:00
parent ebae5e055c
commit 66bc2c4332
2 changed files with 141 additions and 0 deletions

View File

@ -448,6 +448,131 @@ NTSTATUS create_conn_struct_cwd(TALLOC_CTX *ctx,
return NT_STATUS_OK;
}
static int conn_struct_tos_destructor(struct conn_struct_tos *c)
{
if (c->oldcwd_fname != NULL) {
vfs_ChDir(c->conn, c->oldcwd_fname);
TALLOC_FREE(c->oldcwd_fname);
}
SMB_VFS_DISCONNECT(c->conn);
conn_free(c->conn);
return 0;
}
/********************************************************
Fake up a connection struct for the VFS layer, for use in
applications (such as the python bindings), that do not want the
global working directory changed under them.
SMB_VFS_CONNECT requires root privileges.
This temporary uses become_root() and unbecome_root().
But further impersonation has to be cone by the caller.
*********************************************************/
NTSTATUS create_conn_struct_tos(struct messaging_context *msg,
int snum,
const char *path,
const struct auth_session_info *session_info,
struct conn_struct_tos **_c)
{
struct conn_struct_tos *c = NULL;
struct tevent_context *ev = NULL;
NTSTATUS status;
*_c = NULL;
c = talloc_zero(talloc_tos(), struct conn_struct_tos);
if (c == NULL) {
return NT_STATUS_NO_MEMORY;
}
ev = samba_tevent_context_init(c);
if (ev == NULL) {
TALLOC_FREE(c);
return NT_STATUS_NO_MEMORY;
}
status = create_conn_struct(c,
ev,
msg,
&c->conn,
snum,
path,
session_info);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(c);
return status;
}
talloc_steal(c, c->conn);
talloc_set_destructor(c, conn_struct_tos_destructor);
*_c = c;
return NT_STATUS_OK;
}
/********************************************************
Fake up a connection struct for the VFS layer.
Note: this performs a vfs connect and CHANGES CWD !!!! JRA.
See also the comment for create_conn_struct_tos() above!
The CWD change is reverted by the destructor of
conn_struct_tos when the current talloc_tos() is destroyed.
*********************************************************/
NTSTATUS create_conn_struct_tos_cwd(struct messaging_context *msg,
int snum,
const char *path,
const struct auth_session_info *session_info,
struct conn_struct_tos **_c)
{
struct conn_struct_tos *c = NULL;
struct smb_filename smb_fname_connectpath = {0};
NTSTATUS status;
*_c = NULL;
status = create_conn_struct_tos(msg,
snum,
path,
session_info,
&c);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
/*
* Windows seems to insist on doing trans2getdfsreferral() calls on
* the IPC$ share as the anonymous user. If we try to chdir as that
* user we will fail.... WTF ? JRA.
*/
c->oldcwd_fname = vfs_GetWd(c, c->conn);
if (c->oldcwd_fname == NULL) {
status = map_nt_error_from_unix(errno);
DEBUG(3, ("vfs_GetWd failed: %s\n", strerror(errno)));
TALLOC_FREE(c);
return status;
}
smb_fname_connectpath = (struct smb_filename) {
.base_name = c->conn->connectpath
};
if (vfs_ChDir(c->conn, &smb_fname_connectpath) != 0) {
status = map_nt_error_from_unix(errno);
DBG_NOTICE("Can't ChDir to new conn path %s. "
"Error was %s\n",
c->conn->connectpath, strerror(errno));
TALLOC_FREE(c->oldcwd_fname);
TALLOC_FREE(c);
return status;
}
*_c = c;
return NT_STATUS_OK;
}
static void shuffle_strlist(char **list, int count)
{
int i;

View File

@ -514,6 +514,22 @@ NTSTATUS create_conn_struct_cwd(TALLOC_CTX *ctx,
const char *path,
const struct auth_session_info *session_info,
struct smb_filename **poldcwd_fname);
struct connection_struct;
struct smb_filename;
struct conn_struct_tos {
struct connection_struct *conn;
struct smb_filename *oldcwd_fname;
};
NTSTATUS create_conn_struct_tos(struct messaging_context *msg,
int snum,
const char *path,
const struct auth_session_info *session_info,
struct conn_struct_tos **_c);
NTSTATUS create_conn_struct_tos_cwd(struct messaging_context *msg,
int snum,
const char *path,
const struct auth_session_info *session_info,
struct conn_struct_tos **_c);
/* The following definitions come from smbd/negprot.c */