The branch, master has been updated
       via  1f0dd8f talloc: Fix CID 1373619 Unchecked return value
       via  1ecea45 messaging: Fix CID 1373622 Extra high-order bits
       via  978c379 messaging: Fix CID 1373625 Unused value
       via  a04a096 pthreadpool: Fix CID 1373620 Unchecked return value from 
library
       via  6de421b talloc: Fix CID 1373621 Unchecked return value
       via  1e676a6 pthreadpool: Rearrange locks a bit
       via  9f6fe5e s3: winbind: Ensure we store name2sid with the correct 
cache sequence number.
       via  3b97211 examples: Add smb2mount
      from  8577456 support volfile fetch from multiple glusterd nodes

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 1f0dd8f698e7bd74846d3b4c36a5c3dac2098051
Author: Volker Lendecke <v...@samba.org>
Date:   Wed Oct 12 12:27:56 2016 +0200

    talloc: Fix CID 1373619 Unchecked return value
    
    Signed-off-by: Volker Lendecke <v...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>
    
    Autobuild-User(master): Jeremy Allison <j...@samba.org>
    Autobuild-Date(master): Sat Oct 15 01:28:02 CEST 2016 on sn-devel-144

commit 1ecea454e55ccd683f7b098181917ddeed203ebe
Author: Volker Lendecke <v...@samba.org>
Date:   Wed Oct 12 12:25:39 2016 +0200

    messaging: Fix CID 1373622 Extra high-order bits
    
    Signed-off-by: Volker Lendecke <v...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit 978c3792b55ddbc2b3b9da922d11d2797909731f
Author: Volker Lendecke <v...@samba.org>
Date:   Wed Oct 12 12:21:36 2016 +0200

    messaging: Fix CID 1373625 Unused value
    
    Hmm. I wonder how that cut&paste happened...
    
    Signed-off-by: Volker Lendecke <v...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit a04a096783ea083abafb7f943074be9b59ebd950
Author: Volker Lendecke <v...@samba.org>
Date:   Wed Oct 12 12:20:00 2016 +0200

    pthreadpool: Fix CID 1373620 Unchecked return value from library
    
    Signed-off-by: Volker Lendecke <v...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit 6de421b299d8edd3f5e3365e143010becda474f9
Author: Volker Lendecke <v...@samba.org>
Date:   Wed Oct 12 12:18:11 2016 +0200

    talloc: Fix CID 1373621 Unchecked return value
    
    Signed-off-by: Volker Lendecke <v...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit 1e676a6e2c71ceb1f9bf693d94b750c1ebcb95dd
Author: Volker Lendecke <v...@samba.org>
Date:   Wed Oct 12 12:12:28 2016 +0200

    pthreadpool: Rearrange locks a bit
    
    Coverity ID 1373624 says we have a deadlock between pthreadpool_prepare and
    pthreadpool_destroy. Coverity somehow misses that pthreadpool_free unlocks
    pool->mutex, so I think this is a false positive. Nevertheless this 
re-arranges
    the code a bit for more clarity, hoping that Coverity now can better track 
the
    locks and unlocks. Also, the human reader might have to jump between 
routines a
    bit less.
    
    Signed-off-by: Volker Lendecke <v...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit 9f6fe5e2c54870abfff48c8a9d96e21bfec2425f
Author: Jeremy Allison <j...@samba.org>
Date:   Thu Oct 13 15:01:58 2016 -0700

    s3: winbind: Ensure we store name2sid with the correct cache sequence 
number.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=11259
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Uri Simchoni <u...@samba.org>

commit 3b97211d1854b208afae711cc8804dd28ff1e532
Author: Volker Lendecke <v...@samba.org>
Date:   Wed Oct 12 15:02:45 2016 +0200

    examples: Add smb2mount
    
    This is an incomplete playground to add a fuse client based on
    the Samba-internal libsmb interfaces.
    
    There's a few fuse smb clients out there, but they all suffer from
    Samba not exporting the async internal libsmb interfaces.
    
    We don't export those with an API, because we believe we need the ability
    to mess with those interfaces. This is an attempt to create a fully
    asynchronous user-space fuse client file system that might make it
    easier to mess with fancy SMB features than it would be possible in
    a kernel client.
    
    Signed-off-by: Volker Lendecke <v...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Ralph Böhme <s...@samba.org>

-----------------------------------------------------------------------

Summary of changes:
 examples/fuse/README                               |    7 +
 examples/fuse/clifuse.c                            | 1473 ++++++++++++++++++++
 source3/lib/sys_popen.h => examples/fuse/clifuse.h |   13 +-
 examples/fuse/smb2mount.c                          |  167 +++
 examples/fuse/wscript                              |   14 +
 examples/fuse/wscript_build                        |    7 +
 lib/talloc/testsuite.c                             |   19 +-
 source3/lib/messages_dgm.c                         |    2 +-
 source3/lib/pthreadpool/pthreadpool.c              |   30 +-
 source3/lib/pthreadpool/tests.c                    |    4 +-
 source3/winbindd/winbindd_cache.c                  |    6 +
 source3/wscript_build                              |    1 +
 source4/lib/messaging/tests/messaging.c            |    1 +
 wscript                                            |    2 +
 14 files changed, 1719 insertions(+), 27 deletions(-)
 create mode 100644 examples/fuse/README
 create mode 100644 examples/fuse/clifuse.c
 copy source3/lib/sys_popen.h => examples/fuse/clifuse.h (76%)
 create mode 100644 examples/fuse/smb2mount.c
 create mode 100644 examples/fuse/wscript
 create mode 100644 examples/fuse/wscript_build


Changeset truncated at 500 lines:

diff --git a/examples/fuse/README b/examples/fuse/README
new file mode 100644
index 0000000..a1f311d
--- /dev/null
+++ b/examples/fuse/README
@@ -0,0 +1,7 @@
+WARNING:
+
+This is experimental work-in-progress code, don't expect it to do
+anything sensible.
+
+Eventually this *might* turn into a fuse client filesystem. This is
+not a promise for anything.
diff --git a/examples/fuse/clifuse.c b/examples/fuse/clifuse.c
new file mode 100644
index 0000000..fc57ec7
--- /dev/null
+++ b/examples/fuse/clifuse.c
@@ -0,0 +1,1473 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * fusermount smb2 client
+ * Copyright (C) Volker Lendecke 2016
+ *
+ * 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/>.
+ */
+
+#define FUSE_USE_VERSION 26
+#define _FILE_OFFSET_BITS 64
+#include "fuse/fuse_lowlevel.h"
+
+#include "source3/include/includes.h"
+#include "client.h"
+#include "trans2.h"
+#include "libsmb/proto.h"
+#include "libsmb/clirap.h"
+#include "libsmb/cli_smb2_fnum.h"
+#include "lib/util/tevent_ntstatus.h"
+#include "libcli/smb/smbXcli_base.h"
+#include "libcli/security/security.h"
+#include "clifuse.h"
+
+struct mount_state {
+       struct tevent_context *ev;
+       struct cli_state *cli;
+       bool done;
+
+       struct tevent_fd *fde;
+       struct tevent_signal *signal_ev;
+
+       struct fuse_chan *ch;
+       struct fuse_session *se;
+
+       size_t bufsize;
+       char *buf;
+
+       struct idr_context *ino_ctx;
+       TALLOC_CTX *ino_parent;
+};
+
+struct inode_state {
+       struct idr_context *ino_ctx;
+       fuse_ino_t ino;
+       char path[1];
+};
+
+static int inode_state_destructor(struct inode_state *s);
+
+static struct inode_state *inode_state_init(TALLOC_CTX *mem_ctx,
+                                           struct idr_context *ino_ctx,
+                                           const char *path)
+{
+       struct inode_state *state;
+       size_t pathlen;
+       int ino;
+
+       pathlen = strlen(path);
+       state = talloc_size(
+               mem_ctx, offsetof(struct inode_state, path) + pathlen + 1);
+       if (state == NULL) {
+               return NULL;
+       }
+       talloc_set_name_const(state, "struct inode_state");
+
+       ino = idr_get_new_above(ino_ctx, state, 1, INT32_MAX);
+       if (ino == -1) {
+               TALLOC_FREE(state);
+               return NULL;
+       }
+
+       state->ino = ino;
+       state->ino_ctx = ino_ctx;
+       memcpy(state->path, path, pathlen + 1);
+
+       DBG_DEBUG("Creating ino %d for path %s\n", ino, path);
+
+       talloc_set_destructor(state, inode_state_destructor);
+
+       return state;
+}
+
+static struct inode_state *inode_state_new(struct mount_state *mstate,
+                                          const char *path)
+{
+       return inode_state_init(mstate->ino_parent, mstate->ino_ctx, path);
+}
+
+static int inode_state_destructor(struct inode_state *s)
+{
+       DBG_DEBUG("destroying inode %ju\n", (uintmax_t)s->ino);
+       idr_remove(s->ino_ctx, s->ino);
+       return 0;
+}
+
+struct ll_create_state {
+       struct mount_state *mstate;
+       fuse_req_t freq;
+       struct fuse_file_info fi;
+       char *path;
+};
+
+static void cli_ll_create_done(struct tevent_req *req);
+
+static void cli_ll_create(fuse_req_t freq, fuse_ino_t parent, const char *name,
+                         mode_t mode, struct fuse_file_info *fi)
+{
+       struct mount_state *mstate = talloc_get_type_abort(
+               fuse_req_userdata(freq), struct mount_state);
+       struct ll_create_state *state;
+       struct inode_state *istate;
+       struct tevent_req *req;
+
+       DBG_DEBUG("parent=%ju, name=%s, mode=%x\n", (uintmax_t)parent,
+                 name, (unsigned)mode);
+
+       istate = idr_find(mstate->ino_ctx, parent);
+       if (istate == NULL) {
+               fuse_reply_err(freq, ENOENT);
+               return;
+       }
+
+       state = talloc(mstate, struct ll_create_state);
+       if (state == NULL) {
+               fuse_reply_err(freq, ENOMEM);
+               return;
+       }
+       state->mstate = mstate;
+       state->freq = freq;
+       state->fi = *fi;
+
+       state->path = talloc_asprintf(state, "%s%s%s", istate->path,
+                                     strlen(istate->path) ? "\\": "",
+                                     name);
+       if (state->path == NULL) {
+               TALLOC_FREE(state);
+               fuse_reply_err(freq, ENOMEM);
+               return;
+       }
+
+       req = cli_smb2_create_fnum_send(
+               state, mstate->ev, mstate->cli, state->path,
+               0, FILE_GENERIC_READ|FILE_GENERIC_WRITE, FILE_ATTRIBUTE_NORMAL,
+               FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
+               FILE_CREATE, FILE_NON_DIRECTORY_FILE);
+       if (req == NULL) {
+               TALLOC_FREE(state);
+               fuse_reply_err(freq, ENOMEM);
+               return;
+       }
+       tevent_req_set_callback(req, cli_ll_create_done, state);
+}
+
+static void cli_ll_create_done(struct tevent_req *req)
+{
+       struct ll_create_state *state = tevent_req_callback_data(
+               req, struct ll_create_state);
+       struct fuse_entry_param e;
+       struct inode_state *ino;
+       uint16_t fnum;
+       NTSTATUS status;
+
+       status = cli_smb2_create_fnum_recv(req, &fnum, NULL);
+       TALLOC_FREE(req);
+       if (!NT_STATUS_IS_OK(status)) {
+               fuse_reply_err(state->freq, map_errno_from_nt_status(status));
+               return;
+       }
+
+       state->fi.fh = fnum;
+       state->fi.direct_io = 0;
+       state->fi.keep_cache = 0;
+
+       ino = inode_state_new(state->mstate, state->path);
+       if (ino == NULL) {
+               fuse_reply_err(state->freq, ENOMEM);
+               return;
+       }
+
+       e = (struct fuse_entry_param) {
+               .ino = ino->ino,
+               .generation = 1, /* FIXME */
+               .attr_timeout = 1.0,
+               .entry_timeout = 1.0
+       };
+
+       fuse_reply_create(state->freq, &e, &state->fi);
+
+       TALLOC_FREE(state);
+}
+
+struct cli_get_unixattr_state {
+       struct tevent_context *ev;
+       struct cli_state *cli;
+       uint64_t fid_persistent;
+       uint64_t fid_volatile;
+
+       struct timespec create_time;
+       struct timespec access_time;
+       struct timespec write_time;
+       struct timespec change_time;
+       uint32_t mode;
+       uint64_t ino;
+       uint64_t size;
+};
+
+static void cli_get_unixattr_opened(struct tevent_req *subreq);
+static void cli_get_unixattr_gotinfo(struct tevent_req *subreq);
+static void cli_get_unixattr_closed(struct tevent_req *subreq);
+
+
+static struct tevent_req *cli_get_unixattr_send(TALLOC_CTX *mem_ctx,
+                                               struct tevent_context *ev,
+                                               struct cli_state *cli,
+                                               const char *path)
+{
+       struct tevent_req *req, *subreq;
+       struct cli_get_unixattr_state *state;
+
+       req = tevent_req_create(mem_ctx, &state,
+                               struct cli_get_unixattr_state);
+       if (req == NULL) {
+               return NULL;
+       }
+       state->ev = ev;
+       state->cli = cli;
+
+       subreq = smb2cli_create_send(
+               state, ev, cli->conn, cli->timeout, cli->smb2.session,
+               cli->smb2.tcon, path, SMB2_OPLOCK_LEVEL_NONE,
+               SMB2_IMPERSONATION_IMPERSONATION,
+               SYNCHRONIZE_ACCESS|FILE_READ_ATTRIBUTES, 0,
+               FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
+               FILE_OPEN, 0, NULL);
+       if (tevent_req_nomem(subreq, req)) {
+               return tevent_req_post(req, ev);
+       }
+       tevent_req_set_callback(subreq, cli_get_unixattr_opened, req);
+
+       return req;
+}
+
+static void cli_get_unixattr_opened(struct tevent_req *subreq)
+{
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+       struct cli_get_unixattr_state *state = tevent_req_data(
+               req, struct cli_get_unixattr_state);
+       struct cli_state *cli = state->cli;
+       NTSTATUS status;
+
+       status = smb2cli_create_recv(subreq, &state->fid_persistent,
+                                    &state->fid_volatile, NULL, NULL, NULL);
+       TALLOC_FREE(subreq);
+       if (tevent_req_nterror(req, status)) {
+               DBG_DEBUG("smb2cli_create_recv returned %s\n",
+                         nt_errstr(status));
+               return;
+       }
+
+       subreq = smb2cli_query_info_send(
+               state, state->ev, cli->conn, 0,
+               cli->smb2.session, cli->smb2.tcon,
+               1, /* in_info_type */
+               (SMB_FILE_ALL_INFORMATION - 1000), /* in_file_info_class */
+               0xFFFF, /* in_max_output_length */
+               NULL, /* in_input_buffer */
+               0, /* in_additional_info */
+               0, /* in_flags */
+               state->fid_persistent,
+               state->fid_volatile);
+       if (tevent_req_nomem(subreq, req)) {
+               return;
+       }
+       tevent_req_set_callback(subreq, cli_get_unixattr_gotinfo, req);
+}
+
+static void cli_get_unixattr_gotinfo(struct tevent_req *subreq)
+{
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+       struct cli_get_unixattr_state *state = tevent_req_data(
+               req, struct cli_get_unixattr_state);
+       struct cli_state *cli = state->cli;
+       NTSTATUS status;
+       DATA_BLOB outbuf;
+
+       status = smb2cli_query_info_recv(subreq, state, &outbuf);
+        TALLOC_FREE(subreq);
+       if (tevent_req_nterror(req, status)) {
+               DBG_DEBUG("smb2cli_query_info_recv returned %s\n",
+                         nt_errstr(status));
+               return;
+       }
+
+       if (outbuf.length < 0x60) {
+               tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
+               return;
+       }
+
+       state->create_time = interpret_long_date((char *)outbuf.data + 0x0);
+       state->access_time = interpret_long_date((char *)outbuf.data + 0x8);
+       state->write_time  = interpret_long_date((char *)outbuf.data + 0x10);
+       state->change_time = interpret_long_date((char *)outbuf.data + 0x18);
+       state->mode        = IVAL(outbuf.data, 0x20);
+       state->size        = BVAL(outbuf.data, 0x30);
+       state->ino         = BVAL(outbuf.data, 0x40);
+
+       subreq = smb2cli_close_send(state, state->ev, cli->conn, 0,
+                                   cli->smb2.session, cli->smb2.tcon, 0,
+                                   state->fid_persistent,
+                                   state->fid_volatile);
+       if (tevent_req_nomem(subreq, req)) {
+               return;
+       }
+       tevent_req_set_callback(subreq, cli_get_unixattr_closed, req);
+}
+
+static void cli_get_unixattr_closed(struct tevent_req *subreq)
+{
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+       NTSTATUS status;
+
+       status = smb2cli_close_recv(subreq);
+       TALLOC_FREE(subreq);
+       if (tevent_req_nterror(req, status)) {
+               return;
+       }
+       tevent_req_done(req);
+}
+
+static NTSTATUS cli_get_unixattr_recv(struct tevent_req *req,
+                                     struct stat *st)
+{
+       struct cli_get_unixattr_state *state = tevent_req_data(
+               req, struct cli_get_unixattr_state);
+       NTSTATUS status;
+
+       if (tevent_req_is_nterror(req, &status)) {
+               return status;
+       }
+
+       if (IS_DOS_DIR(state->mode)) {
+               st->st_mode = (S_IFDIR | 0555);
+               st->st_nlink = 2;
+       } else {
+               st->st_mode = (S_IFREG | 0444);
+               st->st_nlink = 1;
+       }
+
+       st->st_size = state->size;
+       st->st_uid = getuid();
+       st->st_gid = getgid();
+       st->st_ino = state->ino;
+       st->st_atime = convert_timespec_to_time_t(state->access_time);
+       st->st_ctime = convert_timespec_to_time_t(state->change_time);
+       st->st_mtime = convert_timespec_to_time_t(state->write_time);
+
+       return NT_STATUS_OK;
+}
+
+struct cli_smb2_listdir_state {
+       struct tevent_context *ev;
+       struct smbXcli_conn *conn;
+       uint32_t timeout_msec;
+       struct smbXcli_session *session;
+       struct smbXcli_tcon *tcon;
+       uint8_t level;
+       uint8_t flags;
+       uint32_t file_index;
+       uint64_t fid_persistent;
+       uint64_t fid_volatile;
+       const char *mask;
+       uint32_t outbuf_len;
+
+       uint16_t attribute;
+       const char *mntpoint;
+       const char *pathname;
+       NTSTATUS (*fn)(const char *mntpoint, struct file_info *f,
+                      const char *mask, void *private_data);
+       void *private_data;
+       bool processed_file;
+};
+
+static void cli_smb2_listdir_done(struct tevent_req *subreq);
+
+static struct tevent_req *cli_smb2_listdir_send(
+       TALLOC_CTX *mem_ctx,
+       struct tevent_context *ev,
+       struct smbXcli_conn *conn,
+       uint32_t timeout_msec,
+       struct smbXcli_session *session,
+       struct smbXcli_tcon *tcon,
+       uint8_t level,
+       uint8_t flags,
+       uint32_t file_index,
+       uint64_t fid_persistent,
+       uint64_t fid_volatile,
+       const char *mask,
+       uint32_t outbuf_len,
+       uint16_t attribute,
+       const char *mntpoint,
+       const char *pathname,
+       NTSTATUS (*fn)(const char *mntpoint, struct file_info *f,
+                      const char *mask, void *private_data),
+       void *private_data)
+{
+       struct tevent_req *req, *subreq;
+       struct cli_smb2_listdir_state *state;
+
+       req = tevent_req_create(mem_ctx, &state,
+                               struct cli_smb2_listdir_state);
+       if (req == NULL) {
+               return NULL;
+       }
+       state->ev = ev;
+       state->conn = conn;
+       state->timeout_msec = timeout_msec;
+       state->session = session;
+       state->tcon = tcon;
+       state->level = level;
+       state->flags = flags;
+       state->file_index = file_index;
+       state->fid_persistent = fid_persistent;
+       state->fid_volatile = fid_volatile;
+       state->mask = mask;
+       state->outbuf_len = outbuf_len;
+       state->attribute = attribute;
+       state->mntpoint = mntpoint;
+       state->pathname = pathname;
+       state->fn = fn;
+       state->private_data = private_data;
+
+       subreq = smb2cli_query_directory_send(
+               state, state->ev, state->conn, state->timeout_msec,
+               state->session, state->tcon, state->level,
+               state->flags, state->file_index,
+               state->fid_persistent, state->fid_volatile,
+               state->mask, state->outbuf_len);
+       if (tevent_req_nomem(subreq, req)) {
+               return tevent_req_post(req, ev);
+       }
+       tevent_req_set_callback(subreq, cli_smb2_listdir_done, req);
+       return req;
+}
+
+static NTSTATUS parse_finfo_id_both_directory_info(uint8_t *dir_data,
+                               uint32_t dir_data_length,
+                               struct file_info *finfo,
+                               uint32_t *next_offset)
+{
+       size_t namelen = 0;
+       size_t slen = 0;
+       size_t ret = 0;
+
+       if (dir_data_length < 4) {
+               return NT_STATUS_INFO_LENGTH_MISMATCH;
+       }
+
+       *next_offset = IVAL(dir_data, 0);
+
+       if (*next_offset > dir_data_length) {
+               return NT_STATUS_INFO_LENGTH_MISMATCH;
+       }
+
+       if (*next_offset != 0) {
+               /* Ensure we only read what in this record. */
+               dir_data_length = *next_offset;
+       }


-- 
Samba Shared Repository

Reply via email to