aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/cache.c16
-rw-r--r--fs/cifs/cifs_spnego.c10
-rw-r--r--fs/cifs/cifsfs.c15
-rw-r--r--fs/cifs/cifsglob.h5
-rw-r--r--fs/cifs/connect.c421
-rw-r--r--fs/cifs/dir.c7
-rw-r--r--fs/cifs/file.c235
-rw-r--r--fs/cifs/sess.c33
-rw-r--r--fs/cifs/transport.c2
9 files changed, 332 insertions, 412 deletions
diff --git a/fs/cifs/cache.c b/fs/cifs/cache.c
index 224d7bbd1fcc..e654dfd092c3 100644
--- a/fs/cifs/cache.c
+++ b/fs/cifs/cache.c
@@ -64,7 +64,9 @@ static uint16_t cifs_server_get_key(const void *cookie_netfs_data,
64 void *buffer, uint16_t maxbuf) 64 void *buffer, uint16_t maxbuf)
65{ 65{
66 const struct TCP_Server_Info *server = cookie_netfs_data; 66 const struct TCP_Server_Info *server = cookie_netfs_data;
67 const struct sockaddr *sa = (struct sockaddr *) &server->addr.sockAddr; 67 const struct sockaddr *sa = (struct sockaddr *) &server->dstaddr;
68 const struct sockaddr_in *addr = (struct sockaddr_in *) sa;
69 const struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) sa;
68 struct cifs_server_key *key = buffer; 70 struct cifs_server_key *key = buffer;
69 uint16_t key_len = sizeof(struct cifs_server_key); 71 uint16_t key_len = sizeof(struct cifs_server_key);
70 72
@@ -76,16 +78,16 @@ static uint16_t cifs_server_get_key(const void *cookie_netfs_data,
76 */ 78 */
77 switch (sa->sa_family) { 79 switch (sa->sa_family) {
78 case AF_INET: 80 case AF_INET:
79 key->family = server->addr.sockAddr.sin_family; 81 key->family = sa->sa_family;
80 key->port = server->addr.sockAddr.sin_port; 82 key->port = addr->sin_port;
81 key->addr[0].ipv4_addr = server->addr.sockAddr.sin_addr; 83 key->addr[0].ipv4_addr = addr->sin_addr;
82 key_len += sizeof(key->addr[0].ipv4_addr); 84 key_len += sizeof(key->addr[0].ipv4_addr);
83 break; 85 break;
84 86
85 case AF_INET6: 87 case AF_INET6:
86 key->family = server->addr.sockAddr6.sin6_family; 88 key->family = sa->sa_family;
87 key->port = server->addr.sockAddr6.sin6_port; 89 key->port = addr6->sin6_port;
88 key->addr[0].ipv6_addr = server->addr.sockAddr6.sin6_addr; 90 key->addr[0].ipv6_addr = addr6->sin6_addr;
89 key_len += sizeof(key->addr[0].ipv6_addr); 91 key_len += sizeof(key->addr[0].ipv6_addr);
90 break; 92 break;
91 93
diff --git a/fs/cifs/cifs_spnego.c b/fs/cifs/cifs_spnego.c
index 87044906cd1f..4dfba8283165 100644
--- a/fs/cifs/cifs_spnego.c
+++ b/fs/cifs/cifs_spnego.c
@@ -98,6 +98,8 @@ struct key *
98cifs_get_spnego_key(struct cifsSesInfo *sesInfo) 98cifs_get_spnego_key(struct cifsSesInfo *sesInfo)
99{ 99{
100 struct TCP_Server_Info *server = sesInfo->server; 100 struct TCP_Server_Info *server = sesInfo->server;
101 struct sockaddr_in *sa = (struct sockaddr_in *) &server->dstaddr;
102 struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *) &server->dstaddr;
101 char *description, *dp; 103 char *description, *dp;
102 size_t desc_len; 104 size_t desc_len;
103 struct key *spnego_key; 105 struct key *spnego_key;
@@ -127,10 +129,10 @@ cifs_get_spnego_key(struct cifsSesInfo *sesInfo)
127 dp = description + strlen(description); 129 dp = description + strlen(description);
128 130
129 /* add the server address */ 131 /* add the server address */
130 if (server->addr.sockAddr.sin_family == AF_INET) 132 if (server->dstaddr.ss_family == AF_INET)
131 sprintf(dp, "ip4=%pI4", &server->addr.sockAddr.sin_addr); 133 sprintf(dp, "ip4=%pI4", &sa->sin_addr);
132 else if (server->addr.sockAddr.sin_family == AF_INET6) 134 else if (server->dstaddr.ss_family == AF_INET6)
133 sprintf(dp, "ip6=%pI6", &server->addr.sockAddr6.sin6_addr); 135 sprintf(dp, "ip6=%pI6", &sa6->sin6_addr);
134 else 136 else
135 goto out; 137 goto out;
136 138
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 8e21e0fe65d5..5abfedaa5e78 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -361,18 +361,19 @@ cifs_evict_inode(struct inode *inode)
361static void 361static void
362cifs_show_address(struct seq_file *s, struct TCP_Server_Info *server) 362cifs_show_address(struct seq_file *s, struct TCP_Server_Info *server)
363{ 363{
364 struct sockaddr_in *sa = (struct sockaddr_in *) &server->dstaddr;
365 struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *) &server->dstaddr;
366
364 seq_printf(s, ",addr="); 367 seq_printf(s, ",addr=");
365 368
366 switch (server->addr.sockAddr.sin_family) { 369 switch (server->dstaddr.ss_family) {
367 case AF_INET: 370 case AF_INET:
368 seq_printf(s, "%pI4", &server->addr.sockAddr.sin_addr.s_addr); 371 seq_printf(s, "%pI4", &sa->sin_addr.s_addr);
369 break; 372 break;
370 case AF_INET6: 373 case AF_INET6:
371 seq_printf(s, "%pI6", 374 seq_printf(s, "%pI6", &sa6->sin6_addr.s6_addr);
372 &server->addr.sockAddr6.sin6_addr.s6_addr); 375 if (sa6->sin6_scope_id)
373 if (server->addr.sockAddr6.sin6_scope_id) 376 seq_printf(s, "%%%u", sa6->sin6_scope_id);
374 seq_printf(s, "%%%u",
375 server->addr.sockAddr6.sin6_scope_id);
376 break; 377 break;
377 default: 378 default:
378 seq_printf(s, "(unknown)"); 379 seq_printf(s, "(unknown)");
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 7136c0c3e2f9..dfd2d46275ab 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -163,10 +163,7 @@ struct TCP_Server_Info {
163 char server_RFC1001_name[RFC1001_NAME_LEN_WITH_NULL]; 163 char server_RFC1001_name[RFC1001_NAME_LEN_WITH_NULL];
164 char *hostname; /* hostname portion of UNC string */ 164 char *hostname; /* hostname portion of UNC string */
165 struct socket *ssocket; 165 struct socket *ssocket;
166 union { 166 struct sockaddr_storage dstaddr;
167 struct sockaddr_in sockAddr;
168 struct sockaddr_in6 sockAddr6;
169 } addr;
170 struct sockaddr_storage srcaddr; /* locally bind to this IP */ 167 struct sockaddr_storage srcaddr; /* locally bind to this IP */
171 wait_queue_head_t response_q; 168 wait_queue_head_t response_q;
172 wait_queue_head_t request_q; /* if more than maxmpx to srvr must block*/ 169 wait_queue_head_t request_q; /* if more than maxmpx to srvr must block*/
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index cc1a8604a790..41f002fb4a04 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -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);
@@ -1454,35 +1453,71 @@ srcip_matches(struct sockaddr *srcaddr, struct sockaddr *rhs)
1454 } 1453 }
1455} 1454}
1456 1455
1456/*
1457 * If no port is specified in addr structure, we try to match with 445 port
1458 * and if it fails - with 139 ports. It should be called only if address
1459 * families of server and addr are equal.
1460 */
1461static bool
1462match_port(struct TCP_Server_Info *server, struct sockaddr *addr)
1463{
1464 unsigned short int port, *sport;
1465
1466 switch (addr->sa_family) {
1467 case AF_INET:
1468 sport = &((struct sockaddr_in *) &server->dstaddr)->sin_port;
1469 port = ((struct sockaddr_in *) addr)->sin_port;
1470 break;
1471 case AF_INET6:
1472 sport = &((struct sockaddr_in6 *) &server->dstaddr)->sin6_port;
1473 port = ((struct sockaddr_in6 *) addr)->sin6_port;
1474 break;
1475 default:
1476 WARN_ON(1);
1477 return false;
1478 }
1479
1480 if (!port) {
1481 port = htons(CIFS_PORT);
1482 if (port == *sport)
1483 return true;
1484
1485 port = htons(RFC1001_PORT);
1486 }
1487
1488 return port == *sport;
1489}
1457 1490
1458static bool 1491static bool
1459match_address(struct TCP_Server_Info *server, struct sockaddr *addr, 1492match_address(struct TCP_Server_Info *server, struct sockaddr *addr,
1460 struct sockaddr *srcaddr) 1493 struct sockaddr *srcaddr)
1461{ 1494{
1462 struct sockaddr_in *addr4 = (struct sockaddr_in *)addr;
1463 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)addr;
1464
1465 switch (addr->sa_family) { 1495 switch (addr->sa_family) {
1466 case AF_INET: 1496 case AF_INET: {
1467 if (addr4->sin_addr.s_addr != 1497 struct sockaddr_in *addr4 = (struct sockaddr_in *)addr;
1468 server->addr.sockAddr.sin_addr.s_addr) 1498 struct sockaddr_in *srv_addr4 =
1469 return false; 1499 (struct sockaddr_in *)&server->dstaddr;
1470 if (addr4->sin_port && 1500
1471 addr4->sin_port != server->addr.sockAddr.sin_port) 1501 if (addr4->sin_addr.s_addr != srv_addr4->sin_addr.s_addr)
1472 return false; 1502 return false;
1473 break; 1503 break;
1474 case AF_INET6: 1504 }
1505 case AF_INET6: {
1506 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)addr;
1507 struct sockaddr_in6 *srv_addr6 =
1508 (struct sockaddr_in6 *)&server->dstaddr;
1509
1475 if (!ipv6_addr_equal(&addr6->sin6_addr, 1510 if (!ipv6_addr_equal(&addr6->sin6_addr,
1476 &server->addr.sockAddr6.sin6_addr)) 1511 &srv_addr6->sin6_addr))
1477 return false;
1478 if (addr6->sin6_scope_id !=
1479 server->addr.sockAddr6.sin6_scope_id)
1480 return false; 1512 return false;
1481 if (addr6->sin6_port && 1513 if (addr6->sin6_scope_id != srv_addr6->sin6_scope_id)
1482 addr6->sin6_port != server->addr.sockAddr6.sin6_port)
1483 return false; 1514 return false;
1484 break; 1515 break;
1485 } 1516 }
1517 default:
1518 WARN_ON(1);
1519 return false; /* don't expect to be here */
1520 }
1486 1521
1487 if (!srcip_matches(srcaddr, (struct sockaddr *)&server->srcaddr)) 1522 if (!srcip_matches(srcaddr, (struct sockaddr *)&server->srcaddr))
1488 return false; 1523 return false;
@@ -1549,6 +1584,9 @@ cifs_find_tcp_session(struct sockaddr *addr, struct smb_vol *vol)
1549 (struct sockaddr *)&vol->srcaddr)) 1584 (struct sockaddr *)&vol->srcaddr))
1550 continue; 1585 continue;
1551 1586
1587 if (!match_port(server, addr))
1588 continue;
1589
1552 if (!match_security(server, vol)) 1590 if (!match_security(server, vol))
1553 continue; 1591 continue;
1554 1592
@@ -1681,14 +1719,13 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
1681 cFYI(1, "attempting ipv6 connect"); 1719 cFYI(1, "attempting ipv6 connect");
1682 /* BB should we allow ipv6 on port 139? */ 1720 /* BB should we allow ipv6 on port 139? */
1683 /* other OS never observed in Wild doing 139 with v6 */ 1721 /* other OS never observed in Wild doing 139 with v6 */
1684 memcpy(&tcp_ses->addr.sockAddr6, sin_server6, 1722 memcpy(&tcp_ses->dstaddr, sin_server6,
1685 sizeof(struct sockaddr_in6)); 1723 sizeof(struct sockaddr_in6));
1686 rc = ipv6_connect(tcp_ses); 1724 } else
1687 } else { 1725 memcpy(&tcp_ses->dstaddr, sin_server,
1688 memcpy(&tcp_ses->addr.sockAddr, sin_server, 1726 sizeof(struct sockaddr_in));
1689 sizeof(struct sockaddr_in)); 1727
1690 rc = ipv4_connect(tcp_ses); 1728 rc = ip_connect(tcp_ses);
1691 }
1692 if (rc < 0) { 1729 if (rc < 0) {
1693 cERROR(1, "Error connecting to socket. Aborting operation"); 1730 cERROR(1, "Error connecting to socket. Aborting operation");
1694 goto out_err_crypto_release; 1731 goto out_err_crypto_release;
@@ -1793,6 +1830,8 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
1793{ 1830{
1794 int rc = -ENOMEM, xid; 1831 int rc = -ENOMEM, xid;
1795 struct cifsSesInfo *ses; 1832 struct cifsSesInfo *ses;
1833 struct sockaddr_in *addr = (struct sockaddr_in *)&server->dstaddr;
1834 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&server->dstaddr;
1796 1835
1797 xid = GetXid(); 1836 xid = GetXid();
1798 1837
@@ -1836,12 +1875,10 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
1836 1875
1837 /* new SMB session uses our server ref */ 1876 /* new SMB session uses our server ref */
1838 ses->server = server; 1877 ses->server = server;
1839 if (server->addr.sockAddr6.sin6_family == AF_INET6) 1878 if (server->dstaddr.ss_family == AF_INET6)
1840 sprintf(ses->serverName, "%pI6", 1879 sprintf(ses->serverName, "%pI6", &addr6->sin6_addr);
1841 &server->addr.sockAddr6.sin6_addr);
1842 else 1880 else
1843 sprintf(ses->serverName, "%pI4", 1881 sprintf(ses->serverName, "%pI4", &addr->sin_addr);
1844 &server->addr.sockAddr.sin_addr.s_addr);
1845 1882
1846 if (volume_info->username) 1883 if (volume_info->username)
1847 strncpy(ses->userName, volume_info->username, 1884 strncpy(ses->userName, volume_info->username,
@@ -2136,19 +2173,106 @@ bind_socket(struct TCP_Server_Info *server)
2136} 2173}
2137 2174
2138static int 2175static int
2139ipv4_connect(struct TCP_Server_Info *server) 2176ip_rfc1001_connect(struct TCP_Server_Info *server)
2140{ 2177{
2141 int rc = 0; 2178 int rc = 0;
2142 int val; 2179 /*
2143 bool connected = false; 2180 * some servers require RFC1001 sessinit before sending
2144 __be16 orig_port = 0; 2181 * negprot - BB check reconnection in case where second
2182 * sessinit is sent but no second negprot
2183 */
2184 struct rfc1002_session_packet *ses_init_buf;
2185 struct smb_hdr *smb_buf;
2186 ses_init_buf = kzalloc(sizeof(struct rfc1002_session_packet),
2187 GFP_KERNEL);
2188 if (ses_init_buf) {
2189 ses_init_buf->trailer.session_req.called_len = 32;
2190
2191 if (server->server_RFC1001_name &&
2192 server->server_RFC1001_name[0] != 0)
2193 rfc1002mangle(ses_init_buf->trailer.
2194 session_req.called_name,
2195 server->server_RFC1001_name,
2196 RFC1001_NAME_LEN_WITH_NULL);
2197 else
2198 rfc1002mangle(ses_init_buf->trailer.
2199 session_req.called_name,
2200 DEFAULT_CIFS_CALLED_NAME,
2201 RFC1001_NAME_LEN_WITH_NULL);
2202
2203 ses_init_buf->trailer.session_req.calling_len = 32;
2204
2205 /*
2206 * calling name ends in null (byte 16) from old smb
2207 * convention.
2208 */
2209 if (server->workstation_RFC1001_name &&
2210 server->workstation_RFC1001_name[0] != 0)
2211 rfc1002mangle(ses_init_buf->trailer.
2212 session_req.calling_name,
2213 server->workstation_RFC1001_name,
2214 RFC1001_NAME_LEN_WITH_NULL);
2215 else
2216 rfc1002mangle(ses_init_buf->trailer.
2217 session_req.calling_name,
2218 "LINUX_CIFS_CLNT",
2219 RFC1001_NAME_LEN_WITH_NULL);
2220
2221 ses_init_buf->trailer.session_req.scope1 = 0;
2222 ses_init_buf->trailer.session_req.scope2 = 0;
2223 smb_buf = (struct smb_hdr *)ses_init_buf;
2224
2225 /* sizeof RFC1002_SESSION_REQUEST with no scope */
2226 smb_buf->smb_buf_length = 0x81000044;
2227 rc = smb_send(server, smb_buf, 0x44);
2228 kfree(ses_init_buf);
2229 /*
2230 * RFC1001 layer in at least one server
2231 * requires very short break before negprot
2232 * presumably because not expecting negprot
2233 * to follow so fast. This is a simple
2234 * solution that works without
2235 * complicating the code and causes no
2236 * significant slowing down on mount
2237 * for everyone else
2238 */
2239 usleep_range(1000, 2000);
2240 }
2241 /*
2242 * else the negprot may still work without this
2243 * even though malloc failed
2244 */
2245
2246 return rc;
2247}
2248
2249static int
2250generic_ip_connect(struct TCP_Server_Info *server)
2251{
2252 int rc = 0;
2253 unsigned short int sport;
2254 int slen, sfamily;
2145 struct socket *socket = server->ssocket; 2255 struct socket *socket = server->ssocket;
2256 struct sockaddr *saddr;
2257
2258 saddr = (struct sockaddr *) &server->dstaddr;
2259
2260 if (server->dstaddr.ss_family == AF_INET6) {
2261 sport = ((struct sockaddr_in6 *) saddr)->sin6_port;
2262 slen = sizeof(struct sockaddr_in6);
2263 sfamily = AF_INET6;
2264 } else {
2265 sport = ((struct sockaddr_in *) saddr)->sin_port;
2266 slen = sizeof(struct sockaddr_in);
2267 sfamily = AF_INET;
2268 }
2146 2269
2147 if (socket == NULL) { 2270 if (socket == NULL) {
2148 rc = sock_create_kern(PF_INET, SOCK_STREAM, 2271 rc = sock_create_kern(sfamily, SOCK_STREAM,
2149 IPPROTO_TCP, &socket); 2272 IPPROTO_TCP, &socket);
2150 if (rc < 0) { 2273 if (rc < 0) {
2151 cERROR(1, "Error %d creating socket", rc); 2274 cERROR(1, "Error %d creating socket", rc);
2275 server->ssocket = NULL;
2152 return rc; 2276 return rc;
2153 } 2277 }
2154 2278
@@ -2156,63 +2280,28 @@ ipv4_connect(struct TCP_Server_Info *server)
2156 cFYI(1, "Socket created"); 2280 cFYI(1, "Socket created");
2157 server->ssocket = socket; 2281 server->ssocket = socket;
2158 socket->sk->sk_allocation = GFP_NOFS; 2282 socket->sk->sk_allocation = GFP_NOFS;
2159 cifs_reclassify_socket4(socket); 2283 if (sfamily == AF_INET6)
2284 cifs_reclassify_socket6(socket);
2285 else
2286 cifs_reclassify_socket4(socket);
2160 } 2287 }
2161 2288
2162 rc = bind_socket(server); 2289 rc = bind_socket(server);
2163 if (rc < 0) 2290 if (rc < 0)
2164 return rc; 2291 return rc;
2165 2292
2166 /* user overrode default port */ 2293 rc = socket->ops->connect(socket, saddr, slen, 0);
2167 if (server->addr.sockAddr.sin_port) { 2294 if (rc < 0) {
2168 rc = socket->ops->connect(socket, (struct sockaddr *) 2295 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); 2296 sock_release(socket);
2207 server->ssocket = NULL; 2297 server->ssocket = NULL;
2208 return rc; 2298 return rc;
2209 } 2299 }
2210 2300
2211
2212 /* 2301 /*
2213 * Eventually check for other socket options to change from 2302 * Eventually check for other socket options to change from
2214 * the default. sock_setsockopt not used because it expects 2303 * the default. sock_setsockopt not used because it expects
2215 * user space buffer 2304 * user space buffer
2216 */ 2305 */
2217 socket->sk->sk_rcvtimeo = 7 * HZ; 2306 socket->sk->sk_rcvtimeo = 7 * HZ;
2218 socket->sk->sk_sndtimeo = 5 * HZ; 2307 socket->sk->sk_sndtimeo = 5 * HZ;
@@ -2226,7 +2315,7 @@ ipv4_connect(struct TCP_Server_Info *server)
2226 } 2315 }
2227 2316
2228 if (server->tcp_nodelay) { 2317 if (server->tcp_nodelay) {
2229 val = 1; 2318 int val = 1;
2230 rc = kernel_setsockopt(socket, SOL_TCP, TCP_NODELAY, 2319 rc = kernel_setsockopt(socket, SOL_TCP, TCP_NODELAY,
2231 (char *)&val, sizeof(val)); 2320 (char *)&val, sizeof(val));
2232 if (rc) 2321 if (rc)
@@ -2237,161 +2326,39 @@ ipv4_connect(struct TCP_Server_Info *server)
2237 socket->sk->sk_sndbuf, 2326 socket->sk->sk_sndbuf,
2238 socket->sk->sk_rcvbuf, socket->sk->sk_rcvtimeo); 2327 socket->sk->sk_rcvbuf, socket->sk->sk_rcvtimeo);
2239 2328
2240 /* send RFC1001 sessinit */ 2329 if (sport == htons(RFC1001_PORT))
2241 if (server->addr.sockAddr.sin_port == htons(RFC1001_PORT)) { 2330 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 2331
2300 return rc; 2332 return rc;
2301} 2333}
2302 2334
2303static int 2335static int
2304ipv6_connect(struct TCP_Server_Info *server) 2336ip_connect(struct TCP_Server_Info *server)
2305{ 2337{
2306 int rc = 0; 2338 unsigned short int *sport;
2307 int val; 2339 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&server->dstaddr;
2308 bool connected = false; 2340 struct sockaddr_in *addr = (struct sockaddr_in *)&server->dstaddr;
2309 __be16 orig_port = 0;
2310 struct socket *socket = server->ssocket;
2311 2341
2312 if (socket == NULL) { 2342 if (server->dstaddr.ss_family == AF_INET6)
2313 rc = sock_create_kern(PF_INET6, SOCK_STREAM, 2343 sport = &addr6->sin6_port;
2314 IPPROTO_TCP, &socket); 2344 else
2315 if (rc < 0) { 2345 sport = &addr->sin_port;
2316 cERROR(1, "Error %d creating ipv6 socket", rc);
2317 socket = NULL;
2318 return rc;
2319 }
2320 2346
2321 /* BB other socket options to set KEEPALIVE, NODELAY? */ 2347 if (*sport == 0) {
2322 cFYI(1, "ipv6 Socket created"); 2348 int rc;
2323 server->ssocket = socket;
2324 socket->sk->sk_allocation = GFP_NOFS;
2325 cifs_reclassify_socket6(socket);
2326 }
2327 2349
2328 rc = bind_socket(server); 2350 /* try with 445 port at first */
2329 if (rc < 0) 2351 *sport = htons(CIFS_PORT);
2330 return rc;
2331 2352
2332 /* user overrode default port */ 2353 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) 2354 if (rc >= 0)
2338 connected = true; 2355 return rc;
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)
2362 connected = true;
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 2356
2384 if (server->tcp_nodelay) { 2357 /* if it failed, try with 139 port */
2385 val = 1; 2358 *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 } 2359 }
2391 2360
2392 server->ssocket = socket; 2361 return generic_ip_connect(server);
2393
2394 return rc;
2395} 2362}
2396 2363
2397void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon, 2364void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index db2a58c00f7b..ce8014345258 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -724,10 +724,17 @@ static int cifs_ci_compare(const struct dentry *parent,
724 const struct dentry *dentry, const struct inode *inode, 724 const struct dentry *dentry, const struct inode *inode,
725 unsigned int len, const char *str, const struct qstr *name) 725 unsigned int len, const char *str, const struct qstr *name)
726{ 726{
727<<<<<<< HEAD
728 struct nls_table *codepage = CIFS_SB(dentry->d_inode->i_sb)->local_nls;
729
730 if ((a->len == b->len) &&
731 (nls_strnicmp(codepage, a->name, b->name, a->len) == 0))
732=======
727 struct nls_table *codepage = CIFS_SB(pinode->i_sb)->local_nls; 733 struct nls_table *codepage = CIFS_SB(pinode->i_sb)->local_nls;
728 734
729 if ((name->len == len) && 735 if ((name->len == len) &&
730 (nls_strnicmp(codepage, name->name, str, len) == 0)) 736 (nls_strnicmp(codepage, name->name, str, len) == 0))
737>>>>>>> 0c21e3aaf6ae85bee804a325aa29c325209180fd
731 return 0; 738 return 0;
732 return 1; 739 return 1;
733} 740}
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 5a28660ca2b5..97ddbf2fdfc3 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -104,53 +104,6 @@ static inline int cifs_get_disposition(unsigned int flags)
104 return FILE_OPEN; 104 return FILE_OPEN;
105} 105}
106 106
107static inline int cifs_open_inode_helper(struct inode *inode,
108 struct cifsTconInfo *pTcon, __u32 oplock, FILE_ALL_INFO *buf,
109 char *full_path, int xid)
110{
111 struct cifsInodeInfo *pCifsInode = CIFS_I(inode);
112 struct timespec temp;
113 int rc;
114
115 if (pCifsInode->clientCanCacheRead) {
116 /* we have the inode open somewhere else
117 no need to discard cache data */
118 goto client_can_cache;
119 }
120
121 /* BB need same check in cifs_create too? */
122 /* if not oplocked, invalidate inode pages if mtime or file
123 size changed */
124 temp = cifs_NTtimeToUnix(buf->LastWriteTime);
125 if (timespec_equal(&inode->i_mtime, &temp) &&
126 (inode->i_size ==
127 (loff_t)le64_to_cpu(buf->EndOfFile))) {
128 cFYI(1, "inode unchanged on server");
129 } else {
130 if (inode->i_mapping) {
131 /* BB no need to lock inode until after invalidate
132 since namei code should already have it locked? */
133 rc = filemap_write_and_wait(inode->i_mapping);
134 mapping_set_error(inode->i_mapping, rc);
135 }
136 cFYI(1, "invalidating remote inode since open detected it "
137 "changed");
138 invalidate_remote_inode(inode);
139 }
140
141client_can_cache:
142 if (pTcon->unix_ext)
143 rc = cifs_get_inode_info_unix(&inode, full_path, inode->i_sb,
144 xid);
145 else
146 rc = cifs_get_inode_info(&inode, full_path, buf, inode->i_sb,
147 xid, NULL);
148
149 cifs_set_oplock_level(pCifsInode, oplock);
150
151 return rc;
152}
153
154int cifs_posix_open(char *full_path, struct inode **pinode, 107int cifs_posix_open(char *full_path, struct inode **pinode,
155 struct super_block *sb, int mode, unsigned int f_flags, 108 struct super_block *sb, int mode, unsigned int f_flags,
156 __u32 *poplock, __u16 *pnetfid, int xid) 109 __u32 *poplock, __u16 *pnetfid, int xid)
@@ -213,6 +166,76 @@ posix_open_ret:
213 return rc; 166 return rc;
214} 167}
215 168
169static int
170cifs_nt_open(char *full_path, struct inode *inode, struct cifs_sb_info *cifs_sb,
171 struct cifsTconInfo *tcon, unsigned int f_flags, __u32 *poplock,
172 __u16 *pnetfid, int xid)
173{
174 int rc;
175 int desiredAccess;
176 int disposition;
177 FILE_ALL_INFO *buf;
178
179 desiredAccess = cifs_convert_flags(f_flags);
180
181/*********************************************************************
182 * open flag mapping table:
183 *
184 * POSIX Flag CIFS Disposition
185 * ---------- ----------------
186 * O_CREAT FILE_OPEN_IF
187 * O_CREAT | O_EXCL FILE_CREATE
188 * O_CREAT | O_TRUNC FILE_OVERWRITE_IF
189 * O_TRUNC FILE_OVERWRITE
190 * none of the above FILE_OPEN
191 *
192 * Note that there is not a direct match between disposition
193 * FILE_SUPERSEDE (ie create whether or not file exists although
194 * O_CREAT | O_TRUNC is similar but truncates the existing
195 * file rather than creating a new file as FILE_SUPERSEDE does
196 * (which uses the attributes / metadata passed in on open call)
197 *?
198 *? O_SYNC is a reasonable match to CIFS writethrough flag
199 *? and the read write flags match reasonably. O_LARGEFILE
200 *? is irrelevant because largefile support is always used
201 *? by this client. Flags O_APPEND, O_DIRECT, O_DIRECTORY,
202 * O_FASYNC, O_NOFOLLOW, O_NONBLOCK need further investigation
203 *********************************************************************/
204
205 disposition = cifs_get_disposition(f_flags);
206
207 /* BB pass O_SYNC flag through on file attributes .. BB */
208
209 buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
210 if (!buf)
211 return -ENOMEM;
212
213 if (tcon->ses->capabilities & CAP_NT_SMBS)
214 rc = CIFSSMBOpen(xid, tcon, full_path, disposition,
215 desiredAccess, CREATE_NOT_DIR, pnetfid, poplock, buf,
216 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags
217 & CIFS_MOUNT_MAP_SPECIAL_CHR);
218 else
219 rc = SMBLegacyOpen(xid, tcon, full_path, disposition,
220 desiredAccess, CREATE_NOT_DIR, pnetfid, poplock, buf,
221 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags
222 & CIFS_MOUNT_MAP_SPECIAL_CHR);
223
224 if (rc)
225 goto out;
226
227 if (tcon->unix_ext)
228 rc = cifs_get_inode_info_unix(&inode, full_path, inode->i_sb,
229 xid);
230 else
231 rc = cifs_get_inode_info(&inode, full_path, buf, inode->i_sb,
232 xid, pnetfid);
233
234out:
235 kfree(buf);
236 return rc;
237}
238
216struct cifsFileInfo * 239struct cifsFileInfo *
217cifs_new_fileinfo(__u16 fileHandle, struct file *file, 240cifs_new_fileinfo(__u16 fileHandle, struct file *file,
218 struct tcon_link *tlink, __u32 oplock) 241 struct tcon_link *tlink, __u32 oplock)
@@ -317,10 +340,8 @@ int cifs_open(struct inode *inode, struct file *file)
317 struct cifsFileInfo *pCifsFile = NULL; 340 struct cifsFileInfo *pCifsFile = NULL;
318 struct cifsInodeInfo *pCifsInode; 341 struct cifsInodeInfo *pCifsInode;
319 char *full_path = NULL; 342 char *full_path = NULL;
320 int desiredAccess; 343 bool posix_open_ok = false;
321 int disposition;
322 __u16 netfid; 344 __u16 netfid;
323 FILE_ALL_INFO *buf = NULL;
324 345
325 xid = GetXid(); 346 xid = GetXid();
326 347
@@ -358,17 +379,7 @@ int cifs_open(struct inode *inode, struct file *file)
358 file->f_flags, &oplock, &netfid, xid); 379 file->f_flags, &oplock, &netfid, xid);
359 if (rc == 0) { 380 if (rc == 0) {
360 cFYI(1, "posix open succeeded"); 381 cFYI(1, "posix open succeeded");
361 382 posix_open_ok = true;
362 pCifsFile = cifs_new_fileinfo(netfid, file, tlink,
363 oplock);
364 if (pCifsFile == NULL) {
365 CIFSSMBClose(xid, tcon, netfid);
366 rc = -ENOMEM;
367 }
368
369 cifs_fscache_set_inode_cookie(inode, file);
370
371 goto out;
372 } else if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) { 383 } else if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
373 if (tcon->ses->serverNOS) 384 if (tcon->ses->serverNOS)
374 cERROR(1, "server %s of type %s returned" 385 cERROR(1, "server %s of type %s returned"
@@ -385,103 +396,41 @@ int cifs_open(struct inode *inode, struct file *file)
385 or DFS errors */ 396 or DFS errors */
386 } 397 }
387 398
388 desiredAccess = cifs_convert_flags(file->f_flags); 399 if (!posix_open_ok) {
389 400 rc = cifs_nt_open(full_path, inode, cifs_sb, tcon,
390/********************************************************************* 401 file->f_flags, &oplock, &netfid, xid);
391 * open flag mapping table: 402 if (rc)
392 * 403 goto out;
393 * POSIX Flag CIFS Disposition
394 * ---------- ----------------
395 * O_CREAT FILE_OPEN_IF
396 * O_CREAT | O_EXCL FILE_CREATE
397 * O_CREAT | O_TRUNC FILE_OVERWRITE_IF
398 * O_TRUNC FILE_OVERWRITE
399 * none of the above FILE_OPEN
400 *
401 * Note that there is not a direct match between disposition
402 * FILE_SUPERSEDE (ie create whether or not file exists although
403 * O_CREAT | O_TRUNC is similar but truncates the existing
404 * file rather than creating a new file as FILE_SUPERSEDE does
405 * (which uses the attributes / metadata passed in on open call)
406 *?
407 *? O_SYNC is a reasonable match to CIFS writethrough flag
408 *? and the read write flags match reasonably. O_LARGEFILE
409 *? is irrelevant because largefile support is always used
410 *? by this client. Flags O_APPEND, O_DIRECT, O_DIRECTORY,
411 * O_FASYNC, O_NOFOLLOW, O_NONBLOCK need further investigation
412 *********************************************************************/
413
414 disposition = cifs_get_disposition(file->f_flags);
415
416 /* BB pass O_SYNC flag through on file attributes .. BB */
417
418 /* Also refresh inode by passing in file_info buf returned by SMBOpen
419 and calling get_inode_info with returned buf (at least helps
420 non-Unix server case) */
421
422 /* BB we can not do this if this is the second open of a file
423 and the first handle has writebehind data, we might be
424 able to simply do a filemap_fdatawrite/filemap_fdatawait first */
425 buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
426 if (!buf) {
427 rc = -ENOMEM;
428 goto out;
429 }
430
431 if (tcon->ses->capabilities & CAP_NT_SMBS)
432 rc = CIFSSMBOpen(xid, tcon, full_path, disposition,
433 desiredAccess, CREATE_NOT_DIR, &netfid, &oplock, buf,
434 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags
435 & CIFS_MOUNT_MAP_SPECIAL_CHR);
436 else
437 rc = -EIO; /* no NT SMB support fall into legacy open below */
438
439 if (rc == -EIO) {
440 /* Old server, try legacy style OpenX */
441 rc = SMBLegacyOpen(xid, tcon, full_path, disposition,
442 desiredAccess, CREATE_NOT_DIR, &netfid, &oplock, buf,
443 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags
444 & CIFS_MOUNT_MAP_SPECIAL_CHR);
445 }
446 if (rc) {
447 cFYI(1, "cifs_open returned 0x%x", rc);
448 goto out;
449 } 404 }
450 405
451 rc = cifs_open_inode_helper(inode, tcon, oplock, buf, full_path, xid);
452 if (rc != 0)
453 goto out;
454
455 pCifsFile = cifs_new_fileinfo(netfid, file, tlink, oplock); 406 pCifsFile = cifs_new_fileinfo(netfid, file, tlink, oplock);
456 if (pCifsFile == NULL) { 407 if (pCifsFile == NULL) {
408 CIFSSMBClose(xid, tcon, netfid);
457 rc = -ENOMEM; 409 rc = -ENOMEM;
458 goto out; 410 goto out;
459 } 411 }
460 412
461 cifs_fscache_set_inode_cookie(inode, file); 413 cifs_fscache_set_inode_cookie(inode, file);
462 414
463 if (oplock & CIFS_CREATE_ACTION) { 415 if ((oplock & CIFS_CREATE_ACTION) && !posix_open_ok && tcon->unix_ext) {
464 /* time to set mode which we can not set earlier due to 416 /* time to set mode which we can not set earlier due to
465 problems creating new read-only files */ 417 problems creating new read-only files */
466 if (tcon->unix_ext) { 418 struct cifs_unix_set_info_args args = {
467 struct cifs_unix_set_info_args args = { 419 .mode = inode->i_mode,
468 .mode = inode->i_mode, 420 .uid = NO_CHANGE_64,
469 .uid = NO_CHANGE_64, 421 .gid = NO_CHANGE_64,
470 .gid = NO_CHANGE_64, 422 .ctime = NO_CHANGE_64,
471 .ctime = NO_CHANGE_64, 423 .atime = NO_CHANGE_64,
472 .atime = NO_CHANGE_64, 424 .mtime = NO_CHANGE_64,
473 .mtime = NO_CHANGE_64, 425 .device = 0,
474 .device = 0, 426 };
475 }; 427 CIFSSMBUnixSetPathInfo(xid, tcon, full_path, &args,
476 CIFSSMBUnixSetPathInfo(xid, tcon, full_path, &args, 428 cifs_sb->local_nls,
477 cifs_sb->local_nls, 429 cifs_sb->mnt_cifs_flags &
478 cifs_sb->mnt_cifs_flags & 430 CIFS_MOUNT_MAP_SPECIAL_CHR);
479 CIFS_MOUNT_MAP_SPECIAL_CHR);
480 }
481 } 431 }
482 432
483out: 433out:
484 kfree(buf);
485 kfree(full_path); 434 kfree(full_path);
486 FreeXid(xid); 435 FreeXid(xid);
487 cifs_put_tlink(tlink); 436 cifs_put_tlink(tlink);
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
index 7b01d3f6eed6..54d9f76deff9 100644
--- a/fs/cifs/sess.c
+++ b/fs/cifs/sess.c
@@ -431,13 +431,14 @@ static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer,
431 NEGOTIATE_MESSAGE *sec_blob = (NEGOTIATE_MESSAGE *)pbuffer; 431 NEGOTIATE_MESSAGE *sec_blob = (NEGOTIATE_MESSAGE *)pbuffer;
432 __u32 flags; 432 __u32 flags;
433 433
434 memset(pbuffer, 0, sizeof(NEGOTIATE_MESSAGE));
434 memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8); 435 memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8);
435 sec_blob->MessageType = NtLmNegotiate; 436 sec_blob->MessageType = NtLmNegotiate;
436 437
437 /* BB is NTLMV2 session security format easier to use here? */ 438 /* BB is NTLMV2 session security format easier to use here? */
438 flags = NTLMSSP_NEGOTIATE_56 | NTLMSSP_REQUEST_TARGET | 439 flags = NTLMSSP_NEGOTIATE_56 | NTLMSSP_REQUEST_TARGET |
439 NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE | 440 NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
440 NTLMSSP_NEGOTIATE_NTLM; 441 NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC;
441 if (ses->server->secMode & 442 if (ses->server->secMode &
442 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) { 443 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) {
443 flags |= NTLMSSP_NEGOTIATE_SIGN; 444 flags |= NTLMSSP_NEGOTIATE_SIGN;
@@ -446,7 +447,7 @@ static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer,
446 NTLMSSP_NEGOTIATE_EXTENDED_SEC; 447 NTLMSSP_NEGOTIATE_EXTENDED_SEC;
447 } 448 }
448 449
449 sec_blob->NegotiateFlags |= cpu_to_le32(flags); 450 sec_blob->NegotiateFlags = cpu_to_le32(flags);
450 451
451 sec_blob->WorkstationName.BufferOffset = 0; 452 sec_blob->WorkstationName.BufferOffset = 0;
452 sec_blob->WorkstationName.Length = 0; 453 sec_blob->WorkstationName.Length = 0;
@@ -477,7 +478,7 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
477 flags = NTLMSSP_NEGOTIATE_56 | 478 flags = NTLMSSP_NEGOTIATE_56 |
478 NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_TARGET_INFO | 479 NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_TARGET_INFO |
479 NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE | 480 NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
480 NTLMSSP_NEGOTIATE_NTLM; 481 NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC;
481 if (ses->server->secMode & 482 if (ses->server->secMode &
482 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) 483 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
483 flags |= NTLMSSP_NEGOTIATE_SIGN; 484 flags |= NTLMSSP_NEGOTIATE_SIGN;
@@ -485,7 +486,7 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
485 flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN; 486 flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
486 487
487 tmp = pbuffer + sizeof(AUTHENTICATE_MESSAGE); 488 tmp = pbuffer + sizeof(AUTHENTICATE_MESSAGE);
488 sec_blob->NegotiateFlags |= cpu_to_le32(flags); 489 sec_blob->NegotiateFlags = cpu_to_le32(flags);
489 490
490 sec_blob->LmChallengeResponse.BufferOffset = 491 sec_blob->LmChallengeResponse.BufferOffset =
491 cpu_to_le32(sizeof(AUTHENTICATE_MESSAGE)); 492 cpu_to_le32(sizeof(AUTHENTICATE_MESSAGE));
@@ -544,8 +545,9 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
544 sec_blob->WorkstationName.MaximumLength = 0; 545 sec_blob->WorkstationName.MaximumLength = 0;
545 tmp += 2; 546 tmp += 2;
546 547
547 if ((ses->ntlmssp->server_flags & NTLMSSP_NEGOTIATE_KEY_XCH) && 548 if (((ses->ntlmssp->server_flags & NTLMSSP_NEGOTIATE_KEY_XCH) ||
548 !calc_seckey(ses)) { 549 (ses->ntlmssp->server_flags & NTLMSSP_NEGOTIATE_EXTENDED_SEC))
550 && !calc_seckey(ses)) {
549 memcpy(tmp, ses->ntlmssp->ciphertext, CIFS_CPHTXT_SIZE); 551 memcpy(tmp, ses->ntlmssp->ciphertext, CIFS_CPHTXT_SIZE);
550 sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer); 552 sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer);
551 sec_blob->SessionKey.Length = cpu_to_le16(CIFS_CPHTXT_SIZE); 553 sec_blob->SessionKey.Length = cpu_to_le16(CIFS_CPHTXT_SIZE);
@@ -562,16 +564,6 @@ setup_ntlmv2_ret:
562 *buflen = tmp - pbuffer; 564 *buflen = tmp - pbuffer;
563 return rc; 565 return rc;
564} 566}
565
566
567static void setup_ntlmssp_neg_req(SESSION_SETUP_ANDX *pSMB,
568 struct cifsSesInfo *ses)
569{
570 build_ntlmssp_negotiate_blob(&pSMB->req.SecurityBlob[0], ses);
571 pSMB->req.SecurityBlobLength = cpu_to_le16(sizeof(NEGOTIATE_MESSAGE));
572
573 return;
574}
575#endif 567#endif
576 568
577int 569int
@@ -828,16 +820,19 @@ ssetup_ntlmssp_authenticate:
828 capabilities |= CAP_EXTENDED_SECURITY; 820 capabilities |= CAP_EXTENDED_SECURITY;
829 pSMB->req.Capabilities |= cpu_to_le32(capabilities); 821 pSMB->req.Capabilities |= cpu_to_le32(capabilities);
830 if (phase == NtLmNegotiate) { 822 if (phase == NtLmNegotiate) {
831 setup_ntlmssp_neg_req(pSMB, ses); 823 build_ntlmssp_negotiate_blob(
824 pSMB->req.SecurityBlob, ses);
832 iov[1].iov_len = sizeof(NEGOTIATE_MESSAGE); 825 iov[1].iov_len = sizeof(NEGOTIATE_MESSAGE);
833 iov[1].iov_base = &pSMB->req.SecurityBlob[0]; 826 iov[1].iov_base = pSMB->req.SecurityBlob;
827 pSMB->req.SecurityBlobLength =
828 cpu_to_le16(sizeof(NEGOTIATE_MESSAGE));
834 } else if (phase == NtLmAuthenticate) { 829 } else if (phase == NtLmAuthenticate) {
835 /* 5 is an empirical value, large enought to 830 /* 5 is an empirical value, large enought to
836 * hold authenticate message, max 10 of 831 * hold authenticate message, max 10 of
837 * av paris, doamin,user,workstation mames, 832 * av paris, doamin,user,workstation mames,
838 * flags etc.. 833 * flags etc..
839 */ 834 */
840 ntlmsspblob = kmalloc( 835 ntlmsspblob = kzalloc(
841 5*sizeof(struct _AUTHENTICATE_MESSAGE), 836 5*sizeof(struct _AUTHENTICATE_MESSAGE),
842 GFP_KERNEL); 837 GFP_KERNEL);
843 if (!ntlmsspblob) { 838 if (!ntlmsspblob) {
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
index e0588cdf4cc5..59ca81b16919 100644
--- a/fs/cifs/transport.c
+++ b/fs/cifs/transport.c
@@ -119,7 +119,7 @@ smb_sendv(struct TCP_Server_Info *server, struct kvec *iov, int n_vec)
119 if (ssocket == NULL) 119 if (ssocket == NULL)
120 return -ENOTSOCK; /* BB eventually add reconnect code here */ 120 return -ENOTSOCK; /* BB eventually add reconnect code here */
121 121
122 smb_msg.msg_name = (struct sockaddr *) &server->addr.sockAddr; 122 smb_msg.msg_name = (struct sockaddr *) &server->dstaddr;
123 smb_msg.msg_namelen = sizeof(struct sockaddr); 123 smb_msg.msg_namelen = sizeof(struct sockaddr);
124 smb_msg.msg_control = NULL; 124 smb_msg.msg_control = NULL;
125 smb_msg.msg_controllen = 0; 125 smb_msg.msg_controllen = 0;