Commit b7df0fd6 authored by Steve French's avatar Steve French Committed by Steve French

rfc1001 session init name parsing fix

parent c745d58e
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include <linux/version.h> #include <linux/version.h>
#include <linux/ipv6.h> #include <linux/ipv6.h>
#include <linux/pagemap.h> #include <linux/pagemap.h>
#include <linux/ctype.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/processor.h> #include <asm/processor.h>
#include "cifspdu.h" #include "cifspdu.h"
...@@ -67,8 +68,11 @@ struct smb_vol { ...@@ -67,8 +68,11 @@ struct smb_vol {
unsigned short int port; unsigned short int port;
}; };
static int ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket); static int ipv4_connect(struct sockaddr_in *psin_server,
static int ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket); struct socket **csocket,
char * netb_name);
static int ipv6_connect(struct sockaddr_in6 *psin_server,
struct socket **csocket);
/* /*
...@@ -149,7 +153,9 @@ cifs_reconnect(struct TCP_Server_Info *server) ...@@ -149,7 +153,9 @@ cifs_reconnect(struct TCP_Server_Info *server)
if(server->protocolType == IPV6) { if(server->protocolType == IPV6) {
rc = ipv6_connect(&server->addr.sockAddr6,&server->ssocket); rc = ipv6_connect(&server->addr.sockAddr6,&server->ssocket);
} else { } else {
rc = ipv4_connect(&server->addr.sockAddr, &server->ssocket); rc = ipv4_connect(&server->addr.sockAddr,
&server->ssocket,
server->workstation_RFC1001_name);
} }
if(rc) { if(rc) {
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
...@@ -160,7 +166,6 @@ cifs_reconnect(struct TCP_Server_Info *server) ...@@ -160,7 +166,6 @@ cifs_reconnect(struct TCP_Server_Info *server)
wake_up(&server->response_q); wake_up(&server->response_q);
} }
} }
return rc; return rc;
} }
...@@ -456,12 +461,21 @@ cifs_parse_mount_options(char *options, const char *devname, struct smb_vol *vol ...@@ -456,12 +461,21 @@ cifs_parse_mount_options(char *options, const char *devname, struct smb_vol *vol
{ {
char *value; char *value;
char *data; char *data;
int temp_len, i, j; unsigned int temp_len, i, j;
char separator[2]; char separator[2];
separator[0] = ','; separator[0] = ',';
separator[1] = 0; separator[1] = 0;
memset(vol->source_rfc1001_name,0x20,15);
for(i=0;i < strnlen(system_utsname.nodename,15);i++) {
/* does not have to be a perfect mapping since the field is
informational, only used for servers that do not support
port 445 and it can be overridden at mount time */
vol->source_rfc1001_name[i] = toupper(system_utsname.nodename[i]);
}
vol->source_rfc1001_name[15] = 0;
vol->linux_uid = current->uid; /* current->euid instead? */ vol->linux_uid = current->uid; /* current->euid instead? */
vol->linux_gid = current->gid; vol->linux_gid = current->gid;
vol->dir_mode = S_IRWXUGO; vol->dir_mode = S_IRWXUGO;
...@@ -654,15 +668,25 @@ cifs_parse_mount_options(char *options, const char *devname, struct smb_vol *vol ...@@ -654,15 +668,25 @@ cifs_parse_mount_options(char *options, const char *devname, struct smb_vol *vol
simple_strtoul(value, &value, 0); simple_strtoul(value, &value, 0);
} }
} else if (strnicmp(data, "netbiosname", 4) == 0) { } else if (strnicmp(data, "netbiosname", 4) == 0) {
if (!value || !*value) { if (!value || !*value || (*value == ' ')) {
cFYI(1,("invalid (empty) netbiosname specified")); cFYI(1,("invalid (empty) netbiosname specified"));
} else if (strnlen(value, 16) < 16) {
/* BB are there cases in which a comma can be
valid in the workstation name (and need special
case handling)? */
strncpy(vol->source_rfc1001_name,value,16);
} else { } else {
printk(KERN_WARNING "CIFS: netbiosname too long (more than 15)\n"); memset(vol->source_rfc1001_name,0x20,15);
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)? */
/* We do not uppercase netbiosname for user */
if (value[i]==0)
break;
else
vol->source_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: netbiosname longer than 15 and was truncated.\n");
} }
} else if (strnicmp(data, "version", 3) == 0) { } else if (strnicmp(data, "version", 3) == 0) {
/* ignore */ /* ignore */
...@@ -853,7 +877,7 @@ get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, ...@@ -853,7 +877,7 @@ get_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
/* See RFC1001 section 14 on representation of Netbios names */ /* See RFC1001 section 14 on representation of Netbios names */
static void rfc1002mangle(char * target,char * source, unsigned int length) static void rfc1002mangle(char * target,char * source, unsigned int length)
{ {
int i,j; unsigned int i,j;
for(i=0,j=0;i<(length);i++) { for(i=0,j=0;i<(length);i++) {
/* mask a nibble at a time and encode */ /* mask a nibble at a time and encode */
...@@ -866,7 +890,8 @@ static void rfc1002mangle(char * target,char * source, unsigned int length) ...@@ -866,7 +890,8 @@ static void rfc1002mangle(char * target,char * source, unsigned int length)
static int static int
ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket) ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket,
char * netbios_name)
{ {
int rc = 0; int rc = 0;
int connected = 0; int connected = 0;
...@@ -946,8 +971,13 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket) ...@@ -946,8 +971,13 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket)
rfc1002mangle(ses_init_buf->trailer.session_req.called_name, rfc1002mangle(ses_init_buf->trailer.session_req.called_name,
DEFAULT_CIFS_CALLED_NAME,16); DEFAULT_CIFS_CALLED_NAME,16);
ses_init_buf->trailer.session_req.calling_len = 32; ses_init_buf->trailer.session_req.calling_len = 32;
rfc1002mangle(ses_init_buf->trailer.session_req.calling_name, if(netbios_name && (netbios_name[0] !=0)) {
"LINUX_CIFS_CLNT",16); rfc1002mangle(ses_init_buf->trailer.session_req.calling_name,
netbios_name,16);
} else {
rfc1002mangle(ses_init_buf->trailer.session_req.calling_name,
"LINUX_CIFS_CLNT",16);
}
ses_init_buf->trailer.session_req.scope1 = 0; ses_init_buf->trailer.session_req.scope1 = 0;
ses_init_buf->trailer.session_req.scope2 = 0; ses_init_buf->trailer.session_req.scope2 = 0;
/* BB fixme ensure calling space padded w/null terminate*/ /* BB fixme ensure calling space padded w/null terminate*/
...@@ -1142,7 +1172,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, ...@@ -1142,7 +1172,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
sin_server.sin_port = htons(volume_info.port); sin_server.sin_port = htons(volume_info.port);
else else
sin_server.sin_port = 0; sin_server.sin_port = 0;
rc = ipv4_connect(&sin_server, &csocket); rc = ipv4_connect(&sin_server,&csocket,volume_info.source_rfc1001_name);
if (rc < 0) { if (rc < 0) {
cERROR(1, cERROR(1,
("Error connecting to IPv4 socket. Aborting operation")); ("Error connecting to IPv4 socket. Aborting operation"));
...@@ -1178,6 +1208,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, ...@@ -1178,6 +1208,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
init_MUTEX(&srvTcp->tcpSem); init_MUTEX(&srvTcp->tcpSem);
kernel_thread((void *)(void *)cifs_demultiplex_thread, srvTcp, kernel_thread((void *)(void *)cifs_demultiplex_thread, srvTcp,
CLONE_FS | CLONE_FILES | CLONE_VM); CLONE_FS | CLONE_FILES | CLONE_VM);
memcpy(srvTcp->workstation_RFC1001_name, volume_info.source_rfc1001_name,16);
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment