diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/cifs/CHANGES | 5 | ||||
-rw-r--r-- | fs/cifs/netmisc.c | 40 |
2 files changed, 39 insertions, 6 deletions
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index c65c9da863f3..6d3e736612ba 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES | |||
@@ -14,7 +14,10 @@ bigendian architectures. Fix possible memory corruption when | |||
14 | EAGAIN returned on kern_recvmsg. Return better error if server | 14 | EAGAIN returned on kern_recvmsg. Return better error if server |
15 | requires packet signing but client has disabled it. When mounted | 15 | requires packet signing but client has disabled it. When mounted |
16 | with cifsacl mount option - mode bits are approximated based | 16 | with cifsacl mount option - mode bits are approximated based |
17 | on the contents of the files ACL. | 17 | on the contents of the ACL of the file or directory. When cifs |
18 | mount helper is missing convert make sure that UNC name | ||
19 | has backslash (not forward slash) between ip address of server | ||
20 | and the share name. | ||
18 | 21 | ||
19 | Version 1.50 | 22 | Version 1.50 |
20 | ------------ | 23 | ------------ |
diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c index 4d35c034755a..e1704da43836 100644 --- a/fs/cifs/netmisc.c +++ b/fs/cifs/netmisc.c | |||
@@ -132,6 +132,34 @@ static const struct smb_to_posix_error mapping_table_ERRHRD[] = { | |||
132 | {0, 0} | 132 | {0, 0} |
133 | }; | 133 | }; |
134 | 134 | ||
135 | |||
136 | /* if the mount helper is missing we need to reverse the 1st slash | ||
137 | from '/' to backslash in order to format the UNC properly for | ||
138 | ip address parsing and for tree connect (unless the user | ||
139 | remembered to put the UNC name in properly). Fortunately we do | ||
140 | not have to call this twice (we check for IPv4 addresses | ||
141 | first, so it is already converted by the time we | ||
142 | try IPv6 addresses */ | ||
143 | static int canonicalize_unc(char *cp) | ||
144 | { | ||
145 | int i; | ||
146 | |||
147 | for (i = 0; i <= 46 /* INET6_ADDRSTRLEN */ ; i++) { | ||
148 | if (cp[i] == 0) | ||
149 | break; | ||
150 | if (cp[i] == '\\') | ||
151 | break; | ||
152 | if (cp[i] == '/') { | ||
153 | #ifdef CONFIG_CIFS_DEBUG2 | ||
154 | cFYI(1, ("change slash to backslash in malformed UNC")); | ||
155 | #endif | ||
156 | cp[i] = '\\'; | ||
157 | return 1; | ||
158 | } | ||
159 | } | ||
160 | return 0; | ||
161 | } | ||
162 | |||
135 | /* Convert string containing dotted ip address to binary form */ | 163 | /* Convert string containing dotted ip address to binary form */ |
136 | /* returns 0 if invalid address */ | 164 | /* returns 0 if invalid address */ |
137 | 165 | ||
@@ -141,11 +169,13 @@ cifs_inet_pton(int address_family, char *cp, void *dst) | |||
141 | int ret = 0; | 169 | int ret = 0; |
142 | 170 | ||
143 | /* calculate length by finding first slash or NULL */ | 171 | /* calculate length by finding first slash or NULL */ |
144 | /* BB Should we convert '/' slash to '\' here since it seems already | 172 | if (address_family == AF_INET) { |
145 | * done before this */ | 173 | ret = in4_pton(cp, -1 /* len */, dst, '\\', NULL); |
146 | if ( address_family == AF_INET ) { | 174 | if (ret == 0) { |
147 | ret = in4_pton(cp, -1 /* len */, dst , '\\', NULL); | 175 | if (canonicalize_unc(cp)) |
148 | } else if ( address_family == AF_INET6 ) { | 176 | ret = in4_pton(cp, -1, dst, '\\', NULL); |
177 | } | ||
178 | } else if (address_family == AF_INET6) { | ||
149 | ret = in6_pton(cp, -1 /* len */, dst , '\\', NULL); | 179 | ret = in6_pton(cp, -1 /* len */, dst , '\\', NULL); |
150 | } | 180 | } |
151 | #ifdef CONFIG_CIFS_DEBUG2 | 181 | #ifdef CONFIG_CIFS_DEBUG2 |