aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/connect.c
diff options
context:
space:
mode:
authorSteve French <sfrench@us.ibm.com>2005-08-23 00:38:31 -0400
committerSteve French <sfrench@us.ibm.com>2005-08-23 00:38:31 -0400
commita10faeb2a3e266385cc334fe9af76e08e5e4330f (patch)
tree1649766060aeb1bd56fc51af769646ac9ec84539 /fs/cifs/connect.c
parentb92327fe6b25d60004b79df9e3c19091c03118ba (diff)
[CIFS] Support for mounting to older, pre-CIFS servers added. This
allows specifying an RFC1001 target "called" name (netbios name of the server, which can now be pecified as mount option "servernetbiosname" but will eventually be passed in automatically on retry of host down error messages caused when server refuses to handle default server name and can not handle port 445). This is an important step, but additional testing and fixup is needed to add remaining function needed for these. Signed-off-by: Steve French (sfrench@us.ibm.com)
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 ac2c8bdc8e5..9d61844e89b 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 }