diff options
author | SATOH Fumiyasu <fumiyas@osstech.co.jp> | 2009-06-30 15:29:08 -0700 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2009-06-30 15:29:08 -0700 |
commit | 7f7ebfaecbe3458a4c3e8fc79b68dd247ef4e31e (patch) | |
tree | dabfe401e85a0ca20b327b0fb2dbb2f1f02ffe61 | |
parent | 78519b65007d87870ea406315b7f233eba69e155 (diff) | |
download | samba-7f7ebfaecbe3458a4c3e8fc79b68dd247ef4e31e.tar.gz samba-7f7ebfaecbe3458a4c3e8fc79b68dd247ef4e31e.tar.bz2 samba-7f7ebfaecbe3458a4c3e8fc79b68dd247ef4e31e.zip |
Fix bug #6496 - MS-DFS: cannot follow multibyte char link name.
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.
-rw-r--r-- | source3/include/proto.h | 2 | ||||
-rw-r--r-- | source3/libsmb/clidfs.c | 52 |
2 files changed, 39 insertions, 15 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h index 49afd8c466..a3ae1ddad7 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -2260,7 +2260,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 98b96cfc56..5e944f1aaa 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 = ¶m[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, ¶m_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; |