[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)
This commit is contained in:
Steve French 2005-08-22 21:38:31 -07:00
parent b92327fe6b
commit a10faeb2a3
3 changed files with 58 additions and 12 deletions

View File

@ -1,5 +1,6 @@
Version 1.36
------------
Add support for moounting to older pre-CIFS servers such as Windows9x and ME.
Add mount option for disabling the default behavior of sending byte range lock
requests to the server (necessary for certain applications which break with
mandatory lock behavior such as Evolution), and also mount option for
@ -10,7 +11,11 @@ Version 1.35
------------
Add writepage performance improvements. Fix path name conversions
for long filenames on mounts which were done with "mapchars" mount option
specified.
specified. Ensure multiplex ids do not collide. Fix case in which
rmmod can oops if done soon after last unmount. Fix truncated
search (readdir) output when resume filename was a long filename.
Fix filename conversion when mapchars mount option was specified and
filename was a long filename.
Version 1.34
------------

View File

@ -110,7 +110,8 @@ enum protocolEnum {
*/
struct TCP_Server_Info {
char server_Name[SERVER_NAME_LEN_WITH_NULL]; /* 15 chars + X'20' 16th */
/* 15 character server name + 0x20 16th byte indicating type = srv */
char server_RFC1001_name[SERVER_NAME_LEN_WITH_NULL];
char unicode_server_Name[SERVER_NAME_LEN_WITH_NULL * 2];
struct socket *ssocket;
union {
@ -149,7 +150,8 @@ struct TCP_Server_Info {
__u16 timeZone;
__u16 CurrentMid; /* multiplex id - rotating counter */
char cryptKey[CIFS_CRYPTO_KEY_SIZE];
char workstation_RFC1001_name[16]; /* 16th byte is always zero */
/* 16th byte of RFC1001 workstation name is always null */
char workstation_RFC1001_name[SERVER_NAME_LEN_WITH_NULL];
__u32 sequence_number; /* needed for CIFS PDU signature */
char mac_signing_key[CIFS_SESSION_KEY_SIZE + 16];
};

View File

@ -63,6 +63,7 @@ struct smb_vol {
char *in6_addr; /* ipv6 address as human readable form of in6_addr */
char *iocharset; /* local code page for mapping to and from Unicode */
char source_rfc1001_name[16]; /* netbios name of client */
char target_rfc1001_name[16]; /* netbios name of server for Win9x/ME */
uid_t linux_uid;
gid_t linux_gid;
mode_t file_mode;
@ -89,7 +90,8 @@ struct smb_vol {
static int ipv4_connect(struct sockaddr_in *psin_server,
struct socket **csocket,
char * netb_name);
char * netb_name,
char * server_netb_name);
static int ipv6_connect(struct sockaddr_in6 *psin_server,
struct socket **csocket);
@ -182,7 +184,8 @@ cifs_reconnect(struct TCP_Server_Info *server)
} else {
rc = ipv4_connect(&server->addr.sockAddr,
&server->ssocket,
server->workstation_RFC1001_name);
server->workstation_RFC1001_name,
server->server_RFC1001_name);
}
if(rc) {
msleep(3000);
@ -743,7 +746,9 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
toupper(system_utsname.nodename[i]);
}
vol->source_rfc1001_name[15] = 0;
/* null target name indicates to use *SMBSERVR default called name
if we end up sending RFC1001 session initialize */
vol->target_rfc1001_name[0] = 0;
vol->linux_uid = current->uid; /* current->euid instead? */
vol->linux_gid = current->gid;
vol->dir_mode = S_IRWXUGO;
@ -996,7 +1001,31 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
/* The string has 16th byte zero still from
set at top of the function */
if((i==15) && (value[i] != 0))
printk(KERN_WARNING "CIFS: netbiosname longer than 15 and was truncated.\n");
printk(KERN_WARNING "CIFS: netbiosname longer than 15 truncated.\n");
}
} else if (strnicmp(data, "servern", 7) == 0) {
/* servernetbiosname specified override *SMBSERVER */
if (!value || !*value || (*value == ' ')) {
cFYI(1,("empty server netbiosname specified"));
} else {
/* last byte, type, is 0x20 for servr type */
memset(vol->target_rfc1001_name,0x20,16);
for(i=0;i<15;i++) {
/* BB are there cases in which a comma can be
valid in this workstation netbios name (and need
special handling)? */
/* user or mount helper must uppercase netbiosname */
if (value[i]==0)
break;
else
vol->target_rfc1001_name[i] = value[i];
}
/* The string has 16th byte zero still from
set at top of the function */
if((i==15) && (value[i] != 0))
printk(KERN_WARNING "CIFS: server netbiosname longer than 15 truncated.\n");
}
} else if (strnicmp(data, "credentials", 4) == 0) {
/* ignore */
@ -1042,7 +1071,8 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
vol->posix_paths = 1;
} else if (strnicmp(data, "noposixpaths", 12) == 0) {
vol->posix_paths = 0;
} else if (strnicmp(data, "nocase", 6) == 0) {
} else if ((strnicmp(data, "nocase", 6) == 0) ||
(strnicmp(data, "ignorecase", 10) == 0)) {
vol->nocase = 1;
} else if (strnicmp(data, "brl", 3) == 0) {
vol->nobrl = 0;
@ -1272,7 +1302,7 @@ static void rfc1002mangle(char * target,char * source, unsigned int length)
static int
ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket,
char * netbios_name)
char * netbios_name, char * target_name)
{
int rc = 0;
int connected = 0;
@ -1350,8 +1380,14 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket,
ses_init_buf = kcalloc(1, sizeof(struct rfc1002_session_packet), GFP_KERNEL);
if(ses_init_buf) {
ses_init_buf->trailer.session_req.called_len = 32;
rfc1002mangle(ses_init_buf->trailer.session_req.called_name,
DEFAULT_CIFS_CALLED_NAME,16);
if(target_name && (target_name[0] != 0)) {
rfc1002mangle(ses_init_buf->trailer.session_req.called_name,
target_name, 16);
} else {
rfc1002mangle(ses_init_buf->trailer.session_req.called_name,
DEFAULT_CIFS_CALLED_NAME,16);
}
ses_init_buf->trailer.session_req.calling_len = 32;
/* calling name ends in null (byte 16) from old smb
convention. */
@ -1584,7 +1620,9 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
sin_server.sin_port = htons(volume_info.port);
else
sin_server.sin_port = 0;
rc = ipv4_connect(&sin_server,&csocket,volume_info.source_rfc1001_name);
rc = ipv4_connect(&sin_server,&csocket,
volume_info.source_rfc1001_name,
volume_info.target_rfc1001_name);
if (rc < 0) {
cERROR(1,
("Error connecting to IPv4 socket. Aborting operation"));
@ -1638,6 +1676,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
wait_for_completion(&cifsd_complete);
rc = 0;
memcpy(srvTcp->workstation_RFC1001_name, volume_info.source_rfc1001_name,16);
memcpy(srvTcp->server_RFC1001_name, volume_info.target_rfc1001_name,16);
srvTcp->sequence_number = 0;
}
}