aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
authorPavel Shilovsky <piastryyy@gmail.com>2010-12-13 14:18:07 -0500
committerSteve French <sfrench@us.ibm.com>2011-01-06 14:07:53 -0500
commit4b886136df2b923b6fc6b2d83faa9554e84e05ab (patch)
treea82cdb2ad0272c841d4eab2a1128a4475abea04f /fs/cifs
parenta9f1b85e5ba80519dea6974e3574fa7a30cc5e29 (diff)
CIFS: Add match_port check during looking for an existing connection (try #4)
If we have a share mounted by non-standard port and try to mount another share on the same host with standard port, we connect to the first share again - that's wrong. This patch fixes this bug. Signed-off-by: Pavel Shilovsky <piastryyy@gmail.com> Reviewed-by: Jeff Layton <jlayton@samba.org> Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/connect.c42
1 files changed, 37 insertions, 5 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index b90c7411f4f0..41f002fb4a04 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -1453,6 +1453,40 @@ srcip_matches(struct sockaddr *srcaddr, struct sockaddr *rhs)
1453 } 1453 }
1454} 1454}
1455 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}
1456 1490
1457static bool 1491static bool
1458match_address(struct TCP_Server_Info *server, struct sockaddr *addr, 1492match_address(struct TCP_Server_Info *server, struct sockaddr *addr,
@@ -1466,8 +1500,6 @@ match_address(struct TCP_Server_Info *server, struct sockaddr *addr,
1466 1500
1467 if (addr4->sin_addr.s_addr != srv_addr4->sin_addr.s_addr) 1501 if (addr4->sin_addr.s_addr != srv_addr4->sin_addr.s_addr)
1468 return false; 1502 return false;
1469 if (addr4->sin_port && addr4->sin_port != srv_addr4->sin_port)
1470 return false;
1471 break; 1503 break;
1472 } 1504 }
1473 case AF_INET6: { 1505 case AF_INET6: {
@@ -1480,9 +1512,6 @@ match_address(struct TCP_Server_Info *server, struct sockaddr *addr,
1480 return false; 1512 return false;
1481 if (addr6->sin6_scope_id != srv_addr6->sin6_scope_id) 1513 if (addr6->sin6_scope_id != srv_addr6->sin6_scope_id)
1482 return false; 1514 return false;
1483 if (addr6->sin6_port &&
1484 addr6->sin6_port != srv_addr6->sin6_port)
1485 return false;
1486 break; 1515 break;
1487 } 1516 }
1488 default: 1517 default:
@@ -1555,6 +1584,9 @@ cifs_find_tcp_session(struct sockaddr *addr, struct smb_vol *vol)
1555 (struct sockaddr *)&vol->srcaddr)) 1584 (struct sockaddr *)&vol->srcaddr))
1556 continue; 1585 continue;
1557 1586
1587 if (!match_port(server, addr))
1588 continue;
1589
1558 if (!match_security(server, vol)) 1590 if (!match_security(server, vol))
1559 continue; 1591 continue;
1560 1592