aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/connect.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/connect.c')
-rw-r--r--fs/cifs/connect.c462
1 files changed, 213 insertions, 249 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index cc1a8604a790..a65d311d163a 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -64,8 +64,8 @@ struct smb_vol {
64 char *UNC; 64 char *UNC;
65 char *UNCip; 65 char *UNCip;
66 char *iocharset; /* local code page for mapping to and from Unicode */ 66 char *iocharset; /* local code page for mapping to and from Unicode */
67 char source_rfc1001_name[16]; /* netbios name of client */ 67 char source_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* clnt nb name */
68 char target_rfc1001_name[16]; /* netbios name of server for Win9x/ME */ 68 char target_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* srvr nb name */
69 uid_t cred_uid; 69 uid_t cred_uid;
70 uid_t linux_uid; 70 uid_t linux_uid;
71 gid_t linux_gid; 71 gid_t linux_gid;
@@ -115,8 +115,8 @@ struct smb_vol {
115#define TLINK_ERROR_EXPIRE (1 * HZ) 115#define TLINK_ERROR_EXPIRE (1 * HZ)
116#define TLINK_IDLE_EXPIRE (600 * HZ) 116#define TLINK_IDLE_EXPIRE (600 * HZ)
117 117
118static int ipv4_connect(struct TCP_Server_Info *server); 118static int ip_connect(struct TCP_Server_Info *server);
119static int ipv6_connect(struct TCP_Server_Info *server); 119static int generic_ip_connect(struct TCP_Server_Info *server);
120static void tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink); 120static void tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink);
121static void cifs_prune_tlinks(struct work_struct *work); 121static void cifs_prune_tlinks(struct work_struct *work);
122 122
@@ -200,10 +200,9 @@ cifs_reconnect(struct TCP_Server_Info *server)
200 while ((server->tcpStatus != CifsExiting) && 200 while ((server->tcpStatus != CifsExiting) &&
201 (server->tcpStatus != CifsGood)) { 201 (server->tcpStatus != CifsGood)) {
202 try_to_freeze(); 202 try_to_freeze();
203 if (server->addr.sockAddr6.sin6_family == AF_INET6) 203
204 rc = ipv6_connect(server); 204 /* we should try only the port we connected to before */
205 else 205 rc = generic_ip_connect(server);
206 rc = ipv4_connect(server);
207 if (rc) { 206 if (rc) {
208 cFYI(1, "reconnect error %d", rc); 207 cFYI(1, "reconnect error %d", rc);
209 msleep(3000); 208 msleep(3000);
@@ -477,7 +476,7 @@ incomplete_rcv:
477 * initialize frame) 476 * initialize frame)
478 */ 477 */
479 cifs_set_port((struct sockaddr *) 478 cifs_set_port((struct sockaddr *)
480 &server->addr.sockAddr, CIFS_PORT); 479 &server->dstaddr, CIFS_PORT);
481 cifs_reconnect(server); 480 cifs_reconnect(server);
482 csocket = server->ssocket; 481 csocket = server->ssocket;
483 wake_up(&server->response_q); 482 wake_up(&server->response_q);
@@ -817,11 +816,11 @@ cifs_parse_mount_options(char *options, const char *devname,
817 * informational, only used for servers that do not support 816 * informational, only used for servers that do not support
818 * port 445 and it can be overridden at mount time 817 * port 445 and it can be overridden at mount time
819 */ 818 */
820 memset(vol->source_rfc1001_name, 0x20, 15); 819 memset(vol->source_rfc1001_name, 0x20, RFC1001_NAME_LEN);
821 for (i = 0; i < strnlen(nodename, 15); i++) 820 for (i = 0; i < strnlen(nodename, RFC1001_NAME_LEN); i++)
822 vol->source_rfc1001_name[i] = toupper(nodename[i]); 821 vol->source_rfc1001_name[i] = toupper(nodename[i]);
823 822
824 vol->source_rfc1001_name[15] = 0; 823 vol->source_rfc1001_name[RFC1001_NAME_LEN] = 0;
825 /* null target name indicates to use *SMBSERVR default called name 824 /* null target name indicates to use *SMBSERVR default called name
826 if we end up sending RFC1001 session initialize */ 825 if we end up sending RFC1001 session initialize */
827 vol->target_rfc1001_name[0] = 0; 826 vol->target_rfc1001_name[0] = 0;
@@ -985,13 +984,11 @@ cifs_parse_mount_options(char *options, const char *devname,
985 return 1; 984 return 1;
986 } else if (strnicmp(value, "krb5", 4) == 0) { 985 } else if (strnicmp(value, "krb5", 4) == 0) {
987 vol->secFlg |= CIFSSEC_MAY_KRB5; 986 vol->secFlg |= CIFSSEC_MAY_KRB5;
988#ifdef CONFIG_CIFS_EXPERIMENTAL
989 } else if (strnicmp(value, "ntlmsspi", 8) == 0) { 987 } else if (strnicmp(value, "ntlmsspi", 8) == 0) {
990 vol->secFlg |= CIFSSEC_MAY_NTLMSSP | 988 vol->secFlg |= CIFSSEC_MAY_NTLMSSP |
991 CIFSSEC_MUST_SIGN; 989 CIFSSEC_MUST_SIGN;
992 } else if (strnicmp(value, "ntlmssp", 7) == 0) { 990 } else if (strnicmp(value, "ntlmssp", 7) == 0) {
993 vol->secFlg |= CIFSSEC_MAY_NTLMSSP; 991 vol->secFlg |= CIFSSEC_MAY_NTLMSSP;
994#endif
995 } else if (strnicmp(value, "ntlmv2i", 7) == 0) { 992 } else if (strnicmp(value, "ntlmv2i", 7) == 0) {
996 vol->secFlg |= CIFSSEC_MAY_NTLMV2 | 993 vol->secFlg |= CIFSSEC_MAY_NTLMV2 |
997 CIFSSEC_MUST_SIGN; 994 CIFSSEC_MUST_SIGN;
@@ -1168,22 +1165,22 @@ cifs_parse_mount_options(char *options, const char *devname,
1168 if (!value || !*value || (*value == ' ')) { 1165 if (!value || !*value || (*value == ' ')) {
1169 cFYI(1, "invalid (empty) netbiosname"); 1166 cFYI(1, "invalid (empty) netbiosname");
1170 } else { 1167 } else {
1171 memset(vol->source_rfc1001_name, 0x20, 15); 1168 memset(vol->source_rfc1001_name, 0x20,
1172 for (i = 0; i < 15; i++) { 1169 RFC1001_NAME_LEN);
1173 /* BB are there cases in which a comma can be 1170 /*
1174 valid in this workstation netbios name (and need 1171 * FIXME: are there cases in which a comma can
1175 special handling)? */ 1172 * be valid in workstation netbios name (and
1176 1173 * need special handling)?
1177 /* We do not uppercase netbiosname for user */ 1174 */
1175 for (i = 0; i < RFC1001_NAME_LEN; i++) {
1176 /* don't ucase netbiosname for user */
1178 if (value[i] == 0) 1177 if (value[i] == 0)
1179 break; 1178 break;
1180 else 1179 vol->source_rfc1001_name[i] = value[i];
1181 vol->source_rfc1001_name[i] =
1182 value[i];
1183 } 1180 }
1184 /* The string has 16th byte zero still from 1181 /* The string has 16th byte zero still from
1185 set at top of the function */ 1182 set at top of the function */
1186 if ((i == 15) && (value[i] != 0)) 1183 if (i == RFC1001_NAME_LEN && value[i] != 0)
1187 printk(KERN_WARNING "CIFS: netbiosname" 1184 printk(KERN_WARNING "CIFS: netbiosname"
1188 " longer than 15 truncated.\n"); 1185 " longer than 15 truncated.\n");
1189 } 1186 }
@@ -1193,7 +1190,8 @@ cifs_parse_mount_options(char *options, const char *devname,
1193 cFYI(1, "empty server netbiosname specified"); 1190 cFYI(1, "empty server netbiosname specified");
1194 } else { 1191 } else {
1195 /* last byte, type, is 0x20 for servr type */ 1192 /* last byte, type, is 0x20 for servr type */
1196 memset(vol->target_rfc1001_name, 0x20, 16); 1193 memset(vol->target_rfc1001_name, 0x20,
1194 RFC1001_NAME_LEN_WITH_NULL);
1197 1195
1198 for (i = 0; i < 15; i++) { 1196 for (i = 0; i < 15; i++) {
1199 /* BB are there cases in which a comma can be 1197 /* BB are there cases in which a comma can be
@@ -1210,7 +1208,7 @@ cifs_parse_mount_options(char *options, const char *devname,
1210 } 1208 }
1211 /* The string has 16th byte zero still from 1209 /* The string has 16th byte zero still from
1212 set at top of the function */ 1210 set at top of the function */
1213 if ((i == 15) && (value[i] != 0)) 1211 if (i == RFC1001_NAME_LEN && value[i] != 0)
1214 printk(KERN_WARNING "CIFS: server net" 1212 printk(KERN_WARNING "CIFS: server net"
1215 "biosname longer than 15 truncated.\n"); 1213 "biosname longer than 15 truncated.\n");
1216 } 1214 }
@@ -1341,10 +1339,8 @@ cifs_parse_mount_options(char *options, const char *devname,
1341 vol->no_psx_acl = 0; 1339 vol->no_psx_acl = 0;
1342 } else if (strnicmp(data, "noacl", 5) == 0) { 1340 } else if (strnicmp(data, "noacl", 5) == 0) {
1343 vol->no_psx_acl = 1; 1341 vol->no_psx_acl = 1;
1344#ifdef CONFIG_CIFS_EXPERIMENTAL
1345 } else if (strnicmp(data, "locallease", 6) == 0) { 1342 } else if (strnicmp(data, "locallease", 6) == 0) {
1346 vol->local_lease = 1; 1343 vol->local_lease = 1;
1347#endif
1348 } else if (strnicmp(data, "sign", 4) == 0) { 1344 } else if (strnicmp(data, "sign", 4) == 0) {
1349 vol->secFlg |= CIFSSEC_MUST_SIGN; 1345 vol->secFlg |= CIFSSEC_MUST_SIGN;
1350 } else if (strnicmp(data, "seal", 4) == 0) { 1346 } else if (strnicmp(data, "seal", 4) == 0) {
@@ -1454,35 +1450,71 @@ srcip_matches(struct sockaddr *srcaddr, struct sockaddr *rhs)
1454 } 1450 }
1455} 1451}
1456 1452
1453/*
1454 * If no port is specified in addr structure, we try to match with 445 port
1455 * and if it fails - with 139 ports. It should be called only if address
1456 * families of server and addr are equal.
1457 */
1458static bool
1459match_port(struct TCP_Server_Info *server, struct sockaddr *addr)
1460{
1461 unsigned short int port, *sport;
1462
1463 switch (addr->sa_family) {
1464 case AF_INET:
1465 sport = &((struct sockaddr_in *) &server->dstaddr)->sin_port;
1466 port = ((struct sockaddr_in *) addr)->sin_port;
1467 break;
1468 case AF_INET6:
1469 sport = &((struct sockaddr_in6 *) &server->dstaddr)->sin6_port;
1470 port = ((struct sockaddr_in6 *) addr)->sin6_port;
1471 break;
1472 default:
1473 WARN_ON(1);
1474 return false;
1475 }
1476
1477 if (!port) {
1478 port = htons(CIFS_PORT);
1479 if (port == *sport)
1480 return true;
1481
1482 port = htons(RFC1001_PORT);
1483 }
1484
1485 return port == *sport;
1486}
1457 1487
1458static bool 1488static bool
1459match_address(struct TCP_Server_Info *server, struct sockaddr *addr, 1489match_address(struct TCP_Server_Info *server, struct sockaddr *addr,
1460 struct sockaddr *srcaddr) 1490 struct sockaddr *srcaddr)
1461{ 1491{
1462 struct sockaddr_in *addr4 = (struct sockaddr_in *)addr;
1463 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)addr;
1464
1465 switch (addr->sa_family) { 1492 switch (addr->sa_family) {
1466 case AF_INET: 1493 case AF_INET: {
1467 if (addr4->sin_addr.s_addr != 1494 struct sockaddr_in *addr4 = (struct sockaddr_in *)addr;
1468 server->addr.sockAddr.sin_addr.s_addr) 1495 struct sockaddr_in *srv_addr4 =
1469 return false; 1496 (struct sockaddr_in *)&server->dstaddr;
1470 if (addr4->sin_port && 1497
1471 addr4->sin_port != server->addr.sockAddr.sin_port) 1498 if (addr4->sin_addr.s_addr != srv_addr4->sin_addr.s_addr)
1472 return false; 1499 return false;
1473 break; 1500 break;
1474 case AF_INET6: 1501 }
1502 case AF_INET6: {
1503 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)addr;
1504 struct sockaddr_in6 *srv_addr6 =
1505 (struct sockaddr_in6 *)&server->dstaddr;
1506
1475 if (!ipv6_addr_equal(&addr6->sin6_addr, 1507 if (!ipv6_addr_equal(&addr6->sin6_addr,
1476 &server->addr.sockAddr6.sin6_addr)) 1508 &srv_addr6->sin6_addr))
1477 return false; 1509 return false;
1478 if (addr6->sin6_scope_id != 1510 if (addr6->sin6_scope_id != srv_addr6->sin6_scope_id)
1479 server->addr.sockAddr6.sin6_scope_id)
1480 return false;
1481 if (addr6->sin6_port &&
1482 addr6->sin6_port != server->addr.sockAddr6.sin6_port)
1483 return false; 1511 return false;
1484 break; 1512 break;
1485 } 1513 }
1514 default:
1515 WARN_ON(1);
1516 return false; /* don't expect to be here */
1517 }
1486 1518
1487 if (!srcip_matches(srcaddr, (struct sockaddr *)&server->srcaddr)) 1519 if (!srcip_matches(srcaddr, (struct sockaddr *)&server->srcaddr))
1488 return false; 1520 return false;
@@ -1549,6 +1581,9 @@ cifs_find_tcp_session(struct sockaddr *addr, struct smb_vol *vol)
1549 (struct sockaddr *)&vol->srcaddr)) 1581 (struct sockaddr *)&vol->srcaddr))
1550 continue; 1582 continue;
1551 1583
1584 if (!match_port(server, addr))
1585 continue;
1586
1552 if (!match_security(server, vol)) 1587 if (!match_security(server, vol))
1553 continue; 1588 continue;
1554 1589
@@ -1681,14 +1716,13 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
1681 cFYI(1, "attempting ipv6 connect"); 1716 cFYI(1, "attempting ipv6 connect");
1682 /* BB should we allow ipv6 on port 139? */ 1717 /* BB should we allow ipv6 on port 139? */
1683 /* other OS never observed in Wild doing 139 with v6 */ 1718 /* other OS never observed in Wild doing 139 with v6 */
1684 memcpy(&tcp_ses->addr.sockAddr6, sin_server6, 1719 memcpy(&tcp_ses->dstaddr, sin_server6,
1685 sizeof(struct sockaddr_in6)); 1720 sizeof(struct sockaddr_in6));
1686 rc = ipv6_connect(tcp_ses); 1721 } else
1687 } else { 1722 memcpy(&tcp_ses->dstaddr, sin_server,
1688 memcpy(&tcp_ses->addr.sockAddr, sin_server, 1723 sizeof(struct sockaddr_in));
1689 sizeof(struct sockaddr_in)); 1724
1690 rc = ipv4_connect(tcp_ses); 1725 rc = ip_connect(tcp_ses);
1691 }
1692 if (rc < 0) { 1726 if (rc < 0) {
1693 cERROR(1, "Error connecting to socket. Aborting operation"); 1727 cERROR(1, "Error connecting to socket. Aborting operation");
1694 goto out_err_crypto_release; 1728 goto out_err_crypto_release;
@@ -1793,6 +1827,8 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
1793{ 1827{
1794 int rc = -ENOMEM, xid; 1828 int rc = -ENOMEM, xid;
1795 struct cifsSesInfo *ses; 1829 struct cifsSesInfo *ses;
1830 struct sockaddr_in *addr = (struct sockaddr_in *)&server->dstaddr;
1831 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&server->dstaddr;
1796 1832
1797 xid = GetXid(); 1833 xid = GetXid();
1798 1834
@@ -1836,12 +1872,10 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
1836 1872
1837 /* new SMB session uses our server ref */ 1873 /* new SMB session uses our server ref */
1838 ses->server = server; 1874 ses->server = server;
1839 if (server->addr.sockAddr6.sin6_family == AF_INET6) 1875 if (server->dstaddr.ss_family == AF_INET6)
1840 sprintf(ses->serverName, "%pI6", 1876 sprintf(ses->serverName, "%pI6", &addr6->sin6_addr);
1841 &server->addr.sockAddr6.sin6_addr);
1842 else 1877 else
1843 sprintf(ses->serverName, "%pI4", 1878 sprintf(ses->serverName, "%pI4", &addr->sin_addr);
1844 &server->addr.sockAddr.sin_addr.s_addr);
1845 1879
1846 if (volume_info->username) 1880 if (volume_info->username)
1847 strncpy(ses->userName, volume_info->username, 1881 strncpy(ses->userName, volume_info->username,
@@ -2136,19 +2170,106 @@ bind_socket(struct TCP_Server_Info *server)
2136} 2170}
2137 2171
2138static int 2172static int
2139ipv4_connect(struct TCP_Server_Info *server) 2173ip_rfc1001_connect(struct TCP_Server_Info *server)
2174{
2175 int rc = 0;
2176 /*
2177 * some servers require RFC1001 sessinit before sending
2178 * negprot - BB check reconnection in case where second
2179 * sessinit is sent but no second negprot
2180 */
2181 struct rfc1002_session_packet *ses_init_buf;
2182 struct smb_hdr *smb_buf;
2183 ses_init_buf = kzalloc(sizeof(struct rfc1002_session_packet),
2184 GFP_KERNEL);
2185 if (ses_init_buf) {
2186 ses_init_buf->trailer.session_req.called_len = 32;
2187
2188 if (server->server_RFC1001_name &&
2189 server->server_RFC1001_name[0] != 0)
2190 rfc1002mangle(ses_init_buf->trailer.
2191 session_req.called_name,
2192 server->server_RFC1001_name,
2193 RFC1001_NAME_LEN_WITH_NULL);
2194 else
2195 rfc1002mangle(ses_init_buf->trailer.
2196 session_req.called_name,
2197 DEFAULT_CIFS_CALLED_NAME,
2198 RFC1001_NAME_LEN_WITH_NULL);
2199
2200 ses_init_buf->trailer.session_req.calling_len = 32;
2201
2202 /*
2203 * calling name ends in null (byte 16) from old smb
2204 * convention.
2205 */
2206 if (server->workstation_RFC1001_name &&
2207 server->workstation_RFC1001_name[0] != 0)
2208 rfc1002mangle(ses_init_buf->trailer.
2209 session_req.calling_name,
2210 server->workstation_RFC1001_name,
2211 RFC1001_NAME_LEN_WITH_NULL);
2212 else
2213 rfc1002mangle(ses_init_buf->trailer.
2214 session_req.calling_name,
2215 "LINUX_CIFS_CLNT",
2216 RFC1001_NAME_LEN_WITH_NULL);
2217
2218 ses_init_buf->trailer.session_req.scope1 = 0;
2219 ses_init_buf->trailer.session_req.scope2 = 0;
2220 smb_buf = (struct smb_hdr *)ses_init_buf;
2221
2222 /* sizeof RFC1002_SESSION_REQUEST with no scope */
2223 smb_buf->smb_buf_length = 0x81000044;
2224 rc = smb_send(server, smb_buf, 0x44);
2225 kfree(ses_init_buf);
2226 /*
2227 * RFC1001 layer in at least one server
2228 * requires very short break before negprot
2229 * presumably because not expecting negprot
2230 * to follow so fast. This is a simple
2231 * solution that works without
2232 * complicating the code and causes no
2233 * significant slowing down on mount
2234 * for everyone else
2235 */
2236 usleep_range(1000, 2000);
2237 }
2238 /*
2239 * else the negprot may still work without this
2240 * even though malloc failed
2241 */
2242
2243 return rc;
2244}
2245
2246static int
2247generic_ip_connect(struct TCP_Server_Info *server)
2140{ 2248{
2141 int rc = 0; 2249 int rc = 0;
2142 int val; 2250 unsigned short int sport;
2143 bool connected = false; 2251 int slen, sfamily;
2144 __be16 orig_port = 0;
2145 struct socket *socket = server->ssocket; 2252 struct socket *socket = server->ssocket;
2253 struct sockaddr *saddr;
2254
2255 saddr = (struct sockaddr *) &server->dstaddr;
2256
2257 if (server->dstaddr.ss_family == AF_INET6) {
2258 sport = ((struct sockaddr_in6 *) saddr)->sin6_port;
2259 slen = sizeof(struct sockaddr_in6);
2260 sfamily = AF_INET6;
2261 } else {
2262 sport = ((struct sockaddr_in *) saddr)->sin_port;
2263 slen = sizeof(struct sockaddr_in);
2264 sfamily = AF_INET;
2265 }
2146 2266
2147 if (socket == NULL) { 2267 if (socket == NULL) {
2148 rc = sock_create_kern(PF_INET, SOCK_STREAM, 2268 rc = sock_create_kern(sfamily, SOCK_STREAM,
2149 IPPROTO_TCP, &socket); 2269 IPPROTO_TCP, &socket);
2150 if (rc < 0) { 2270 if (rc < 0) {
2151 cERROR(1, "Error %d creating socket", rc); 2271 cERROR(1, "Error %d creating socket", rc);
2272 server->ssocket = NULL;
2152 return rc; 2273 return rc;
2153 } 2274 }
2154 2275
@@ -2156,63 +2277,28 @@ ipv4_connect(struct TCP_Server_Info *server)
2156 cFYI(1, "Socket created"); 2277 cFYI(1, "Socket created");
2157 server->ssocket = socket; 2278 server->ssocket = socket;
2158 socket->sk->sk_allocation = GFP_NOFS; 2279 socket->sk->sk_allocation = GFP_NOFS;
2159 cifs_reclassify_socket4(socket); 2280 if (sfamily == AF_INET6)
2281 cifs_reclassify_socket6(socket);
2282 else
2283 cifs_reclassify_socket4(socket);
2160 } 2284 }
2161 2285
2162 rc = bind_socket(server); 2286 rc = bind_socket(server);
2163 if (rc < 0) 2287 if (rc < 0)
2164 return rc; 2288 return rc;
2165 2289
2166 /* user overrode default port */ 2290 rc = socket->ops->connect(socket, saddr, slen, 0);
2167 if (server->addr.sockAddr.sin_port) { 2291 if (rc < 0) {
2168 rc = socket->ops->connect(socket, (struct sockaddr *) 2292 cFYI(1, "Error %d connecting to server", rc);
2169 &server->addr.sockAddr,
2170 sizeof(struct sockaddr_in), 0);
2171 if (rc >= 0)
2172 connected = true;
2173 }
2174
2175 if (!connected) {
2176 /* save original port so we can retry user specified port
2177 later if fall back ports fail this time */
2178 orig_port = server->addr.sockAddr.sin_port;
2179
2180 /* do not retry on the same port we just failed on */
2181 if (server->addr.sockAddr.sin_port != htons(CIFS_PORT)) {
2182 server->addr.sockAddr.sin_port = htons(CIFS_PORT);
2183 rc = socket->ops->connect(socket,
2184 (struct sockaddr *)
2185 &server->addr.sockAddr,
2186 sizeof(struct sockaddr_in), 0);
2187 if (rc >= 0)
2188 connected = true;
2189 }
2190 }
2191 if (!connected) {
2192 server->addr.sockAddr.sin_port = htons(RFC1001_PORT);
2193 rc = socket->ops->connect(socket, (struct sockaddr *)
2194 &server->addr.sockAddr,
2195 sizeof(struct sockaddr_in), 0);
2196 if (rc >= 0)
2197 connected = true;
2198 }
2199
2200 /* give up here - unless we want to retry on different
2201 protocol families some day */
2202 if (!connected) {
2203 if (orig_port)
2204 server->addr.sockAddr.sin_port = orig_port;
2205 cFYI(1, "Error %d connecting to server via ipv4", rc);
2206 sock_release(socket); 2293 sock_release(socket);
2207 server->ssocket = NULL; 2294 server->ssocket = NULL;
2208 return rc; 2295 return rc;
2209 } 2296 }
2210 2297
2211
2212 /* 2298 /*
2213 * Eventually check for other socket options to change from 2299 * Eventually check for other socket options to change from
2214 * the default. sock_setsockopt not used because it expects 2300 * the default. sock_setsockopt not used because it expects
2215 * user space buffer 2301 * user space buffer
2216 */ 2302 */
2217 socket->sk->sk_rcvtimeo = 7 * HZ; 2303 socket->sk->sk_rcvtimeo = 7 * HZ;
2218 socket->sk->sk_sndtimeo = 5 * HZ; 2304 socket->sk->sk_sndtimeo = 5 * HZ;
@@ -2226,7 +2312,7 @@ ipv4_connect(struct TCP_Server_Info *server)
2226 } 2312 }
2227 2313
2228 if (server->tcp_nodelay) { 2314 if (server->tcp_nodelay) {
2229 val = 1; 2315 int val = 1;
2230 rc = kernel_setsockopt(socket, SOL_TCP, TCP_NODELAY, 2316 rc = kernel_setsockopt(socket, SOL_TCP, TCP_NODELAY,
2231 (char *)&val, sizeof(val)); 2317 (char *)&val, sizeof(val));
2232 if (rc) 2318 if (rc)
@@ -2237,161 +2323,39 @@ ipv4_connect(struct TCP_Server_Info *server)
2237 socket->sk->sk_sndbuf, 2323 socket->sk->sk_sndbuf,
2238 socket->sk->sk_rcvbuf, socket->sk->sk_rcvtimeo); 2324 socket->sk->sk_rcvbuf, socket->sk->sk_rcvtimeo);
2239 2325
2240 /* send RFC1001 sessinit */ 2326 if (sport == htons(RFC1001_PORT))
2241 if (server->addr.sockAddr.sin_port == htons(RFC1001_PORT)) { 2327 rc = ip_rfc1001_connect(server);
2242 /* some servers require RFC1001 sessinit before sending
2243 negprot - BB check reconnection in case where second
2244 sessinit is sent but no second negprot */
2245 struct rfc1002_session_packet *ses_init_buf;
2246 struct smb_hdr *smb_buf;
2247 ses_init_buf = kzalloc(sizeof(struct rfc1002_session_packet),
2248 GFP_KERNEL);
2249 if (ses_init_buf) {
2250 ses_init_buf->trailer.session_req.called_len = 32;
2251 if (server->server_RFC1001_name &&
2252 server->server_RFC1001_name[0] != 0)
2253 rfc1002mangle(ses_init_buf->trailer.
2254 session_req.called_name,
2255 server->server_RFC1001_name,
2256 RFC1001_NAME_LEN_WITH_NULL);
2257 else
2258 rfc1002mangle(ses_init_buf->trailer.
2259 session_req.called_name,
2260 DEFAULT_CIFS_CALLED_NAME,
2261 RFC1001_NAME_LEN_WITH_NULL);
2262
2263 ses_init_buf->trailer.session_req.calling_len = 32;
2264
2265 /* calling name ends in null (byte 16) from old smb
2266 convention. */
2267 if (server->workstation_RFC1001_name &&
2268 server->workstation_RFC1001_name[0] != 0)
2269 rfc1002mangle(ses_init_buf->trailer.
2270 session_req.calling_name,
2271 server->workstation_RFC1001_name,
2272 RFC1001_NAME_LEN_WITH_NULL);
2273 else
2274 rfc1002mangle(ses_init_buf->trailer.
2275 session_req.calling_name,
2276 "LINUX_CIFS_CLNT",
2277 RFC1001_NAME_LEN_WITH_NULL);
2278
2279 ses_init_buf->trailer.session_req.scope1 = 0;
2280 ses_init_buf->trailer.session_req.scope2 = 0;
2281 smb_buf = (struct smb_hdr *)ses_init_buf;
2282 /* sizeof RFC1002_SESSION_REQUEST with no scope */
2283 smb_buf->smb_buf_length = 0x81000044;
2284 rc = smb_send(server, smb_buf, 0x44);
2285 kfree(ses_init_buf);
2286 msleep(1); /* RFC1001 layer in at least one server
2287 requires very short break before negprot
2288 presumably because not expecting negprot
2289 to follow so fast. This is a simple
2290 solution that works without
2291 complicating the code and causes no
2292 significant slowing down on mount
2293 for everyone else */
2294 }
2295 /* else the negprot may still work without this
2296 even though malloc failed */
2297
2298 }
2299 2328
2300 return rc; 2329 return rc;
2301} 2330}
2302 2331
2303static int 2332static int
2304ipv6_connect(struct TCP_Server_Info *server) 2333ip_connect(struct TCP_Server_Info *server)
2305{ 2334{
2306 int rc = 0; 2335 unsigned short int *sport;
2307 int val; 2336 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&server->dstaddr;
2308 bool connected = false; 2337 struct sockaddr_in *addr = (struct sockaddr_in *)&server->dstaddr;
2309 __be16 orig_port = 0;
2310 struct socket *socket = server->ssocket;
2311 2338
2312 if (socket == NULL) { 2339 if (server->dstaddr.ss_family == AF_INET6)
2313 rc = sock_create_kern(PF_INET6, SOCK_STREAM, 2340 sport = &addr6->sin6_port;
2314 IPPROTO_TCP, &socket); 2341 else
2315 if (rc < 0) { 2342 sport = &addr->sin_port;
2316 cERROR(1, "Error %d creating ipv6 socket", rc);
2317 socket = NULL;
2318 return rc;
2319 }
2320 2343
2321 /* BB other socket options to set KEEPALIVE, NODELAY? */ 2344 if (*sport == 0) {
2322 cFYI(1, "ipv6 Socket created"); 2345 int rc;
2323 server->ssocket = socket;
2324 socket->sk->sk_allocation = GFP_NOFS;
2325 cifs_reclassify_socket6(socket);
2326 }
2327 2346
2328 rc = bind_socket(server); 2347 /* try with 445 port at first */
2329 if (rc < 0) 2348 *sport = htons(CIFS_PORT);
2330 return rc;
2331 2349
2332 /* user overrode default port */ 2350 rc = generic_ip_connect(server);
2333 if (server->addr.sockAddr6.sin6_port) {
2334 rc = socket->ops->connect(socket,
2335 (struct sockaddr *) &server->addr.sockAddr6,
2336 sizeof(struct sockaddr_in6), 0);
2337 if (rc >= 0)
2338 connected = true;
2339 }
2340
2341 if (!connected) {
2342 /* save original port so we can retry user specified port
2343 later if fall back ports fail this time */
2344
2345 orig_port = server->addr.sockAddr6.sin6_port;
2346 /* do not retry on the same port we just failed on */
2347 if (server->addr.sockAddr6.sin6_port != htons(CIFS_PORT)) {
2348 server->addr.sockAddr6.sin6_port = htons(CIFS_PORT);
2349 rc = socket->ops->connect(socket, (struct sockaddr *)
2350 &server->addr.sockAddr6,
2351 sizeof(struct sockaddr_in6), 0);
2352 if (rc >= 0)
2353 connected = true;
2354 }
2355 }
2356 if (!connected) {
2357 server->addr.sockAddr6.sin6_port = htons(RFC1001_PORT);
2358 rc = socket->ops->connect(socket, (struct sockaddr *)
2359 &server->addr.sockAddr6,
2360 sizeof(struct sockaddr_in6), 0);
2361 if (rc >= 0) 2351 if (rc >= 0)
2362 connected = true; 2352 return rc;
2363 }
2364
2365 /* give up here - unless we want to retry on different
2366 protocol families some day */
2367 if (!connected) {
2368 if (orig_port)
2369 server->addr.sockAddr6.sin6_port = orig_port;
2370 cFYI(1, "Error %d connecting to server via ipv6", rc);
2371 sock_release(socket);
2372 server->ssocket = NULL;
2373 return rc;
2374 }
2375
2376 /*
2377 * Eventually check for other socket options to change from
2378 * the default. sock_setsockopt not used because it expects
2379 * user space buffer
2380 */
2381 socket->sk->sk_rcvtimeo = 7 * HZ;
2382 socket->sk->sk_sndtimeo = 5 * HZ;
2383 2353
2384 if (server->tcp_nodelay) { 2354 /* if it failed, try with 139 port */
2385 val = 1; 2355 *sport = htons(RFC1001_PORT);
2386 rc = kernel_setsockopt(socket, SOL_TCP, TCP_NODELAY,
2387 (char *)&val, sizeof(val));
2388 if (rc)
2389 cFYI(1, "set TCP_NODELAY socket option error %d", rc);
2390 } 2356 }
2391 2357
2392 server->ssocket = socket; 2358 return generic_ip_connect(server);
2393
2394 return rc;
2395} 2359}
2396 2360
2397void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon, 2361void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,