bk://cifs.bkbits.net/linux-2.5cifs stevef@smfhome.smfsambadom|ChangeSet|20040426034320|53426 stevef # This is a BitKeeper generated diff -Nru style patch. # # ChangeSet # 2004/04/25 22:43:20-05:00 stevef@smfhome.smfsambadom # Remove unneeded debug statement # # fs/cifs/connect.c # 2004/04/25 22:42:58-05:00 stevef@smfhome.smfsambadom +0 -1 # Remove unneeded debug statement # # ChangeSet # 2004/04/25 22:41:35-05:00 stevef@smfhome.smfsambadom # Fix port 139 connections to Windows 2K adding missing RFC1002 session_init # # fs/cifs/rfc1002pdu.h # 2004/04/25 22:41:28-05:00 stevef@smfhome.smfsambadom +6 -2 # Fix port 139 connections to Windows 2K adding missing RFC1002 session_init # # fs/cifs/file.c # 2004/04/25 22:41:28-05:00 stevef@smfhome.smfsambadom +1 -1 # fix typo in comment # # fs/cifs/connect.c # 2004/04/25 22:41:28-05:00 stevef@smfhome.smfsambadom +74 -11 # Fix port 139 connections to Windows 2K adding missing RFC1002 session_init # # fs/cifs/cifsglob.h # 2004/04/25 22:41:28-05:00 stevef@smfhome.smfsambadom +1 -0 # Fix port 139 connections to Windows 2K adding missing RFC1002 session_init # # ChangeSet # 2004/04/23 12:36:52-07:00 akpm@bix.(none) # Merge bk://cifs.bkbits.net/linux-2.5cifs # into bix.(none):/usr/src/bk-cifs # # fs/cifs/cifsfs.c # 2004/04/23 12:36:49-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/04/19 19:23:58-07:00 akpm@bix.(none) # Merge bk://cifs.bkbits.net/linux-2.5cifs # into bix.(none):/usr/src/bk-cifs # # fs/cifs/cifsfs.c # 2004/04/19 19:23:56-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/04/16 20:19:53-07:00 akpm@bix.(none) # Merge bk://cifs.bkbits.net/linux-2.5cifs # into bix.(none):/usr/src/bk-cifs # # fs/cifs/cifsfs.c # 2004/04/16 20:19:51-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/04/16 20:18:59-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-cifs # # fs/cifs/cifsfs.c # 2004/04/16 20:18:56-07:00 akpm@bix.(none) +0 -0 # Auto merged # diff -Nru a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h --- a/fs/cifs/cifsglob.h Sun Apr 25 22:46:16 2004 +++ b/fs/cifs/cifsglob.h Sun Apr 25 22:46:16 2004 @@ -174,6 +174,7 @@ uid_t linux_uid; /* local Linux uid */ int capabilities; char serverName[SERVER_NAME_LEN_WITH_NULL * 2]; /* BB make bigger for tcp names - will ipv6 and sctp addresses fit here?? */ + char workstation_RFC1001_name[15]; /* 16th byte is always zero */ char userName[MAX_USERNAME_SIZE + 1]; char domainName[MAX_USERNAME_SIZE + 1]; char * password; diff -Nru a/fs/cifs/connect.c b/fs/cifs/connect.c --- a/fs/cifs/connect.c Sun Apr 25 22:46:16 2004 +++ b/fs/cifs/connect.c Sun Apr 25 22:46:16 2004 @@ -54,7 +54,7 @@ char *UNC; char *UNCip; char *iocharset; /* local code page for mapping to and from Unicode */ - char *source_rfc1001_name; /* netbios name of client */ + char source_rfc1001_name[16]; /* netbios name of client */ uid_t linux_uid; gid_t linux_gid; mode_t file_mode; @@ -67,8 +67,8 @@ unsigned short int port; }; -int ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket); -int ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket); +static int ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket); +static int ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket); /* @@ -590,6 +590,8 @@ printk(KERN_WARNING "CIFS: invalid domain name\n"); return 1; /* needs_arg; */ } + /* BB are there cases in which a comma can be valid in + a domain name and need special handling? */ if (strnlen(value, 65) < 65) { vol->domainname = value; cFYI(1, ("Domain name set")); @@ -653,9 +655,12 @@ } } else if (strnicmp(data, "netbiosname", 4) == 0) { if (!value || !*value) { - vol->source_rfc1001_name = NULL; - } else if (strnlen(value, 17) < 17) { - vol->source_rfc1001_name = value; + 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 { printk(KERN_WARNING "CIFS: netbiosname too long (more than 15)\n"); } @@ -845,7 +850,22 @@ return rc; } -int +/* See RFC1001 section 14 on representation of Netbios names */ +static void rfc1002mangle(char * target,char * source, unsigned int length) +{ + int i,j; + + for(i=0,j=0;i<(length);i++) { + /* mask a nibble at a time and encode */ + target[j] = 'A' + (0x0F & (source[i] >> 4)); + target[j+1] = 'A' + (0x0F & source[i]); + j+=2; + } + +} + + +static int ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket) { int rc = 0; @@ -865,7 +885,6 @@ } psin_server->sin_family = AF_INET; - if(psin_server->sin_port) { /* user overrode default port */ rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *) psin_server, @@ -912,11 +931,42 @@ the default. sock_setsockopt not used because it expects user space buffer */ (*csocket)->sk->sk_rcvtimeo = 7 * HZ; + + /* send RFC1001 sessinit */ + + if(psin_server->sin_port == htons(139)) { + /* some servers require RFC1001 sessinit before sending + negprot - BB check reconnection in case where second + sessinit is sent but no second negprot */ + struct rfc1002_session_packet * ses_init_buf; + struct smb_hdr * smb_buf; + ses_init_buf = cifs_kcalloc(36, 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); + ses_init_buf->trailer.session_req.calling_len = 32; + 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.scope2 = 0; + /* BB fixme ensure calling space padded w/null terminate*/ + smb_buf = (struct smb_hdr *)ses_init_buf; + /* sizeof RFC1002_SESSION_REQUEST with no scope */ + smb_buf->smb_buf_length = 0x81000044; + rc = smb_send(*csocket, smb_buf, 0x44, + (struct sockaddr *)psin_server); + kfree(ses_init_buf); + } + /* else the negprot may still work without this + even though malloc failed */ + + } return rc; } -int +static int ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket) { int rc = 0; @@ -1000,7 +1050,6 @@ /* cFYI(1, ("Entering cifs_mount. Xid: %d with: %s", xid, mount_data)); */ memset(&volume_info,0,sizeof(struct smb_vol)); - if (cifs_parse_mount_options(mount_data, devname, &volume_info)) { if(volume_info.UNC) kfree(volume_info.UNC); @@ -1049,6 +1098,12 @@ } else if (volume_info.UNCip){ /* BB using ip addr as server name connect to the DFS root below */ cERROR(1,("Connecting to DFS root not implemented yet")); + if(volume_info.UNC) + kfree(volume_info.UNC); + if(volume_info.password) + kfree(volume_info.password); + FreeXid(xid); + return -EINVAL; } else /* which servers DFS root would we conect to */ { cERROR(1, ("CIFS mount error: No UNC path (e.g. -o unc=//192.168.1.100/public) specified ")); @@ -1131,6 +1186,7 @@ cFYI(1, ("Existing smb sess found ")); if(volume_info.password) kfree(volume_info.password); + /* volume_info.UNC freed at end of function */ } else if (!rc) { cFYI(1, ("Existing smb sess not found ")); pSesInfo = sesInfoAlloc(); @@ -1142,7 +1198,8 @@ NIPQUAD(sin_server.sin_addr.s_addr)); } - if (!rc){ + if (!rc){ + /* volume_info.password freed at unmount */ if (volume_info.password) pSesInfo->password = volume_info.password; if (volume_info.username) @@ -1263,6 +1320,11 @@ if (tcon->ses->capabilities & CAP_UNIX) CIFSSMBQFSUnixInfo(xid, tcon, cifs_sb->local_nls); } + + /* volume_info.password is freed above when existing session found + (in which case it is not needed anymore) but when new sesion is created + the password ptr is put in the new session structure (in which case the + password will be freed at unmount time) */ if(volume_info.UNC) kfree(volume_info.UNC); FreeXid(xid); diff -Nru a/fs/cifs/file.c b/fs/cifs/file.c --- a/fs/cifs/file.c Sun Apr 25 22:46:16 2004 +++ b/fs/cifs/file.c Sun Apr 25 22:46:16 2004 @@ -1049,7 +1049,7 @@ } else if (bytes_read > 0) { pSMBr = (struct smb_com_read_rsp *)smb_read_data; cifs_copy_cache_pages(mapping, page_list, bytes_read, - smb_read_data + 4 /* RFC1000 hdr */ + + smb_read_data + 4 /* RFC1001 hdr */ + le16_to_cpu(pSMBr->DataOffset), &lru_pvec); i += bytes_read >> PAGE_CACHE_SHIFT; diff -Nru a/fs/cifs/rfc1002pdu.h b/fs/cifs/rfc1002pdu.h --- a/fs/cifs/rfc1002pdu.h Sun Apr 25 22:46:16 2004 +++ b/fs/cifs/rfc1002pdu.h Sun Apr 25 22:46:16 2004 @@ -42,8 +42,12 @@ __u16 length; union { struct { - __u8 called_name[16]; - __u8 calling_name[16]; + __u8 called_len; + __u8 called_name[32]; + __u8 scope1; /* null */ + __u8 calling_len; + __u8 calling_name[32]; + __u8 scope2; /* null */ } session_req; struct { __u32 retarget_ip_addr;