summaryrefslogtreecommitdiffstats
path: root/fs/cifs/connect.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/connect.c')
-rw-r--r--fs/cifs/connect.c91
1 files changed, 33 insertions, 58 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index dec7c15d886..428d8a12b82 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -1114,6 +1114,9 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
char *string = NULL;
char *tmp_end, *value;
char delim;
+ bool got_ip = false;
+ unsigned short port = 0;
+ struct sockaddr *dstaddr = (struct sockaddr *)&vol->dstaddr;
separator[0] = ',';
separator[1] = 0;
@@ -1422,12 +1425,12 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
vol->dir_mode = option;
break;
case Opt_port:
- if (get_option_ul(args, &option)) {
- cERROR(1, "%s: Invalid port value",
- __func__);
+ if (get_option_ul(args, &option) ||
+ option > USHRT_MAX) {
+ cERROR(1, "%s: Invalid port value", __func__);
goto cifs_parse_mount_err;
}
- vol->port = option;
+ port = (unsigned short)option;
break;
case Opt_rsize:
if (get_option_ul(args, &option)) {
@@ -1543,25 +1546,21 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
vol->password[j] = '\0';
break;
case Opt_blank_ip:
- vol->UNCip = NULL;
+ /* FIXME: should this be an error instead? */
+ got_ip = false;
break;
case Opt_ip:
string = match_strdup(args);
if (string == NULL)
goto out_nomem;
- if (strnlen(string, INET6_ADDRSTRLEN) >
- INET6_ADDRSTRLEN) {
- printk(KERN_WARNING "CIFS: ip address "
- "too long\n");
- goto cifs_parse_mount_err;
- }
- vol->UNCip = kstrdup(string, GFP_KERNEL);
- if (!vol->UNCip) {
- printk(KERN_WARNING "CIFS: no memory "
- "for UNC IP\n");
+ if (!cifs_convert_address(dstaddr, string,
+ strlen(string))) {
+ printk(KERN_ERR "CIFS: bad ip= option (%s).\n",
+ string);
goto cifs_parse_mount_err;
}
+ got_ip = true;
break;
case Opt_unc:
string = match_strdup(args);
@@ -1811,8 +1810,18 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
goto cifs_parse_mount_err;
}
- if (vol->UNCip == NULL)
- vol->UNCip = &vol->UNC[2];
+ if (!got_ip) {
+ /* No ip= option specified? Try to get it from UNC */
+ if (!cifs_convert_address(dstaddr, &vol->UNC[2],
+ strlen(&vol->UNC[2]))) {
+ printk(KERN_ERR "Unable to determine destination "
+ "address.\n");
+ goto cifs_parse_mount_err;
+ }
+ }
+
+ /* set the port that we got earlier */
+ cifs_set_port(dstaddr, port);
if (uid_specified)
vol->override_uid = override_uid;
@@ -2062,29 +2071,13 @@ static struct TCP_Server_Info *
cifs_get_tcp_session(struct smb_vol *volume_info)
{
struct TCP_Server_Info *tcp_ses = NULL;
- struct sockaddr_storage addr;
- struct sockaddr_in *sin_server = (struct sockaddr_in *) &addr;
- struct sockaddr_in6 *sin_server6 = (struct sockaddr_in6 *) &addr;
+ struct sockaddr *dstaddr = (struct sockaddr *)&volume_info->dstaddr;
int rc;
- memset(&addr, 0, sizeof(struct sockaddr_storage));
-
- cFYI(1, "UNC: %s ip: %s", volume_info->UNC, volume_info->UNCip);
-
- if (volume_info->UNCip && volume_info->UNC) {
- rc = cifs_fill_sockaddr((struct sockaddr *)&addr,
- volume_info->UNCip,
- strlen(volume_info->UNCip),
- volume_info->port);
- if (!rc) {
- /* we failed translating address */
- rc = -EINVAL;
- goto out_err;
- }
- }
+ cFYI(1, "UNC: %s", volume_info->UNC);
/* see if we already have a matching tcp_ses */
- tcp_ses = cifs_find_tcp_session((struct sockaddr *)&addr, volume_info);
+ tcp_ses = cifs_find_tcp_session(dstaddr, volume_info);
if (tcp_ses)
return tcp_ses;
@@ -2140,15 +2133,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
sizeof(tcp_ses->srcaddr));
++tcp_ses->srv_count;
- if (addr.ss_family == AF_INET6) {
- cFYI(1, "attempting ipv6 connect");
- /* BB should we allow ipv6 on port 139? */
- /* other OS never observed in Wild doing 139 with v6 */
- memcpy(&tcp_ses->dstaddr, sin_server6,
- sizeof(struct sockaddr_in6));
- } else
- memcpy(&tcp_ses->dstaddr, sin_server,
- sizeof(struct sockaddr_in));
+ memcpy(&tcp_ses->dstaddr, dstaddr, sizeof(tcp_ses->dstaddr));
rc = ip_connect(tcp_ses);
if (rc < 0) {
@@ -2708,11 +2693,9 @@ cifs_match_super(struct super_block *sb, void *data)
struct cifs_ses *ses;
struct cifs_tcon *tcon;
struct tcon_link *tlink;
- struct sockaddr_storage addr;
+ struct sockaddr *dstaddr;
int rc = 0;
- memset(&addr, 0, sizeof(struct sockaddr_storage));
-
spin_lock(&cifs_tcp_ses_lock);
cifs_sb = CIFS_SB(sb);
tlink = cifs_get_tlink(cifs_sb_master_tlink(cifs_sb));
@@ -2725,15 +2708,9 @@ cifs_match_super(struct super_block *sb, void *data)
tcp_srv = ses->server;
volume_info = mnt_data->vol;
+ dstaddr = (struct sockaddr *)&volume_info->dstaddr;
- rc = cifs_fill_sockaddr((struct sockaddr *)&addr,
- volume_info->UNCip,
- strlen(volume_info->UNCip),
- volume_info->port);
- if (!rc)
- goto out;
-
- if (!match_server(tcp_srv, (struct sockaddr *)&addr, volume_info) ||
+ if (!match_server(tcp_srv, dstaddr, volume_info) ||
!match_session(ses, volume_info) ||
!match_tcon(tcon, volume_info->UNC)) {
rc = 0;
@@ -3248,8 +3225,6 @@ cleanup_volume_info_contents(struct smb_vol *volume_info)
{
kfree(volume_info->username);
kzfree(volume_info->password);
- if (volume_info->UNCip != volume_info->UNC + 2)
- kfree(volume_info->UNCip);
kfree(volume_info->UNC);
kfree(volume_info->domainname);
kfree(volume_info->iocharset);