The branch, v3-4-test has been updated
       via  ee70079d08acf23cf7c342f09a7db4f5fc7ca95e (commit)
      from  91a5b8561e2f13f77fa5648f7cc373aff1701954 (commit)

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


- Log -----------------------------------------------------------------
commit ee70079d08acf23cf7c342f09a7db4f5fc7ca95e
Author: SATOH Fumiyasu <fumi...@osstech.co.jp>
Date:   Tue Sep 8 16:07:17 2009 -0700

    Fix bug 6496 - libsmbclient: MS-DFS: cannot follow multibyte char link 
name. A server returns a byte of consumed path in UCS2, not UNIX charset.

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

Summary of changes:
 source3/include/proto.h |    2 +-
 source3/libsmb/clidfs.c |   52 ++++++++++++++++++++++++++++++++++------------
 2 files changed, 39 insertions(+), 15 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/include/proto.h b/source3/include/proto.h
index 85619ee..d33a019 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -2371,7 +2371,7 @@ bool cli_dfs_get_referral(TALLOC_CTX *ctx,
                        const char *path,
                        CLIENT_DFS_REFERRAL**refs,
                        size_t *num_refs,
-                       uint16 *consumed);
+                       size_t *consumed);
 bool cli_resolve_path(TALLOC_CTX *ctx,
                        const char *mountpt,
                        const struct user_auth_info *dfs_auth_info,
diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c
index 98b96cf..5e944f1 100644
--- a/source3/libsmb/clidfs.c
+++ b/source3/libsmb/clidfs.c
@@ -603,16 +603,19 @@ bool cli_dfs_get_referral(TALLOC_CTX *ctx,
                        const char *path,
                        CLIENT_DFS_REFERRAL**refs,
                        size_t *num_refs,
-                       uint16 *consumed)
+                       size_t *consumed)
 {
        unsigned int data_len = 0;
        unsigned int param_len = 0;
        uint16 setup = TRANSACT2_GET_DFS_REFERRAL;
-       char *param;
+       char *param = NULL;
        char *rparam=NULL, *rdata=NULL;
        char *p;
        char *endp;
        size_t pathlen = 2*(strlen(path)+1);
+       smb_ucs2_t *path_ucs;
+       char *consumed_path = NULL;
+       uint16_t consumed_ucs;
        uint16 num_referrals;
        CLIENT_DFS_REFERRAL *referrals = NULL;
        bool ret = false;
@@ -622,11 +625,12 @@ bool cli_dfs_get_referral(TALLOC_CTX *ctx,
 
        param = SMB_MALLOC_ARRAY(char, 2+pathlen+2);
        if (!param) {
-               return false;
+               goto out;
        }
        SSVAL(param, 0, 0x03);  /* max referral level */
        p = &param[2];
 
+       path_ucs = (smb_ucs2_t *)p;
        p += clistr_push(cli, p, path, pathlen, STR_TERMINATE);
        param_len = PTR_DIFF(p, param);
 
@@ -637,16 +641,13 @@ bool cli_dfs_get_referral(TALLOC_CTX *ctx,
                        param, param_len, 2,            /* param, length, max */
                        NULL, 0, cli->max_xmit /* data, length, max */
                        )) {
-               SAFE_FREE(param);
-               return false;
+               goto out;
        }
 
-       SAFE_FREE(param);
-
        if (!cli_receive_trans(cli, SMBtrans2,
                &rparam, &param_len,
                &rdata, &data_len)) {
-                       return false;
+               goto out;
        }
 
        if (data_len < 4) {
@@ -655,9 +656,30 @@ bool cli_dfs_get_referral(TALLOC_CTX *ctx,
 
        endp = rdata + data_len;
 
-       *consumed     = SVAL(rdata, 0);
+       consumed_ucs  = SVAL(rdata, 0);
        num_referrals = SVAL(rdata, 2);
 
+       /* consumed_ucs is the number of bytes
+        * of the UCS2 path consumed not counting any
+        * terminating null. We need to convert
+        * back to unix charset and count again
+        * to get the number of bytes consumed from
+        * the incoming path. */
+
+       if (pull_string_talloc(talloc_tos(),
+                       NULL,
+                       0,
+                       &consumed_path,
+                       path_ucs,
+                       consumed_ucs,
+                       STR_UNICODE) == 0) {
+               goto out;
+       }
+       if (consumed_path == NULL) {
+               goto out;
+       }
+       *consumed = strlen(consumed_path);
+
        if (num_referrals != 0) {
                uint16 ref_version;
                uint16 ref_size;
@@ -714,6 +736,8 @@ bool cli_dfs_get_referral(TALLOC_CTX *ctx,
 
   out:
 
+       TALLOC_FREE(consumed_path);
+       SAFE_FREE(param);
        SAFE_FREE(rdata);
        SAFE_FREE(rparam);
        return ret;
@@ -732,7 +756,7 @@ bool cli_resolve_path(TALLOC_CTX *ctx,
 {
        CLIENT_DFS_REFERRAL *refs = NULL;
        size_t num_refs = 0;
-       uint16 consumed;
+       size_t consumed = 0;
        struct cli_state *cli_ipc = NULL;
        char *dfs_path = NULL;
        char *cleanpath = NULL;
@@ -840,13 +864,13 @@ bool cli_resolve_path(TALLOC_CTX *ctx,
        if (!dfs_path) {
                return false;
        }
-       pathlen = strlen(dfs_path)*2;
+       pathlen = strlen(dfs_path);
        consumed = MIN(pathlen, consumed);
-       *pp_targetpath = talloc_strdup(ctx, &dfs_path[consumed/2]);
+       *pp_targetpath = talloc_strdup(ctx, &dfs_path[consumed]);
        if (!*pp_targetpath) {
                return false;
        }
-       dfs_path[consumed/2] = '\0';
+       dfs_path[consumed] = '\0';
 
        /*
         * *pp_targetpath is now the unconsumed part of the path.
@@ -963,7 +987,7 @@ static bool cli_check_msdfs_proxy(TALLOC_CTX *ctx,
 {
        CLIENT_DFS_REFERRAL *refs = NULL;
        size_t num_refs = 0;
-       uint16 consumed;
+       size_t consumed = 0;
        char *fullpath = NULL;
        bool res;
        uint16 cnum;


-- 
Samba Shared Repository

Reply via email to