The branch, v3-3-stable has been updated
       via  bb9f768... WHATSNEW: Update changes.
       via  2c935e6... WHATSNEW. Update changes since 3.3.8.
       via  cdf190a... s3:wbc_sid: Fix build.
       via  42aea0d... s3: Fix a memleak reported by dmarkey (cherry picked 
from commit 5aeb954ba9382e1975c64ac96f1e377ed6af3ae0)
       via  2b40f75... s3:smbclient: Fix bug 6606 (reported as 6744) in 3.3
       via  7f17f28... Correct fix for bug 6781 - Cannot rename subfolders in 
Explorer view with recent versions of Samba. Without this fix, renaming a 
directory ./a to ./b, whilst a directory ./aa was already open would fail. 
Jeremy. (cherry picked from commit 1f604d26d038956a6ddde892610c9b2254268160)
       via  0e7fbe2... Fix bug 6769 - symlink unlink does nothing. Jeremy. 
(cherry picked from commit fdc28f6700c97e1276e3d6ae1f242f7daa9bab9e)
       via  89cc728... s3:mount.cifs: make "mount.cifs -V" print the version, 
not usage.
       via  d7607eb... Revert "cifs mount did not properly display version 
string when no other parameters passed in."
      from  8468e58... WHATSNEW: Add more coherent explanation for bug #6680.

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-3-stable


- Log -----------------------------------------------------------------
commit bb9f768419b656508ba1d62e8c84be7b6037a11f
Author: Karolin Seeger <ksee...@samba.org>
Date:   Mon Oct 12 13:45:39 2009 +0200

    WHATSNEW: Update changes.
    
    Karolin
    (cherry picked from commit 0e52cec95a7b6040a1dd6e6bb5c5439fd3378a32)

commit 2c935e618331face49a11ba3459b93d453d7092f
Author: Karolin Seeger <ksee...@samba.org>
Date:   Mon Oct 12 13:10:29 2009 +0200

    WHATSNEW. Update changes since 3.3.8.
    
    Karolin
    (cherry picked from commit 680e39a6795729dfa5e9a748e189f1424324434f)

commit cdf190a5030291807ea30481c8fee67c6b6187d5
Author: Karolin Seeger <ksee...@samba.org>
Date:   Mon Oct 12 11:24:30 2009 +0200

    s3:wbc_sid: Fix build.
    
    Use talloc_free instead of TALLOC_FREE.
    
    Signed-off-by: Volker Lendecke <v...@samba.org>
    (cherry picked from commit 95389ecdeb2e1d9d9512210a92c05c7a2d753409)

commit 42aea0d90745235efc57d35b96a54a2dc834aa14
Author: Volker Lendecke <v...@samba.org>
Date:   Fri Oct 9 22:58:14 2009 +0200

    s3: Fix a memleak reported by dmarkey (cherry picked from commit 
5aeb954ba9382e1975c64ac96f1e377ed6af3ae0)
    
    Fix bug #6797.
    (cherry picked from commit 68c77a51410bd3a1a0fbe61d6714a9a95b4d82cd)

commit 2b40f75d70b94a1213e5cd78996171b428b35b56
Author: Volker Lendecke <v...@samba.org>
Date:   Fri Sep 18 19:45:36 2009 +0200

    s3:smbclient: Fix bug 6606 (reported as 6744) in 3.3
    
    This is a port of 1f34ffa0ca and 24309bdb2efc to 3.3.
    
    Fix file corruption using smbclient with NT4 server.
    (cherry picked from commit b0fdc578fb10062c36ce2df18ab37cab57a89692)

commit 7f17f286d3a4a0b864fa771f945a8fc02e45ae4d
Author: Jeremy Allison <j...@samba.org>
Date:   Wed Oct 7 15:49:56 2009 -0700

    Correct fix for bug 6781 - Cannot rename subfolders in Explorer view with 
recent versions of Samba. Without this fix, renaming a directory ./a to ./b, 
whilst a directory ./aa was already open would fail. Jeremy.
    (cherry picked from commit 1f604d26d038956a6ddde892610c9b2254268160)

commit 0e7fbe2c0b0ffeb56fc3d2a3b2cd9f45bffb91ad
Author: Jeremy Allison <j...@samba.org>
Date:   Thu Oct 8 15:55:35 2009 -0700

    Fix bug 6769 - symlink unlink does nothing. Jeremy.
    (cherry picked from commit fdc28f6700c97e1276e3d6ae1f242f7daa9bab9e)

commit 89cc728e44b0cec6fe122b7e650f22447d251b7a
Author: Michael Adam <ob...@samba.org>
Date:   Thu Oct 8 10:44:48 2009 -0400

    s3:mount.cifs: make "mount.cifs -V" print the version, not usage.
    
    (cherry-picked from d7ca4997017e86b6f23ced64f1f1672bfb15716b)
    
    Also make "mount.cifs -h" not exit with error exit code but with return 
code 0.
    
    Michael
    
    Part 2/2 of a fix for bug #6692 (mount.cifs segfault).
    (cherry picked from commit d41131948346619be98514331d7059d9bffecac5)

commit d7607eb74658cae4856bb287242bc6f5fb27438b
Author: Jeff Layton <jlay...@redhat.com>
Date:   Thu Oct 8 10:42:37 2009 -0400

    Revert "cifs mount did not properly display version string when no other 
parameters passed in."
    
    This reverts commit c7bf0f4c222ae46be2a751997e03197832b494cd.
    
    Part 1/2 of a fix for bug #6692.
    (cherry picked from commit 2cda51b4e6fba53c04f87e4c2dd99a952a63d812)

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

Summary of changes:
 WHATSNEW.txt                          |    6 +
 source/client/mount.cifs.c            |   41 +++++---
 source/libsmb/clireadwrite.c          |  188 +++++++++++++++++++++++++++++----
 source/modules/vfs_default.c          |    6 +-
 source/nsswitch/libwbclient/wbc_sid.c |    4 +
 source/smbd/files.c                   |    9 ++-
 source/smbd/posix_acls.c              |   57 ++++++++---
 source/smbd/reply.c                   |   49 +++++++--
 8 files changed, 298 insertions(+), 62 deletions(-)


Changeset truncated at 500 lines:

diff --git a/WHATSNEW.txt b/WHATSNEW.txt
index 81a325c..2d4262c 100644
--- a/WHATSNEW.txt
+++ b/WHATSNEW.txt
@@ -9,6 +9,7 @@ This is the latest bugfix release of the Samba 3.3 series.
 Major enhancements in Samba 3.3.9 include:
 
    o Fix trust relationships to windows 2008 (2008 r2) (bug #6711).
+   o Fix file corruption using smbclient with NT4 server (bug #6606).
    o Fix Windows 7 share access (which defaults to NTLMv2) (bug #6680).
    o Fix SAMR server for Winbind access (bug #6504).
 
@@ -22,11 +23,14 @@ Changes since 3.3.8
 
 o   Michael Adam <ob...@samba.org>
     * BUG 6509: Use gid (not uid) cache in fetch_gid_from_cache().
+    * BUG 6692: Fix mount.cifs segfault.
 
 
 o   Jeremy Allison <j...@samba.org>
     * BUG 6504: Fix SAMR server for Winbind access.
+    * BUG 6769: Symlink unlink does nothing.
     * BUG 6776: Fix core dump when running overlapping Byte Lock test.
+    * BUG 6781: Fix renaming of subfolders in Explorer view.
 
 
 o   Yannick Bergeron <burgerg...@hotmail.com>
@@ -49,8 +53,10 @@ o   Volker Lendecke <v...@samba.org>
     * BUG 5886: Fix password change propagation.
     * BUG 6349: Initialize domain info struct.
     * BUG 6585: Fix unqualified "net join".
+    * BUG 6606: Fix file corruption using smbclient with NT4 server.
     * BUG 6646: Correctly chew keepalive packets.
     * BUG 6785: Only ever handle one event after a select call.
+    * BUG 6797: Fix a memleak in libwbclient.
 
 
 o   Derrell Lipman <derrell.lip...@unwireduniverse.com>
diff --git a/source/client/mount.cifs.c b/source/client/mount.cifs.c
index c78aee0..0add7a8 100644
--- a/source/client/mount.cifs.c
+++ b/source/client/mount.cifs.c
@@ -1036,6 +1036,14 @@ uppercase_string(char *string)
        return 1;
 }
 
+static void print_cifs_mount_version(void)
+{
+       printf("mount.cifs version: %s.%s%s\n",
+               MOUNT_CIFS_VERSION_MAJOR,
+               MOUNT_CIFS_VERSION_MINOR,
+               MOUNT_CIFS_VENDOR_SUFFIX);
+}
+
 int main(int argc, char ** argv)
 {
        int c;
@@ -1097,15 +1105,25 @@ int main(int argc, char ** argv)
                        exit(EX_SYSERR);
                }
                mountpoint = argv[2];
-       } else {
-               if ((strcmp (argv[1], "--version") == 0) ||
-                   ((strcmp (argv[1], "-V") == 0))) {
-                       printf ("mount.cifs version: %s.%s%s\n",
-                       MOUNT_CIFS_VERSION_MAJOR,
-                       MOUNT_CIFS_VERSION_MINOR,
-                       MOUNT_CIFS_VENDOR_SUFFIX);
-                       exit (0);
+       } else if (argc == 2) {
+               if ((strcmp(argv[1], "-V") == 0) ||
+                   (strcmp(argv[1], "--version") == 0))
+               {
+                       print_cifs_mount_version();
+                       exit(0);
+               }
+
+               if ((strcmp(argv[1], "-h") == 0) ||
+                   (strcmp(argv[1], "-?") == 0) ||
+                   (strcmp(argv[1], "--help") == 0))
+               {
+                       mount_cifs_usage();
+                       exit(0);
                }
+
+               mount_cifs_usage();
+               exit(EX_USAGE);
+       } else {
                mount_cifs_usage();
                exit(EX_USAGE);
        }
@@ -1161,11 +1179,8 @@ int main(int argc, char ** argv)
                case 'v':
                        ++verboseflag;
                        break;
-               case 'V':          
-                       printf ("mount.cifs version: %s.%s%s\n",
-                       MOUNT_CIFS_VERSION_MAJOR,
-                       MOUNT_CIFS_VERSION_MINOR,
-                       MOUNT_CIFS_VENDOR_SUFFIX);
+               case 'V':
+                       print_cifs_mount_version();
                        exit (0);
                case 'w':
                        flags &= ~MS_RDONLY;
diff --git a/source/libsmb/clireadwrite.c b/source/libsmb/clireadwrite.c
index a57f1e0..ac59c8a 100644
--- a/source/libsmb/clireadwrite.c
+++ b/source/libsmb/clireadwrite.c
@@ -154,6 +154,133 @@ NTSTATUS cli_read_andx_recv(struct async_req *req, 
ssize_t *received,
        return NT_STATUS_OK;
 }
 
+struct cli_readall_state {
+       struct cli_state *cli;
+       uint16_t fnum;
+       off_t start_offset;
+       size_t size;
+       size_t received;
+       uint8_t *buf;
+};
+
+static void cli_readall_done(struct async_req *subreq);
+
+static struct async_req *cli_readall_send(TALLOC_CTX *mem_ctx,
+                                         struct cli_state *cli,
+                                         uint16_t fnum,
+                                         off_t offset, size_t size)
+{
+       struct async_req *req, *subreq;
+       struct cli_readall_state *state;
+
+       req = async_req_new(mem_ctx, cli->event_ctx);
+       if (req == NULL) {
+               return NULL;
+       }
+       state = talloc(req, struct cli_readall_state);
+       if (state == NULL) {
+               TALLOC_FREE(req);
+               return NULL;
+       }
+       req->private_data = state;
+
+       state->cli = cli;
+       state->fnum = fnum;
+       state->start_offset = offset;
+       state->size = size;
+       state->received = 0;
+       state->buf = NULL;
+
+       subreq = cli_read_andx_send(state, cli, fnum, offset, size);
+       if (subreq == NULL) {
+               TALLOC_FREE(req);
+               return NULL;
+       }
+       subreq->async.fn = cli_readall_done;
+       subreq->async.priv = req;
+       return req;
+}
+
+static void cli_readall_done(struct async_req *subreq)
+{
+       struct async_req *req = talloc_get_type_abort(
+               subreq->async.priv, struct async_req);
+       struct cli_readall_state *state = talloc_get_type_abort(
+               req->private_data, struct cli_readall_state);
+       ssize_t received;
+       uint8_t *buf;
+       NTSTATUS status;
+
+       status = cli_read_andx_recv(subreq, &received, &buf);
+       if (!NT_STATUS_IS_OK(status)) {
+               async_req_error(req, status);
+               return;
+       }
+
+       if (received == 0) {
+               /* EOF */
+               async_req_done(req);
+               return;
+       }
+
+       if ((state->received == 0) && (received == state->size)) {
+               /* Ideal case: Got it all in one run */
+               state->buf = buf;
+               state->received += received;
+               async_req_done(req);
+               return;
+       }
+
+       /*
+        * We got a short read, issue a read for the
+        * rest. Unfortunately we have to allocate the buffer
+        * ourselves now, as our caller expects to receive a single
+        * buffer. cli_read_andx does it from the buffer received from
+        * the net, but with a short read we have to put it together
+        * from several reads.
+        */
+
+       if (state->buf == NULL) {
+               state->buf = talloc_array(state, uint8_t, state->size);
+               if (async_req_nomem(state->buf, req)) {
+                       return;
+               }
+       }
+       memcpy(state->buf + state->received, buf, received);
+       state->received += received;
+
+       TALLOC_FREE(subreq);
+
+       if (state->received >= state->size) {
+               async_req_done(req);
+               return;
+       }
+
+       subreq = cli_read_andx_send(state, state->cli, state->fnum,
+                                   state->start_offset + state->received,
+                                   state->size - state->received);
+       if (async_req_nomem(subreq, req)) {
+               return;
+       }
+       subreq->async.fn = cli_readall_done;
+       subreq->async.priv = req;
+}
+
+static NTSTATUS cli_readall_recv(struct async_req *req, ssize_t *received,
+                                uint8_t **rcvbuf)
+{
+       struct cli_readall_state *state = talloc_get_type_abort(
+               req->private_data, struct cli_readall_state);
+
+       SMB_ASSERT(req->state >= ASYNC_REQ_DONE);
+       if (req->state == ASYNC_REQ_ERROR) {
+               return req->status;
+       }
+       *received = state->received;
+       *rcvbuf = state->buf;
+       return NT_STATUS_OK;
+}
+
 /*
  * Parallel read support.
  *
@@ -162,6 +289,12 @@ NTSTATUS cli_read_andx_recv(struct async_req *req, ssize_t 
*received,
  * the callback function "sink" in the right order.
  */
 
+struct cli_pull_subreq {
+       struct async_req *req;
+       size_t received;
+       uint8_t *buf;
+};
+
 struct cli_pull_state {
        struct async_req *req;
 
@@ -179,7 +312,7 @@ struct cli_pull_state {
         * Outstanding requests
         */
        int num_reqs;
-       struct async_req **reqs;
+       struct cli_pull_subreq *reqs;
 
        /*
         * For how many bytes did we send requests already?
@@ -268,7 +401,7 @@ struct async_req *cli_pull_send(TALLOC_CTX *mem_ctx, struct 
cli_state *cli,
        state->num_reqs = MAX(window_size/state->chunk_size, 1);
        state->num_reqs = MIN(state->num_reqs, cli->max_mux);
 
-       state->reqs = TALLOC_ZERO_ARRAY(state, struct async_req *,
+       state->reqs = TALLOC_ZERO_ARRAY(state, struct cli_pull_subreq,
                                        state->num_reqs);
        if (state->reqs == NULL) {
                goto failed;
@@ -288,17 +421,17 @@ struct async_req *cli_pull_send(TALLOC_CTX *mem_ctx, 
struct cli_state *cli,
                size_left = size - state->requested;
                request_thistime = MIN(size_left, state->chunk_size);
 
-               state->reqs[i] = cli_read_andx_send(
+               state->reqs[i].req = cli_readall_send(
                        state->reqs, cli, fnum,
                        state->start_offset + state->requested,
                        request_thistime);
 
-               if (state->reqs[i] == NULL) {
+               if (state->reqs[i].req == NULL) {
                        goto failed;
                }
 
-               state->reqs[i]->async.fn = cli_pull_read_done;
-               state->reqs[i]->async.priv = result;
+               state->reqs[i].req->async.fn = cli_pull_read_done;
+               state->reqs[i].req->async.priv = result;
 
                state->requested += request_thistime;
        }
@@ -320,16 +453,32 @@ static void cli_pull_read_done(struct async_req *read_req)
                read_req->async.priv, struct async_req);
        struct cli_pull_state *state = talloc_get_type_abort(
                pull_req->private_data, struct cli_pull_state);
-       struct cli_request *read_state = cli_request_get(read_req);
+       ssize_t received;
+       uint8_t *buf;
        NTSTATUS status;
+       int i;
 
-       status = cli_read_andx_recv(read_req, &read_state->data.read.received,
-                                   &read_state->data.read.rcvbuf);
+       status = cli_readall_recv(read_req, &received, &buf);
        if (!NT_STATUS_IS_OK(status)) {
                async_req_error(state->req, status);
                return;
        }
 
+       for (i=0; i<state->num_reqs; i++) {
+               if (state->reqs[i].req == read_req) {
+                       break;
+               }
+       }
+
+       if (i == state->num_reqs) {
+               /* Got something we did not send. Just drop it. */
+               TALLOC_FREE(read_req);
+               return;
+       }
+
+       state->reqs[i].received = received;
+       state->reqs[i].buf = buf;
+
        /*
         * This loop is the one to take care of out-of-order replies. All
         * pending requests are in state->reqs, state->reqs[top_req] is the
@@ -339,34 +488,33 @@ static void cli_pull_read_done(struct async_req *read_req)
         * requests.
         */
 
-       while (state->reqs[state->top_req] != NULL) {
-               struct cli_request *top_read;
+       while (state->reqs[state->top_req].req != NULL) {
+               struct cli_pull_subreq *top_read;
 
                DEBUG(11, ("cli_pull_read_done: top_req = %d\n",
                           state->top_req));
 
-               if (state->reqs[state->top_req]->state < ASYNC_REQ_DONE) {
+               if (state->reqs[state->top_req].req->state < ASYNC_REQ_DONE) {
                        DEBUG(11, ("cli_pull_read_done: top request not yet "
                                   "done\n"));
                        return;
                }
 
-               top_read = cli_request_get(state->reqs[state->top_req]);
+               top_read = &state->reqs[state->top_req];
 
                DEBUG(10, ("cli_pull_read_done: Pushing %d bytes, %d already "
-                          "pushed\n", (int)top_read->data.read.received,
+                          "pushed\n", (int)top_read->received,
                           (int)state->pushed));
 
-               status = state->sink((char *)top_read->data.read.rcvbuf,
-                                    top_read->data.read.received,
+               status = state->sink((char *)top_read->buf, top_read->received,
                                     state->priv);
                if (!NT_STATUS_IS_OK(status)) {
                        async_req_error(state->req, status);
                        return;
                }
-               state->pushed += top_read->data.read.received;
+               state->pushed += top_read->received;
 
-               TALLOC_FREE(state->reqs[state->top_req]);
+               TALLOC_FREE(state->reqs[state->top_req].req);
 
                if (state->requested < state->size) {
                        struct async_req *new_req;
@@ -383,7 +531,7 @@ static void cli_pull_read_done(struct async_req *read_req)
                                         + state->requested),
                                   state->top_req));
 
-                       new_req = cli_read_andx_send(
+                       new_req = cli_readall_send(
                                state->reqs, state->cli, state->fnum,
                                state->start_offset + state->requested,
                                request_thistime);
@@ -395,7 +543,7 @@ static void cli_pull_read_done(struct async_req *read_req)
                        new_req->async.fn = cli_pull_read_done;
                        new_req->async.priv = pull_req;
 
-                       state->reqs[state->top_req] = new_req;
+                       state->reqs[state->top_req].req = new_req;
                        state->requested += request_thistime;
                }
 
diff --git a/source/modules/vfs_default.c b/source/modules/vfs_default.c
index 1e95633..d8ef888 100644
--- a/source/modules/vfs_default.c
+++ b/source/modules/vfs_default.c
@@ -993,7 +993,11 @@ static NTSTATUS vfswrap_streaminfo(vfs_handle_struct 
*handle,
                ret = SMB_VFS_FSTAT(fsp, &sbuf);
        }
        else {
-               ret = SMB_VFS_STAT(handle->conn, fname, &sbuf);
+               if (lp_posix_pathnames()) {
+                       ret = SMB_VFS_LSTAT(handle->conn, fname, &sbuf);
+               } else {
+                       ret = SMB_VFS_STAT(handle->conn, fname, &sbuf);
+               }
        }
 
        if (ret == -1) {
diff --git a/source/nsswitch/libwbclient/wbc_sid.c 
b/source/nsswitch/libwbclient/wbc_sid.c
index 18516b6..856b8b4 100644
--- a/source/nsswitch/libwbclient/wbc_sid.c
+++ b/source/nsswitch/libwbclient/wbc_sid.c
@@ -281,9 +281,13 @@ wbcErr wbcLookupSid(const struct wbcDomainSid *sid,
        if (WBC_ERROR_IS_OK(wbc_status)) {
                if (pdomain != NULL) {
                        *pdomain = domain;
+               } else {
+                       talloc_free(domain);
                }
                if (pname != NULL) {
                        *pname = name;
+               } else {
+                       talloc_free(name);
                }
                if (pname_type != NULL) {
                        *pname_type = name_type;
diff --git a/source/smbd/files.c b/source/smbd/files.c
index cdaa5f1..e74ad7a 100644
--- a/source/smbd/files.c
+++ b/source/smbd/files.c
@@ -407,13 +407,18 @@ bool file_find_subpath(files_struct *dir_fsp)
                                        fsp->conn->connectpath,
                                        fsp->fsp_name);
 
-               if (strnequal(d_fullname, d1_fullname, dlen)) {
+               /*
+                * If the open file has a path that is a longer
+                * component, then it's a subpath.
+                */
+               if (strnequal(d_fullname, d1_fullname, dlen) &&
+                               (d1_fullname[dlen] == '/')) {
                        TALLOC_FREE(d_fullname);
                        TALLOC_FREE(d1_fullname);
                        return true;
                }
                TALLOC_FREE(d1_fullname);
-       } 
+       }
 
        TALLOC_FREE(d_fullname);
        return false;
diff --git a/source/smbd/posix_acls.c b/source/smbd/posix_acls.c
index 1afd48e..c8d9e00 100644
--- a/source/smbd/posix_acls.c
+++ b/source/smbd/posix_acls.c
@@ -3178,13 +3178,19 @@ NTSTATUS posix_get_nt_acl(struct connection_struct 
*conn, const char *name,
        SMB_ACL_T posix_acl = NULL;
        SMB_ACL_T def_acl = NULL;
        struct pai_val *pal;
+       int ret;
 
        *ppdesc = NULL;
 
        DEBUG(10,("posix_get_nt_acl: called for file %s\n", name ));
 
        /* Get the stat struct for the owner info. */
-       if(SMB_VFS_STAT(conn, name, &sbuf) != 0) {
+       if (lp_posix_pathnames()) {
+               ret = SMB_VFS_LSTAT(conn, name, &sbuf);
+       } else {
+               ret = SMB_VFS_STAT(conn, name, &sbuf);
+       }
+       if(ret != 0) {
                return map_nt_error_from_unix(errno);
        }
 
@@ -3218,6 +3224,7 @@ int try_chown(connection_struct *conn, const char *fname, 
uid_t uid, gid_t gid)
        int ret;
        files_struct *fsp;
        SMB_STRUCT_STAT st;
+       bool posix_paths = lp_posix_pathnames();
 
        if(!CAN_WRITE(conn)) {
                return -1;
@@ -3225,7 +3232,11 @@ int try_chown(connection_struct *conn, const char 
*fname, uid_t uid, gid_t gid)
 
        /* Case (1). */
        /* try the direct way first */
-       ret = SMB_VFS_CHOWN(conn, fname, uid, gid);
+       if (posix_paths) {
+               ret = SMB_VFS_LCHOWN(conn, fname, uid, gid);
+       } else {
+               ret = SMB_VFS_CHOWN(conn, fname, uid, gid);
+       }
        if (ret == 0)
                return 0;
 
@@ -3265,7 +3276,12 @@ int try_chown(connection_struct *conn, const char 
*fname, uid_t uid, gid_t gid)


-- 
Samba Shared Repository

Reply via email to