aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/cifs_dfs_ref.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-12-28 15:37:14 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2008-12-28 15:37:14 -0500
commit54a696bd07c14d3b1192d03ce7269bc59b45209a (patch)
tree2da3a0ce28e08bde17a0fba8bb807480849cf410 /fs/cifs/cifs_dfs_ref.c
parent1d248b2593e92db6c51ca07235985a95c625a93f (diff)
parent359d67d6ad054ae11ad459665fdfb883aca87782 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6: (31 commits) [CIFS] Remove redundant test [CIFS] make sure that DFS pathnames are properly formed Remove an already-checked error condition in SendReceiveBlockingLock Streamline SendReceiveBlockingLock: Use "goto out:" in an error condition Streamline SendReceiveBlockingLock: Use "goto out:" in an error condition [CIFS] Streamline SendReceive[2] by using "goto out:" in an error condition Slightly streamline SendReceive[2] Check the return value of cifs_sign_smb[2] [CIFS] Cleanup: Move the check for too large R/W requests [CIFS] Slightly simplify wait_for_free_request(), remove an unnecessary "else" branch Simplify allocate_mid() slightly: Remove some unnecessary "else" branches [CIFS] In SendReceive, move consistency check out of the mutexed region cifs: store password in tcon cifs: have calc_lanman_hash take more granular args cifs: zero out session password before freeing it cifs: fix wait_for_response to time out sleeping processes correctly [CIFS] Can not mount with prefixpath if root directory of share is inaccessible [CIFS] various minor cleanups pointed out by checkpatch script [CIFS] fix typo [CIFS] remove sparse warning ... Fix trivial conflict in fs/cifs/cifs_fs_sb.h due to comment changes for the CIFS_MOUNT_xyz bit definitions between cifs updates and security updates.
Diffstat (limited to 'fs/cifs/cifs_dfs_ref.c')
-rw-r--r--fs/cifs/cifs_dfs_ref.c48
1 files changed, 36 insertions, 12 deletions
diff --git a/fs/cifs/cifs_dfs_ref.c b/fs/cifs/cifs_dfs_ref.c
index e1c18362ba46..85c0a74d034d 100644
--- a/fs/cifs/cifs_dfs_ref.c
+++ b/fs/cifs/cifs_dfs_ref.c
@@ -122,7 +122,7 @@ static char *compose_mount_options(const char *sb_mountdata,
122 char **devname) 122 char **devname)
123{ 123{
124 int rc; 124 int rc;
125 char *mountdata; 125 char *mountdata = NULL;
126 int md_len; 126 int md_len;
127 char *tkn_e; 127 char *tkn_e;
128 char *srvIP = NULL; 128 char *srvIP = NULL;
@@ -136,10 +136,9 @@ static char *compose_mount_options(const char *sb_mountdata,
136 *devname = cifs_get_share_name(ref->node_name); 136 *devname = cifs_get_share_name(ref->node_name);
137 rc = dns_resolve_server_name_to_ip(*devname, &srvIP); 137 rc = dns_resolve_server_name_to_ip(*devname, &srvIP);
138 if (rc != 0) { 138 if (rc != 0) {
139 cERROR(1, ("%s: Failed to resolve server part of %s to IP", 139 cERROR(1, ("%s: Failed to resolve server part of %s to IP: %d",
140 __func__, *devname)); 140 __func__, *devname, rc));;
141 mountdata = ERR_PTR(rc); 141 goto compose_mount_options_err;
142 goto compose_mount_options_out;
143 } 142 }
144 /* md_len = strlen(...) + 12 for 'sep+prefixpath=' 143 /* md_len = strlen(...) + 12 for 'sep+prefixpath='
145 * assuming that we have 'unc=' and 'ip=' in 144 * assuming that we have 'unc=' and 'ip=' in
@@ -149,8 +148,8 @@ static char *compose_mount_options(const char *sb_mountdata,
149 strlen(ref->node_name) + 12; 148 strlen(ref->node_name) + 12;
150 mountdata = kzalloc(md_len+1, GFP_KERNEL); 149 mountdata = kzalloc(md_len+1, GFP_KERNEL);
151 if (mountdata == NULL) { 150 if (mountdata == NULL) {
152 mountdata = ERR_PTR(-ENOMEM); 151 rc = -ENOMEM;
153 goto compose_mount_options_out; 152 goto compose_mount_options_err;
154 } 153 }
155 154
156 /* copy all options except of unc,ip,prefixpath */ 155 /* copy all options except of unc,ip,prefixpath */
@@ -197,18 +196,32 @@ static char *compose_mount_options(const char *sb_mountdata,
197 196
198 /* find & copy prefixpath */ 197 /* find & copy prefixpath */
199 tkn_e = strchr(ref->node_name + 2, '\\'); 198 tkn_e = strchr(ref->node_name + 2, '\\');
200 if (tkn_e == NULL) /* invalid unc, missing share name*/ 199 if (tkn_e == NULL) {
201 goto compose_mount_options_out; 200 /* invalid unc, missing share name*/
201 rc = -EINVAL;
202 goto compose_mount_options_err;
203 }
202 204
205 /*
206 * this function gives us a path with a double backslash prefix. We
207 * require a single backslash for DFS. Temporarily increment fullpath
208 * to put it in the proper form and decrement before freeing it.
209 */
203 fullpath = build_path_from_dentry(dentry); 210 fullpath = build_path_from_dentry(dentry);
211 if (!fullpath) {
212 rc = -ENOMEM;
213 goto compose_mount_options_err;
214 }
215 ++fullpath;
204 tkn_e = strchr(tkn_e + 1, '\\'); 216 tkn_e = strchr(tkn_e + 1, '\\');
205 if (tkn_e || strlen(fullpath) - (ref->path_consumed)) { 217 if (tkn_e || (strlen(fullpath) - ref->path_consumed)) {
206 strncat(mountdata, &sep, 1); 218 strncat(mountdata, &sep, 1);
207 strcat(mountdata, "prefixpath="); 219 strcat(mountdata, "prefixpath=");
208 if (tkn_e) 220 if (tkn_e)
209 strcat(mountdata, tkn_e + 1); 221 strcat(mountdata, tkn_e + 1);
210 strcat(mountdata, fullpath + (ref->path_consumed)); 222 strcat(mountdata, fullpath + ref->path_consumed);
211 } 223 }
224 --fullpath;
212 kfree(fullpath); 225 kfree(fullpath);
213 226
214 /*cFYI(1,("%s: parent mountdata: %s", __func__,sb_mountdata));*/ 227 /*cFYI(1,("%s: parent mountdata: %s", __func__,sb_mountdata));*/
@@ -217,6 +230,11 @@ static char *compose_mount_options(const char *sb_mountdata,
217compose_mount_options_out: 230compose_mount_options_out:
218 kfree(srvIP); 231 kfree(srvIP);
219 return mountdata; 232 return mountdata;
233
234compose_mount_options_err:
235 kfree(mountdata);
236 mountdata = ERR_PTR(rc);
237 goto compose_mount_options_out;
220} 238}
221 239
222 240
@@ -309,13 +327,19 @@ cifs_dfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd)
309 goto out_err; 327 goto out_err;
310 } 328 }
311 329
330 /*
331 * The MSDFS spec states that paths in DFS referral requests and
332 * responses must be prefixed by a single '\' character instead of
333 * the double backslashes usually used in the UNC. This function
334 * gives us the latter, so we must adjust the result.
335 */
312 full_path = build_path_from_dentry(dentry); 336 full_path = build_path_from_dentry(dentry);
313 if (full_path == NULL) { 337 if (full_path == NULL) {
314 rc = -ENOMEM; 338 rc = -ENOMEM;
315 goto out_err; 339 goto out_err;
316 } 340 }
317 341
318 rc = get_dfs_path(xid, ses , full_path, cifs_sb->local_nls, 342 rc = get_dfs_path(xid, ses , full_path + 1, cifs_sb->local_nls,
319 &num_referrals, &referrals, 343 &num_referrals, &referrals,
320 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 344 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
321 345