mirror of
https://github.com/samba-team/samba.git
synced 2025-03-27 22:50:26 +03:00
s3:smbd: let SMB_VFS_GETXATTRAT_SEND() do explicit impersonation
SMB_VFS_GETXATTRAT_SEND() gets passed a raw event context and the default implementation uses that as well a raw threadpool. Impersonation is done explicitly instead of by the tevent and pthreadpool wrappers. Signed-off-by: Ralph Boehme <slow@samba.org> Reviewed-by: Volker Lendecke <vl@samba.org> Reviewed-by: Stefan Metzmacher <metze@samba.org>
This commit is contained in:
parent
a62bc3f221
commit
7f7ce0ec2f
@ -873,14 +873,13 @@ struct skel_getxattrat_state {
|
||||
|
||||
static struct tevent_req *skel_getxattrat_send(
|
||||
TALLOC_CTX *mem_ctx,
|
||||
const struct smb_vfs_ev_glue *evg,
|
||||
struct tevent_context *ev,
|
||||
struct vfs_handle_struct *handle,
|
||||
files_struct *dir_fsp,
|
||||
const struct smb_filename *smb_fname,
|
||||
const char *xattr_name,
|
||||
size_t alloc_hint)
|
||||
{
|
||||
struct tevent_context *ev = smb_vfs_ev_glue_ev_ctx(evg);
|
||||
struct tevent_req *req = NULL;
|
||||
struct skel_getxattrat_state *state = NULL;
|
||||
|
||||
|
@ -1094,14 +1094,13 @@ static void skel_getxattrat_done(struct tevent_req *subreq);
|
||||
|
||||
static struct tevent_req *skel_getxattrat_send(
|
||||
TALLOC_CTX *mem_ctx,
|
||||
const struct smb_vfs_ev_glue *evg,
|
||||
struct tevent_context *ev,
|
||||
struct vfs_handle_struct *handle,
|
||||
files_struct *dir_fsp,
|
||||
const struct smb_filename *smb_fname,
|
||||
const char *xattr_name,
|
||||
size_t alloc_hint)
|
||||
{
|
||||
struct tevent_context *ev = smb_vfs_ev_glue_ev_ctx(evg);
|
||||
struct tevent_req *req = NULL;
|
||||
struct skel_getxattrat_state *state = NULL;
|
||||
struct tevent_req *subreq = NULL;
|
||||
@ -1113,7 +1112,7 @@ static struct tevent_req *skel_getxattrat_send(
|
||||
}
|
||||
|
||||
subreq = SMB_VFS_NEXT_GETXATTRAT_SEND(state,
|
||||
evg,
|
||||
ev,
|
||||
handle,
|
||||
dir_fsp,
|
||||
smb_fname,
|
||||
|
@ -969,7 +969,7 @@ struct vfs_fn_pointers {
|
||||
size_t size);
|
||||
struct tevent_req *(*getxattrat_send_fn)(
|
||||
TALLOC_CTX *mem_ctx,
|
||||
const struct smb_vfs_ev_glue *evg,
|
||||
struct tevent_context *ev,
|
||||
struct vfs_handle_struct *handle,
|
||||
files_struct *dir_fsp,
|
||||
const struct smb_filename *smb_fname,
|
||||
@ -1481,7 +1481,7 @@ ssize_t smb_vfs_call_getxattr(struct vfs_handle_struct *handle,
|
||||
size_t size);
|
||||
struct tevent_req *smb_vfs_call_getxattrat_send(
|
||||
TALLOC_CTX *mem_ctx,
|
||||
const struct smb_vfs_ev_glue *evg,
|
||||
struct tevent_context *ev,
|
||||
struct vfs_handle_struct *handle,
|
||||
files_struct *dir_fsp,
|
||||
const struct smb_filename *smb_fname,
|
||||
@ -1910,7 +1910,7 @@ ssize_t vfs_not_implemented_getxattr(vfs_handle_struct *handle,
|
||||
size_t size);
|
||||
struct tevent_req *vfs_not_implemented_getxattrat_send(
|
||||
TALLOC_CTX *mem_ctx,
|
||||
const struct smb_vfs_ev_glue *evg,
|
||||
struct tevent_context *ev,
|
||||
struct vfs_handle_struct *handle,
|
||||
files_struct *dir_fsp,
|
||||
const struct smb_filename *smb_fname,
|
||||
|
@ -515,18 +515,18 @@
|
||||
#define SMB_VFS_NEXT_GETXATTR(handle,smb_fname,name,value,size) \
|
||||
smb_vfs_call_getxattr((handle)->next,(smb_fname),(name),(value),(size))
|
||||
|
||||
#define SMB_VFS_GETXATTRAT_SEND(mem_ctx,evg,dir_fsp,smb_fname, \
|
||||
#define SMB_VFS_GETXATTRAT_SEND(mem_ctx,ev,dir_fsp,smb_fname, \
|
||||
xattr_name, alloc_hint) \
|
||||
smb_vfs_call_getxattrat_send((mem_ctx),(evg), \
|
||||
smb_vfs_call_getxattrat_send((mem_ctx),(ev), \
|
||||
(dir_fsp)->conn->vfs_handles, \
|
||||
(dir_fsp),(smb_fname),(xattr_name), \
|
||||
(alloc_hint))
|
||||
#define SMB_VFS_GETXATTRAT_RECV(req, aio_state, mem_ctx, xattr_value) \
|
||||
smb_vfs_call_getxattrat_recv((req),(aio_state),(mem_ctx),(xattr_value))
|
||||
|
||||
#define SMB_VFS_NEXT_GETXATTRAT_SEND(mem_ctx,evg,handle,dir_fsp,smb_fname, \
|
||||
#define SMB_VFS_NEXT_GETXATTRAT_SEND(mem_ctx,ev,handle,dir_fsp,smb_fname, \
|
||||
xattr_name,alloc_hint) \
|
||||
smb_vfs_call_getxattrat_send((mem_ctx),(evg), \
|
||||
smb_vfs_call_getxattrat_send((mem_ctx),(ev), \
|
||||
(handle)->next, \
|
||||
(dir_fsp), (smb_fname),(xattr_name), \
|
||||
(alloc_hint))
|
||||
|
@ -1493,7 +1493,7 @@ struct vfswrap_get_dos_attributes_state {
|
||||
struct vfs_aio_state aio_state;
|
||||
connection_struct *conn;
|
||||
TALLOC_CTX *mem_ctx;
|
||||
const struct smb_vfs_ev_glue *evg;
|
||||
struct tevent_context *ev;
|
||||
files_struct *dir_fsp;
|
||||
struct smb_filename *smb_fname;
|
||||
uint32_t dosmode;
|
||||
@ -1509,7 +1509,7 @@ static struct tevent_req *vfswrap_get_dos_attributes_send(
|
||||
files_struct *dir_fsp,
|
||||
struct smb_filename *smb_fname)
|
||||
{
|
||||
struct tevent_context *ev = smb_vfs_ev_glue_ev_ctx(evg);
|
||||
struct tevent_context *ev = dir_fsp->conn->sconn->raw_ev_ctx;
|
||||
struct tevent_req *req = NULL;
|
||||
struct tevent_req *subreq = NULL;
|
||||
struct vfswrap_get_dos_attributes_state *state = NULL;
|
||||
@ -1523,13 +1523,13 @@ static struct tevent_req *vfswrap_get_dos_attributes_send(
|
||||
*state = (struct vfswrap_get_dos_attributes_state) {
|
||||
.conn = dir_fsp->conn,
|
||||
.mem_ctx = mem_ctx,
|
||||
.evg = evg,
|
||||
.ev = ev,
|
||||
.dir_fsp = dir_fsp,
|
||||
.smb_fname = smb_fname,
|
||||
};
|
||||
|
||||
subreq = SMB_VFS_GETXATTRAT_SEND(state,
|
||||
evg,
|
||||
ev,
|
||||
dir_fsp,
|
||||
smb_fname,
|
||||
SAMBA_XATTR_DOS_ATTRIB,
|
||||
@ -1562,8 +1562,6 @@ static void vfswrap_get_dos_attributes_getxattr_done(struct tevent_req *subreq)
|
||||
&blob.data);
|
||||
TALLOC_FREE(subreq);
|
||||
if (xattr_size == -1) {
|
||||
const struct smb_vfs_ev_glue *root_evg = NULL;
|
||||
|
||||
status = map_nt_error_from_unix(state->aio_state.error);
|
||||
|
||||
if (state->as_root) {
|
||||
@ -1576,14 +1574,15 @@ static void vfswrap_get_dos_attributes_getxattr_done(struct tevent_req *subreq)
|
||||
}
|
||||
|
||||
state->as_root = true;
|
||||
root_evg = smb_vfs_ev_glue_get_root_glue(state->evg);
|
||||
|
||||
become_root();
|
||||
subreq = SMB_VFS_GETXATTRAT_SEND(state,
|
||||
root_evg,
|
||||
state->ev,
|
||||
state->dir_fsp,
|
||||
state->smb_fname,
|
||||
SAMBA_XATTR_DOS_ATTRIB,
|
||||
sizeof(fstring));
|
||||
unbecome_root();
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return;
|
||||
}
|
||||
@ -2903,13 +2902,22 @@ static ssize_t vfswrap_getxattr(struct vfs_handle_struct *handle,
|
||||
}
|
||||
|
||||
struct vfswrap_getxattrat_state {
|
||||
int dirfd;
|
||||
char *name;
|
||||
size_t xattr_bufsize;
|
||||
const char *xattr_name;
|
||||
ssize_t xattr_size;
|
||||
uint8_t *xattr_value;
|
||||
struct tevent_context *ev;
|
||||
files_struct *dir_fsp;
|
||||
const struct smb_filename *smb_fname;
|
||||
struct tevent_req *req;
|
||||
|
||||
/*
|
||||
* The following variables are talloced off "state" which is protected
|
||||
* by a destructor and thus are guaranteed to be safe to be used in the
|
||||
* job function in the worker thread.
|
||||
*/
|
||||
char *name;
|
||||
const char *xattr_name;
|
||||
uint8_t *xattr_value;
|
||||
struct security_unix_token *token;
|
||||
|
||||
ssize_t xattr_size;
|
||||
struct vfs_aio_state vfs_aio_state;
|
||||
SMBPROFILE_BYTES_ASYNC_STATE(profile_bytes);
|
||||
};
|
||||
@ -2920,23 +2928,26 @@ static int vfswrap_getxattrat_state_destructor(
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void vfswrap_getxattrat_do(void *private_data);
|
||||
static void vfswrap_getxattrat_do_sync(struct tevent_req *req);
|
||||
static void vfswrap_getxattrat_do_async(void *private_data);
|
||||
static void vfswrap_getxattrat_done(struct tevent_req *subreq);
|
||||
|
||||
static struct tevent_req *vfswrap_getxattrat_send(
|
||||
TALLOC_CTX *mem_ctx,
|
||||
const struct smb_vfs_ev_glue *evg,
|
||||
struct tevent_context *ev,
|
||||
struct vfs_handle_struct *handle,
|
||||
files_struct *dir_fsp,
|
||||
const struct smb_filename *smb_fname,
|
||||
const char *xattr_name,
|
||||
size_t alloc_hint)
|
||||
{
|
||||
struct tevent_context *ev = smb_vfs_ev_glue_ev_ctx(evg);
|
||||
struct pthreadpool_tevent *tp = smb_vfs_ev_glue_tp_chdir_safe(evg);
|
||||
struct tevent_req *req = NULL;
|
||||
struct tevent_req *subreq = NULL;
|
||||
struct vfswrap_getxattrat_state *state = NULL;
|
||||
size_t max_threads = 0;
|
||||
bool have_per_thread_cwd = false;
|
||||
bool have_per_thread_creds = false;
|
||||
bool do_async = false;
|
||||
|
||||
req = tevent_req_create(mem_ctx, &state,
|
||||
struct vfswrap_getxattrat_state);
|
||||
@ -2944,19 +2955,49 @@ static struct tevent_req *vfswrap_getxattrat_send(
|
||||
return NULL;
|
||||
}
|
||||
*state = (struct vfswrap_getxattrat_state) {
|
||||
.dirfd = dir_fsp->fh->fd,
|
||||
.xattr_bufsize = alloc_hint,
|
||||
.ev = ev,
|
||||
.dir_fsp = dir_fsp,
|
||||
.smb_fname = smb_fname,
|
||||
.req = req,
|
||||
};
|
||||
|
||||
max_threads = pthreadpool_tevent_max_threads(dir_fsp->conn->sconn->pool);
|
||||
if (max_threads >= 1) {
|
||||
/*
|
||||
* We need a non sync threadpool!
|
||||
*/
|
||||
have_per_thread_cwd = per_thread_cwd_supported();
|
||||
}
|
||||
#ifdef HAVE_LINUX_THREAD_CREDENTIALS
|
||||
have_per_thread_creds = true;
|
||||
#endif
|
||||
if (have_per_thread_cwd && have_per_thread_creds) {
|
||||
do_async = true;
|
||||
}
|
||||
|
||||
SMBPROFILE_BYTES_ASYNC_START(syscall_asys_getxattrat, profile_p,
|
||||
state->profile_bytes, 0);
|
||||
|
||||
if (state->dirfd == -1) {
|
||||
if (dir_fsp->fh->fd == -1) {
|
||||
DBG_ERR("Need a valid directory fd\n");
|
||||
tevent_req_error(req, EINVAL);
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
if (alloc_hint > 0) {
|
||||
state->xattr_value = talloc_zero_array(state,
|
||||
uint8_t,
|
||||
alloc_hint);
|
||||
if (tevent_req_nomem(state->xattr_value, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
}
|
||||
|
||||
if (!do_async) {
|
||||
vfswrap_getxattrat_do_sync(req);
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
/*
|
||||
* Now allocate all parameters from a memory context that won't go away
|
||||
* no matter what. These paremeters will get used in threads and we
|
||||
@ -2974,22 +3015,32 @@ static struct tevent_req *vfswrap_getxattrat_send(
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
if (state->xattr_bufsize > 0) {
|
||||
state->xattr_value = talloc_zero_array(state,
|
||||
uint8_t,
|
||||
state->xattr_bufsize);
|
||||
if (tevent_req_nomem(state->xattr_value, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
/*
|
||||
* This is a hot codepath so at first glance one might think we should
|
||||
* somehow optimize away the token allocation and do a
|
||||
* talloc_reference() or similar black magic instead. But due to the
|
||||
* talloc_stackframe pool per SMB2 request this should be a simple copy
|
||||
* without a malloc in most cases.
|
||||
*/
|
||||
if (geteuid() == sec_initial_uid()) {
|
||||
state->token = root_unix_token(state);
|
||||
} else {
|
||||
state->token = copy_unix_token(
|
||||
state,
|
||||
dir_fsp->conn->session_info->unix_token);
|
||||
}
|
||||
if (tevent_req_nomem(state->token, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
SMBPROFILE_BYTES_ASYNC_SET_IDLE(state->profile_bytes);
|
||||
|
||||
subreq = pthreadpool_tevent_job_send(state,
|
||||
ev,
|
||||
tp,
|
||||
vfswrap_getxattrat_do,
|
||||
state);
|
||||
subreq = pthreadpool_tevent_job_send(
|
||||
state,
|
||||
ev,
|
||||
dir_fsp->conn->sconn->raw_thread_pool,
|
||||
vfswrap_getxattrat_do_async,
|
||||
state);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
@ -3000,7 +3051,43 @@ static struct tevent_req *vfswrap_getxattrat_send(
|
||||
return req;
|
||||
}
|
||||
|
||||
static void vfswrap_getxattrat_do(void *private_data)
|
||||
static void vfswrap_getxattrat_do_sync(struct tevent_req *req)
|
||||
{
|
||||
struct vfswrap_getxattrat_state *state = talloc_get_type_abort(
|
||||
req, struct vfswrap_getxattrat_state);
|
||||
char *path = NULL;
|
||||
char *tofree = NULL;
|
||||
char pathbuf[PATH_MAX+1];
|
||||
size_t pathlen;
|
||||
int err;
|
||||
|
||||
pathlen = full_path_tos(state->dir_fsp->fsp_name->base_name,
|
||||
state->smb_fname->base_name,
|
||||
pathbuf,
|
||||
sizeof(pathbuf),
|
||||
&path,
|
||||
&tofree);
|
||||
if (pathlen == -1) {
|
||||
tevent_req_error(req, ENOMEM);
|
||||
return;
|
||||
}
|
||||
|
||||
state->xattr_size = getxattr(path,
|
||||
state->xattr_name,
|
||||
state->xattr_value,
|
||||
talloc_array_length(state->xattr_value));
|
||||
err = errno;
|
||||
TALLOC_FREE(tofree);
|
||||
if (state->xattr_size == -1) {
|
||||
tevent_req_error(req, err);
|
||||
return;
|
||||
}
|
||||
|
||||
tevent_req_done(req);
|
||||
return;
|
||||
}
|
||||
|
||||
static void vfswrap_getxattrat_do_async(void *private_data)
|
||||
{
|
||||
struct vfswrap_getxattrat_state *state = talloc_get_type_abort(
|
||||
private_data, struct vfswrap_getxattrat_state);
|
||||
@ -3014,14 +3101,22 @@ static void vfswrap_getxattrat_do(void *private_data)
|
||||
/*
|
||||
* Here we simulate a getxattrat()
|
||||
* call using fchdir();getxattr()
|
||||
*
|
||||
* We don't need to revert the directory
|
||||
* change as pthreadpool_tevent wrapper
|
||||
* handlers that.
|
||||
*/
|
||||
SMB_ASSERT(pthreadpool_tevent_current_job_per_thread_cwd());
|
||||
|
||||
ret = fchdir(state->dirfd);
|
||||
per_thread_cwd_activate();
|
||||
|
||||
/* Become the correct credential on this thread. */
|
||||
ret = set_thread_credentials(state->token->uid,
|
||||
state->token->gid,
|
||||
(size_t)state->token->ngroups,
|
||||
state->token->groups);
|
||||
if (ret != 0) {
|
||||
state->xattr_size = -1;
|
||||
state->vfs_aio_state.error = errno;
|
||||
goto end_profile;
|
||||
}
|
||||
|
||||
ret = fchdir(state->dir_fsp->fh->fd);
|
||||
if (ret == -1) {
|
||||
state->xattr_size = -1;
|
||||
state->vfs_aio_state.error = errno;
|
||||
@ -3031,7 +3126,7 @@ static void vfswrap_getxattrat_do(void *private_data)
|
||||
state->xattr_size = getxattr(state->name,
|
||||
state->xattr_name,
|
||||
state->xattr_value,
|
||||
state->xattr_bufsize);
|
||||
talloc_array_length(state->xattr_value));
|
||||
if (state->xattr_size == -1) {
|
||||
state->vfs_aio_state.error = errno;
|
||||
}
|
||||
@ -3049,12 +3144,34 @@ static void vfswrap_getxattrat_done(struct tevent_req *subreq)
|
||||
struct vfswrap_getxattrat_state *state = tevent_req_data(
|
||||
req, struct vfswrap_getxattrat_state);
|
||||
int ret;
|
||||
bool ok;
|
||||
|
||||
/*
|
||||
* Make sure we run as the user again
|
||||
*/
|
||||
ok = change_to_user(state->dir_fsp->conn,
|
||||
state->dir_fsp->vuid);
|
||||
if (!ok) {
|
||||
smb_panic("Can't change to user");
|
||||
return;
|
||||
}
|
||||
|
||||
ret = pthreadpool_tevent_job_recv(subreq);
|
||||
TALLOC_FREE(subreq);
|
||||
SMBPROFILE_BYTES_ASYNC_END(state->profile_bytes);
|
||||
talloc_set_destructor(state, NULL);
|
||||
if (tevent_req_error(req, ret)) {
|
||||
if (ret != 0) {
|
||||
if (ret != EAGAIN) {
|
||||
tevent_req_error(req, ret);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* If we get EAGAIN from pthreadpool_tevent_job_recv() this
|
||||
* means the lower level pthreadpool failed to create a new
|
||||
* thread. Fallback to sync processing in that case to allow
|
||||
* some progress for the client.
|
||||
*/
|
||||
vfswrap_getxattrat_do_sync(req);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2523,14 +2523,13 @@ static void smb_full_audit_getxattrat_done(struct tevent_req *subreq);
|
||||
|
||||
static struct tevent_req *smb_full_audit_getxattrat_send(
|
||||
TALLOC_CTX *mem_ctx,
|
||||
const struct smb_vfs_ev_glue *evg,
|
||||
struct tevent_context *ev,
|
||||
struct vfs_handle_struct *handle,
|
||||
files_struct *dir_fsp,
|
||||
const struct smb_filename *smb_fname,
|
||||
const char *xattr_name,
|
||||
size_t alloc_hint)
|
||||
{
|
||||
struct tevent_context *ev = smb_vfs_ev_glue_ev_ctx(evg);
|
||||
struct tevent_req *req = NULL;
|
||||
struct tevent_req *subreq = NULL;
|
||||
struct smb_full_audit_getxattrat_state *state = NULL;
|
||||
@ -2555,7 +2554,7 @@ static struct tevent_req *smb_full_audit_getxattrat_send(
|
||||
};
|
||||
|
||||
subreq = SMB_VFS_NEXT_GETXATTRAT_SEND(state,
|
||||
evg,
|
||||
ev,
|
||||
handle,
|
||||
dir_fsp,
|
||||
smb_fname,
|
||||
|
@ -877,14 +877,13 @@ struct vfs_not_implemented_getxattrat_state {
|
||||
|
||||
struct tevent_req *vfs_not_implemented_getxattrat_send(
|
||||
TALLOC_CTX *mem_ctx,
|
||||
const struct smb_vfs_ev_glue *evg,
|
||||
struct tevent_context *ev,
|
||||
struct vfs_handle_struct *handle,
|
||||
files_struct *dir_fsp,
|
||||
const struct smb_filename *smb_fname,
|
||||
const char *xattr_name,
|
||||
size_t alloc_hint)
|
||||
{
|
||||
struct tevent_context *ev = smb_vfs_ev_glue_ev_ctx(evg);
|
||||
struct tevent_req *req = NULL;
|
||||
struct vfs_not_implemented_getxattrat_state *state = NULL;
|
||||
|
||||
|
@ -2456,14 +2456,13 @@ static void smb_time_audit_getxattrat_done(struct tevent_req *subreq);
|
||||
|
||||
static struct tevent_req *smb_time_audit_getxattrat_send(
|
||||
TALLOC_CTX *mem_ctx,
|
||||
const struct smb_vfs_ev_glue *evg,
|
||||
struct tevent_context *ev,
|
||||
struct vfs_handle_struct *handle,
|
||||
files_struct *dir_fsp,
|
||||
const struct smb_filename *smb_fname,
|
||||
const char *xattr_name,
|
||||
size_t alloc_hint)
|
||||
{
|
||||
struct tevent_context *ev = smb_vfs_ev_glue_ev_ctx(evg);
|
||||
struct tevent_req *req = NULL;
|
||||
struct tevent_req *subreq = NULL;
|
||||
struct smb_time_audit_getxattrat_state *state = NULL;
|
||||
@ -2480,7 +2479,7 @@ static struct tevent_req *smb_time_audit_getxattrat_send(
|
||||
};
|
||||
|
||||
subreq = SMB_VFS_NEXT_GETXATTRAT_SEND(state,
|
||||
evg,
|
||||
ev,
|
||||
handle,
|
||||
dir_fsp,
|
||||
smb_fname,
|
||||
|
@ -112,14 +112,13 @@ struct xattr_tdb_getxattrat_state {
|
||||
|
||||
static struct tevent_req *xattr_tdb_getxattrat_send(
|
||||
TALLOC_CTX *mem_ctx,
|
||||
const struct smb_vfs_ev_glue *evg,
|
||||
struct tevent_context *ev,
|
||||
struct vfs_handle_struct *handle,
|
||||
files_struct *dir_fsp,
|
||||
const struct smb_filename *smb_fname,
|
||||
const char *xattr_name,
|
||||
size_t alloc_hint)
|
||||
{
|
||||
struct tevent_context *ev = smb_vfs_ev_glue_ev_ctx(evg);
|
||||
struct tevent_req *req = NULL;
|
||||
struct xattr_tdb_getxattrat_state *state = NULL;
|
||||
struct smb_filename *cwd = NULL;
|
||||
|
@ -240,7 +240,6 @@ struct smbd_smb2_query_directory_state {
|
||||
bool async_dosmode;
|
||||
bool async_ask_sharemode;
|
||||
int last_entry_off;
|
||||
struct pthreadpool_tevent *tp_chdir_safe;
|
||||
size_t max_async_dosmode_active;
|
||||
uint32_t async_dosmode_active;
|
||||
bool done;
|
||||
@ -279,7 +278,6 @@ static struct tevent_req *smbd_smb2_query_directory_send(TALLOC_CTX *mem_ctx,
|
||||
}
|
||||
state->evg = conn->user_vfs_evg;
|
||||
state->ev = ev;
|
||||
state->tp_chdir_safe = smb_vfs_ev_glue_tp_chdir_safe(state->evg);
|
||||
state->fsp = fsp;
|
||||
state->smb2req = smb2req;
|
||||
state->in_output_buffer_length = in_output_buffer_length;
|
||||
@ -519,7 +517,7 @@ static struct tevent_req *smbd_smb2_query_directory_send(TALLOC_CTX *mem_ctx,
|
||||
if (state->async_dosmode) {
|
||||
size_t max_threads;
|
||||
|
||||
max_threads = pthreadpool_tevent_max_threads(state->tp_chdir_safe);
|
||||
max_threads = pthreadpool_tevent_max_threads(conn->sconn->raw_thread_pool);
|
||||
|
||||
state->max_async_dosmode_active = lp_smbd_max_async_dosmode(
|
||||
SNUM(conn));
|
||||
@ -664,7 +662,7 @@ static bool smb2_query_directory_next_entry(struct tevent_req *req)
|
||||
state->async_dosmode_active++;
|
||||
|
||||
outstanding_aio = pthreadpool_tevent_queued_jobs(
|
||||
state->tp_chdir_safe);
|
||||
state->fsp->conn->sconn->raw_thread_pool);
|
||||
|
||||
if (outstanding_aio > state->max_async_dosmode_active) {
|
||||
stop = true;
|
||||
|
@ -3539,7 +3539,7 @@ static void smb_vfs_call_getxattrat_done(struct tevent_req *subreq);
|
||||
|
||||
struct tevent_req *smb_vfs_call_getxattrat_send(
|
||||
TALLOC_CTX *mem_ctx,
|
||||
const struct smb_vfs_ev_glue *evg,
|
||||
struct tevent_context *ev,
|
||||
struct vfs_handle_struct *handle,
|
||||
files_struct *dir_fsp,
|
||||
const struct smb_filename *smb_fname,
|
||||
@ -3549,7 +3549,6 @@ struct tevent_req *smb_vfs_call_getxattrat_send(
|
||||
struct tevent_req *req = NULL;
|
||||
struct smb_vfs_call_getxattrat_state *state = NULL;
|
||||
struct tevent_req *subreq = NULL;
|
||||
bool ok;
|
||||
|
||||
req = tevent_req_create(mem_ctx, &state,
|
||||
struct smb_vfs_call_getxattrat_state);
|
||||
@ -3560,24 +3559,18 @@ struct tevent_req *smb_vfs_call_getxattrat_send(
|
||||
VFS_FIND(getxattrat_send);
|
||||
state->recv_fn = handle->fns->getxattrat_recv_fn;
|
||||
|
||||
ok = smb_vfs_ev_glue_push_use(evg, req);
|
||||
if (!ok) {
|
||||
tevent_req_error(req, EIO);
|
||||
return tevent_req_post(req, evg->return_ev);
|
||||
}
|
||||
|
||||
subreq = handle->fns->getxattrat_send_fn(mem_ctx,
|
||||
evg->next_glue,
|
||||
ev,
|
||||
handle,
|
||||
dir_fsp,
|
||||
smb_fname,
|
||||
xattr_name,
|
||||
alloc_hint);
|
||||
smb_vfs_ev_glue_pop_use(evg);
|
||||
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return tevent_req_post(req, evg->return_ev);
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
tevent_req_defer_callback(req, ev);
|
||||
|
||||
tevent_req_set_callback(subreq, smb_vfs_call_getxattrat_done, req);
|
||||
return req;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user