diff options
-rw-r--r-- | fs/cifs/cifsproto.h | 3 | ||||
-rw-r--r-- | fs/cifs/cifssmb.c | 36 | ||||
-rw-r--r-- | fs/cifs/link.c | 22 |
3 files changed, 20 insertions, 41 deletions
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 4167716d32f2..7d54a5a4dd55 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
@@ -260,8 +260,7 @@ extern int CIFSUnixCreateSymLink(const int xid, | |||
260 | const struct nls_table *nls_codepage); | 260 | const struct nls_table *nls_codepage); |
261 | extern int CIFSSMBUnixQuerySymLink(const int xid, | 261 | extern int CIFSSMBUnixQuerySymLink(const int xid, |
262 | struct cifsTconInfo *tcon, | 262 | struct cifsTconInfo *tcon, |
263 | const unsigned char *searchName, | 263 | const unsigned char *searchName, char **syminfo, |
264 | char *syminfo, const int buflen, | ||
265 | const struct nls_table *nls_codepage); | 264 | const struct nls_table *nls_codepage); |
266 | extern int CIFSSMBQueryReparseLinkInfo(const int xid, | 265 | extern int CIFSSMBQueryReparseLinkInfo(const int xid, |
267 | struct cifsTconInfo *tcon, | 266 | struct cifsTconInfo *tcon, |
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index f15848374cfa..dfb8e391d538 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
@@ -2382,8 +2382,7 @@ winCreateHardLinkRetry: | |||
2382 | 2382 | ||
2383 | int | 2383 | int |
2384 | CIFSSMBUnixQuerySymLink(const int xid, struct cifsTconInfo *tcon, | 2384 | CIFSSMBUnixQuerySymLink(const int xid, struct cifsTconInfo *tcon, |
2385 | const unsigned char *searchName, | 2385 | const unsigned char *searchName, char **symlinkinfo, |
2386 | char *symlinkinfo, const int buflen, | ||
2387 | const struct nls_table *nls_codepage) | 2386 | const struct nls_table *nls_codepage) |
2388 | { | 2387 | { |
2389 | /* SMB_QUERY_FILE_UNIX_LINK */ | 2388 | /* SMB_QUERY_FILE_UNIX_LINK */ |
@@ -2393,6 +2392,7 @@ CIFSSMBUnixQuerySymLink(const int xid, struct cifsTconInfo *tcon, | |||
2393 | int bytes_returned; | 2392 | int bytes_returned; |
2394 | int name_len; | 2393 | int name_len; |
2395 | __u16 params, byte_count; | 2394 | __u16 params, byte_count; |
2395 | char *data_start; | ||
2396 | 2396 | ||
2397 | cFYI(1, ("In QPathSymLinkInfo (Unix) for path %s", searchName)); | 2397 | cFYI(1, ("In QPathSymLinkInfo (Unix) for path %s", searchName)); |
2398 | 2398 | ||
@@ -2447,30 +2447,22 @@ querySymLinkRetry: | |||
2447 | /* decode response */ | 2447 | /* decode response */ |
2448 | 2448 | ||
2449 | rc = validate_t2((struct smb_t2_rsp *)pSMBr); | 2449 | rc = validate_t2((struct smb_t2_rsp *)pSMBr); |
2450 | if (rc || (pSMBr->ByteCount < 2)) | ||
2451 | /* BB also check enough total bytes returned */ | 2450 | /* BB also check enough total bytes returned */ |
2452 | rc = -EIO; /* bad smb */ | 2451 | if (rc || (pSMBr->ByteCount < 2)) |
2452 | rc = -EIO; | ||
2453 | else { | 2453 | else { |
2454 | __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); | 2454 | u16 count = le16_to_cpu(pSMBr->t2.DataCount); |
2455 | __u16 count = le16_to_cpu(pSMBr->t2.DataCount); | 2455 | |
2456 | data_start = ((char *) &pSMBr->hdr.Protocol) + | ||
2457 | le16_to_cpu(pSMBr->t2.DataOffset); | ||
2456 | 2458 | ||
2457 | if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) { | ||
2458 | name_len = UniStrnlen((wchar_t *) ((char *) | ||
2459 | &pSMBr->hdr.Protocol + data_offset), | ||
2460 | min_t(const int, buflen, count) / 2); | ||
2461 | /* BB FIXME investigate remapping reserved chars here */ | 2459 | /* BB FIXME investigate remapping reserved chars here */ |
2462 | cifs_strfromUCS_le(symlinkinfo, | 2460 | *symlinkinfo = cifs_strndup(data_start, count, |
2463 | (__le16 *) ((char *)&pSMBr->hdr.Protocol | 2461 | pSMBr->hdr.Flags2 & |
2464 | + data_offset), | 2462 | SMBFLG2_UNICODE, |
2465 | name_len, nls_codepage); | 2463 | nls_codepage); |
2466 | } else { | 2464 | if (!symlinkinfo) |
2467 | strncpy(symlinkinfo, | 2465 | rc = -ENOMEM; |
2468 | (char *) &pSMBr->hdr.Protocol + | ||
2469 | data_offset, | ||
2470 | min_t(const int, buflen, count)); | ||
2471 | } | ||
2472 | symlinkinfo[buflen] = 0; | ||
2473 | /* just in case so calling code does not go off the end of buffer */ | ||
2474 | } | 2466 | } |
2475 | } | 2467 | } |
2476 | cifs_buf_release(pSMB); | 2468 | cifs_buf_release(pSMB); |
diff --git a/fs/cifs/link.c b/fs/cifs/link.c index 63f644000ce5..e17a092f43ec 100644 --- a/fs/cifs/link.c +++ b/fs/cifs/link.c | |||
@@ -119,16 +119,11 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd) | |||
119 | full_path = build_path_from_dentry(direntry); | 119 | full_path = build_path_from_dentry(direntry); |
120 | 120 | ||
121 | if (!full_path) | 121 | if (!full_path) |
122 | goto out_no_free; | 122 | goto out; |
123 | 123 | ||
124 | cFYI(1, ("Full path: %s inode = 0x%p", full_path, inode)); | 124 | cFYI(1, ("Full path: %s inode = 0x%p", full_path, inode)); |
125 | cifs_sb = CIFS_SB(inode->i_sb); | 125 | cifs_sb = CIFS_SB(inode->i_sb); |
126 | pTcon = cifs_sb->tcon; | 126 | pTcon = cifs_sb->tcon; |
127 | target_path = kmalloc(PATH_MAX, GFP_KERNEL); | ||
128 | if (!target_path) { | ||
129 | target_path = ERR_PTR(-ENOMEM); | ||
130 | goto out; | ||
131 | } | ||
132 | 127 | ||
133 | /* We could change this to: | 128 | /* We could change this to: |
134 | if (pTcon->unix_ext) | 129 | if (pTcon->unix_ext) |
@@ -138,8 +133,7 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd) | |||
138 | 133 | ||
139 | if (pTcon->ses->capabilities & CAP_UNIX) | 134 | if (pTcon->ses->capabilities & CAP_UNIX) |
140 | rc = CIFSSMBUnixQuerySymLink(xid, pTcon, full_path, | 135 | rc = CIFSSMBUnixQuerySymLink(xid, pTcon, full_path, |
141 | target_path, | 136 | &target_path, |
142 | PATH_MAX-1, | ||
143 | cifs_sb->local_nls); | 137 | cifs_sb->local_nls); |
144 | else { | 138 | else { |
145 | /* BB add read reparse point symlink code here */ | 139 | /* BB add read reparse point symlink code here */ |
@@ -148,22 +142,16 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd) | |||
148 | /* BB Add MAC style xsymlink check here if enabled */ | 142 | /* BB Add MAC style xsymlink check here if enabled */ |
149 | } | 143 | } |
150 | 144 | ||
151 | if (rc == 0) { | 145 | if (rc != 0) { |
152 | |||
153 | /* BB Add special case check for Samba DFS symlinks */ | ||
154 | |||
155 | target_path[PATH_MAX-1] = 0; | ||
156 | } else { | ||
157 | kfree(target_path); | 146 | kfree(target_path); |
158 | target_path = ERR_PTR(rc); | 147 | target_path = ERR_PTR(rc); |
159 | } | 148 | } |
160 | 149 | ||
161 | out: | ||
162 | kfree(full_path); | 150 | kfree(full_path); |
163 | out_no_free: | 151 | out: |
164 | FreeXid(xid); | 152 | FreeXid(xid); |
165 | nd_set_link(nd, target_path); | 153 | nd_set_link(nd, target_path); |
166 | return NULL; /* No cookie */ | 154 | return NULL; |
167 | } | 155 | } |
168 | 156 | ||
169 | int | 157 | int |