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.c57
1 files changed, 48 insertions, 9 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index ac2c8bdc8e55..9d61844e89b6 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -63,6 +63,7 @@ struct smb_vol {
63 char *in6_addr; /* ipv6 address as human readable form of in6_addr */ 63 char *in6_addr; /* ipv6 address as human readable form of in6_addr */
64 char *iocharset; /* local code page for mapping to and from Unicode */ 64 char *iocharset; /* local code page for mapping to and from Unicode */
65 char source_rfc1001_name[16]; /* netbios name of client */ 65 char source_rfc1001_name[16]; /* netbios name of client */
66 char target_rfc1001_name[16]; /* netbios name of server for Win9x/ME */
66 uid_t linux_uid; 67 uid_t linux_uid;
67 gid_t linux_gid; 68 gid_t linux_gid;
68 mode_t file_mode; 69 mode_t file_mode;
@@ -89,7 +90,8 @@ struct smb_vol {
89 90
90static int ipv4_connect(struct sockaddr_in *psin_server, 91static int ipv4_connect(struct sockaddr_in *psin_server,
91 struct socket **csocket, 92 struct socket **csocket,
92 char * netb_name); 93 char * netb_name,
94 char * server_netb_name);
93static int ipv6_connect(struct sockaddr_in6 *psin_server, 95static int ipv6_connect(struct sockaddr_in6 *psin_server,
94 struct socket **csocket); 96 struct socket **csocket);
95 97
@@ -182,7 +184,8 @@ cifs_reconnect(struct TCP_Server_Info *server)
182 } else { 184 } else {
183 rc = ipv4_connect(&server->addr.sockAddr, 185 rc = ipv4_connect(&server->addr.sockAddr,
184 &server->ssocket, 186 &server->ssocket,
185 server->workstation_RFC1001_name); 187 server->workstation_RFC1001_name,
188 server->server_RFC1001_name);
186 } 189 }
187 if(rc) { 190 if(rc) {
188 msleep(3000); 191 msleep(3000);
@@ -743,7 +746,9 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
743 toupper(system_utsname.nodename[i]); 746 toupper(system_utsname.nodename[i]);
744 } 747 }
745 vol->source_rfc1001_name[15] = 0; 748 vol->source_rfc1001_name[15] = 0;
746 749 /* null target name indicates to use *SMBSERVR default called name
750 if we end up sending RFC1001 session initialize */
751 vol->target_rfc1001_name[0] = 0;
747 vol->linux_uid = current->uid; /* current->euid instead? */ 752 vol->linux_uid = current->uid; /* current->euid instead? */
748 vol->linux_gid = current->gid; 753 vol->linux_gid = current->gid;
749 vol->dir_mode = S_IRWXUGO; 754 vol->dir_mode = S_IRWXUGO;
@@ -996,7 +1001,31 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
996 /* The string has 16th byte zero still from 1001 /* The string has 16th byte zero still from
997 set at top of the function */ 1002 set at top of the function */
998 if((i==15) && (value[i] != 0)) 1003 if((i==15) && (value[i] != 0))
999 printk(KERN_WARNING "CIFS: netbiosname longer than 15 and was truncated.\n"); 1004 printk(KERN_WARNING "CIFS: netbiosname longer than 15 truncated.\n");
1005 }
1006 } else if (strnicmp(data, "servern", 7) == 0) {
1007 /* servernetbiosname specified override *SMBSERVER */
1008 if (!value || !*value || (*value == ' ')) {
1009 cFYI(1,("empty server netbiosname specified"));
1010 } else {
1011 /* last byte, type, is 0x20 for servr type */
1012 memset(vol->target_rfc1001_name,0x20,16);
1013
1014 for(i=0;i<15;i++) {
1015 /* BB are there cases in which a comma can be
1016 valid in this workstation netbios name (and need
1017 special handling)? */
1018
1019 /* user or mount helper must uppercase netbiosname */
1020 if (value[i]==0)
1021 break;
1022 else
1023 vol->target_rfc1001_name[i] = value[i];
1024 }
1025 /* The string has 16th byte zero still from
1026 set at top of the function */
1027 if((i==15) && (value[i] != 0))
1028 printk(KERN_WARNING "CIFS: server netbiosname longer than 15 truncated.\n");
1000 } 1029 }
1001 } else if (strnicmp(data, "credentials", 4) == 0) { 1030 } else if (strnicmp(data, "credentials", 4) == 0) {
1002 /* ignore */ 1031 /* ignore */
@@ -1042,7 +1071,8 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
1042 vol->posix_paths = 1; 1071 vol->posix_paths = 1;
1043 } else if (strnicmp(data, "noposixpaths", 12) == 0) { 1072 } else if (strnicmp(data, "noposixpaths", 12) == 0) {
1044 vol->posix_paths = 0; 1073 vol->posix_paths = 0;
1045 } else if (strnicmp(data, "nocase", 6) == 0) { 1074 } else if ((strnicmp(data, "nocase", 6) == 0) ||
1075 (strnicmp(data, "ignorecase", 10) == 0)) {
1046 vol->nocase = 1; 1076 vol->nocase = 1;
1047 } else if (strnicmp(data, "brl", 3) == 0) { 1077 } else if (strnicmp(data, "brl", 3) == 0) {
1048 vol->nobrl = 0; 1078 vol->nobrl = 0;
@@ -1272,7 +1302,7 @@ static void rfc1002mangle(char * target,char * source, unsigned int length)
1272 1302
1273static int 1303static int
1274ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket, 1304ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket,
1275 char * netbios_name) 1305 char * netbios_name, char * target_name)
1276{ 1306{
1277 int rc = 0; 1307 int rc = 0;
1278 int connected = 0; 1308 int connected = 0;
@@ -1350,8 +1380,14 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket,
1350 ses_init_buf = kcalloc(1, sizeof(struct rfc1002_session_packet), GFP_KERNEL); 1380 ses_init_buf = kcalloc(1, sizeof(struct rfc1002_session_packet), GFP_KERNEL);
1351 if(ses_init_buf) { 1381 if(ses_init_buf) {
1352 ses_init_buf->trailer.session_req.called_len = 32; 1382 ses_init_buf->trailer.session_req.called_len = 32;
1353 rfc1002mangle(ses_init_buf->trailer.session_req.called_name, 1383 if(target_name && (target_name[0] != 0)) {
1354 DEFAULT_CIFS_CALLED_NAME,16); 1384 rfc1002mangle(ses_init_buf->trailer.session_req.called_name,
1385 target_name, 16);
1386 } else {
1387 rfc1002mangle(ses_init_buf->trailer.session_req.called_name,
1388 DEFAULT_CIFS_CALLED_NAME,16);
1389 }
1390
1355 ses_init_buf->trailer.session_req.calling_len = 32; 1391 ses_init_buf->trailer.session_req.calling_len = 32;
1356 /* calling name ends in null (byte 16) from old smb 1392 /* calling name ends in null (byte 16) from old smb
1357 convention. */ 1393 convention. */
@@ -1584,7 +1620,9 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1584 sin_server.sin_port = htons(volume_info.port); 1620 sin_server.sin_port = htons(volume_info.port);
1585 else 1621 else
1586 sin_server.sin_port = 0; 1622 sin_server.sin_port = 0;
1587 rc = ipv4_connect(&sin_server,&csocket,volume_info.source_rfc1001_name); 1623 rc = ipv4_connect(&sin_server,&csocket,
1624 volume_info.source_rfc1001_name,
1625 volume_info.target_rfc1001_name);
1588 if (rc < 0) { 1626 if (rc < 0) {
1589 cERROR(1, 1627 cERROR(1,
1590 ("Error connecting to IPv4 socket. Aborting operation")); 1628 ("Error connecting to IPv4 socket. Aborting operation"));
@@ -1638,6 +1676,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1638 wait_for_completion(&cifsd_complete); 1676 wait_for_completion(&cifsd_complete);
1639 rc = 0; 1677 rc = 0;
1640 memcpy(srvTcp->workstation_RFC1001_name, volume_info.source_rfc1001_name,16); 1678 memcpy(srvTcp->workstation_RFC1001_name, volume_info.source_rfc1001_name,16);
1679 memcpy(srvTcp->server_RFC1001_name, volume_info.target_rfc1001_name,16);
1641 srvTcp->sequence_number = 0; 1680 srvTcp->sequence_number = 0;
1642 } 1681 }
1643 } 1682 }