[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

@@ -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;
}
}