aboutsummaryrefslogtreecommitdiffstats
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
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)
-rw-r--r--fs/cifs/CHANGES7
-rw-r--r--fs/cifs/cifsglob.h6
-rw-r--r--fs/cifs/connect.c57
3 files changed, 58 insertions, 12 deletions
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index b0429ea524fb..2137002aecc4 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -1,5 +1,6 @@
1Version 1.36 1Version 1.36
2------------ 2------------
3Add support for moounting to older pre-CIFS servers such as Windows9x and ME.
3Add mount option for disabling the default behavior of sending byte range lock 4Add mount option for disabling the default behavior of sending byte range lock
4requests to the server (necessary for certain applications which break with 5requests to the server (necessary for certain applications which break with
5mandatory lock behavior such as Evolution), and also mount option for 6mandatory lock behavior such as Evolution), and also mount option for
@@ -10,7 +11,11 @@ Version 1.35
10------------ 11------------
11Add writepage performance improvements. Fix path name conversions 12Add writepage performance improvements. Fix path name conversions
12for long filenames on mounts which were done with "mapchars" mount option 13for long filenames on mounts which were done with "mapchars" mount option
13specified. 14specified. Ensure multiplex ids do not collide. Fix case in which
15rmmod can oops if done soon after last unmount. Fix truncated
16search (readdir) output when resume filename was a long filename.
17Fix filename conversion when mapchars mount option was specified and
18filename was a long filename.
14 19
15Version 1.34 20Version 1.34
16------------ 21------------
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 6a8c7d1bee8c..f143975627e0 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -110,7 +110,8 @@ enum protocolEnum {
110 */ 110 */
111 111
112struct TCP_Server_Info { 112struct TCP_Server_Info {
113 char server_Name[SERVER_NAME_LEN_WITH_NULL]; /* 15 chars + X'20' 16th */ 113 /* 15 character server name + 0x20 16th byte indicating type = srv */
114 char server_RFC1001_name[SERVER_NAME_LEN_WITH_NULL];
114 char unicode_server_Name[SERVER_NAME_LEN_WITH_NULL * 2]; 115 char unicode_server_Name[SERVER_NAME_LEN_WITH_NULL * 2];
115 struct socket *ssocket; 116 struct socket *ssocket;
116 union { 117 union {
@@ -149,7 +150,8 @@ struct TCP_Server_Info {
149 __u16 timeZone; 150 __u16 timeZone;
150 __u16 CurrentMid; /* multiplex id - rotating counter */ 151 __u16 CurrentMid; /* multiplex id - rotating counter */
151 char cryptKey[CIFS_CRYPTO_KEY_SIZE]; 152 char cryptKey[CIFS_CRYPTO_KEY_SIZE];
152 char workstation_RFC1001_name[16]; /* 16th byte is always zero */ 153 /* 16th byte of RFC1001 workstation name is always null */
154 char workstation_RFC1001_name[SERVER_NAME_LEN_WITH_NULL];
153 __u32 sequence_number; /* needed for CIFS PDU signature */ 155 __u32 sequence_number; /* needed for CIFS PDU signature */
154 char mac_signing_key[CIFS_SESSION_KEY_SIZE + 16]; 156 char mac_signing_key[CIFS_SESSION_KEY_SIZE + 16];
155}; 157};
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 }