#include <linux/string.h>
#include <linux/list.h>
#include <linux/wait.h>
-#include <linux/version.h>
#include <linux/ipv6.h>
#include <linux/pagemap.h>
#include <linux/ctype.h>
char *domainname;
char *UNC;
char *UNCip;
+ 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 */
uid_t linux_uid;
unsigned intr:1;
unsigned setuids:1;
unsigned noperm:1;
+ unsigned no_psx_acl:1; /* set if posix acl support should be disabled */
+ unsigned server_ino:1; /* use inode numbers from server ie UniqueId */
+ unsigned direct_io:1;
unsigned int rsize;
unsigned int wsize;
unsigned int sockopt;
write_unlock(&GlobalSMBSeslock);
if(length > 1) {
mempool_resize(cifs_req_poolp,
- length + CIFS_MIN_RCV_POOL,
+ length + cifs_min_rcv,
GFP_KERNEL);
}
cFYI(1,("call to reconnect done"));
csocket = server->ssocket;
continue;
- } else if ((length == -ERESTARTSYS) || (length == -EAGAIN)) {
+ } else if ((length == -ERESTARTSYS) || (length == -EAGAIN)
+ || ((length > 0) && (length <= 3)) ) {
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(1); /* minimum sleep to prevent looping
allowing socket to clear and app threads to set
}
pdu_length = 4 + ntohl(smb_buffer->smb_buf_length);
- /* Ony read pdu_length after below checks for too short (due
+ /* Only read pdu_length after below checks for too short (due
to e.g. int overflow) and too long ie beyond end of buf */
cFYI(1, ("Peek length rcvd: 0x%x beginning 0x%x)", length, pdu_length));
csocket = server->ssocket;
continue;
} else {
- if ((length != sizeof (struct smb_hdr) - 1)
- || (pdu_length >
- CIFS_MAX_MSGSIZE + MAX_CIFS_HDR_SIZE)
+ if (length < 16) {
+ /* We can not validate the SMB unless
+ at least this much of SMB available
+ so give the socket time to copy
+ a few more bytes and retry */
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(10);
+ continue;
+ } else if( (pdu_length >
+ CIFSMaxBufSize + MAX_CIFS_HDR_SIZE)
|| (pdu_length <
sizeof (struct smb_hdr) - 1)
- ||
- (checkSMBhdr
+ || (checkSMBhdr
(smb_buffer, smb_buffer->Mid))) {
cERROR(1,
- ("Invalid size or format for SMB found with length %d and pdu_lenght %d",
+ ("Invalid size or format for SMB found with length %d and pdu_length %d",
length, pdu_length));
- cifs_dump_mem("Received Data is: ",temp,sizeof(struct smb_hdr));
+ cifs_dump_mem("Received Data is: ",temp,sizeof(struct smb_hdr)+3);
/* could we fix this network corruption by finding next
smb header (instead of killing the session) and
restart reading from next valid SMB found? */
write_unlock(&GlobalSMBSeslock);
if(length > 0) {
mempool_resize(cifs_req_poolp,
- length + CIFS_MIN_RCV_POOL,
+ length + cifs_min_rcv,
GFP_KERNEL);
}
}
static int
-cifs_parse_mount_options(char *options, const char *devname, struct smb_vol *vol)
+cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
{
char *value;
char *data;
vol->file_mode =
simple_strtoul(value, &value, 0);
}
- } else if (strnicmp(data, "dir_mode", 3) == 0) {
+ } else if (strnicmp(data, "dir_mode", 4) == 0) {
+ if (value && *value) {
+ vol->dir_mode =
+ simple_strtoul(value, &value, 0);
+ }
+ } else if (strnicmp(data, "dirmode", 4) == 0) {
if (value && *value) {
vol->dir_mode =
simple_strtoul(value, &value, 0);
/* ignore */
} else if (strnicmp(data, "version", 3) == 0) {
/* ignore */
+ } else if (strnicmp(data, "guest",5) == 0) {
+ /* ignore */
} else if (strnicmp(data, "rw", 2) == 0) {
vol->rw = TRUE;
} else if ((strnicmp(data, "suid", 4) == 0) ||
vol->intr = 0;
} else if (strnicmp(data, "intr", 4) == 0) {
vol->intr = 1;
+ } else if (strnicmp(data, "serverino",7) == 0) {
+ vol->server_ino = 1;
+ } else if (strnicmp(data, "noserverino",9) == 0) {
+ vol->server_ino = 0;
+ } else if (strnicmp(data, "acl",3) == 0) {
+ vol->no_psx_acl = 0;
+ } else if (strnicmp(data, "noacl",5) == 0) {
+ vol->no_psx_acl = 1;
+ } else if (strnicmp(data, "direct",6) == 0) {
+ vol->direct_io = 1;
+ } else if (strnicmp(data, "forcedirectio",13) == 0) {
+ vol->direct_io = 1;
+ } else if (strnicmp(data, "in6_addr",8) == 0) {
+ if (!value || !*value) {
+ vol->in6_addr = NULL;
+ } else if (strnlen(value, 49) == 48) {
+ vol->in6_addr = value;
+ } else {
+ printk(KERN_WARNING "CIFS: ip v6 address not 48 characters long\n");
+ return 1;
+ }
} else if (strnicmp(data, "noac", 4) == 0) {
printk(KERN_WARNING "CIFS: Mount option noac not supported. Instead set /proc/fs/cifs/LookupCacheEnabled to 0\n");
} else
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
if(volume_info.setuids)
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID;
+ if(volume_info.server_ino)
+ cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SERVER_INUM;
+ if(volume_info.direct_io) {
+ cERROR(1,("mounting share using direct i/o"));
+ cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
+ }
tcon =
find_unc(sin_server.sin_addr.s_addr, volume_info.UNC,
sb->s_maxbytes = (u64) 1 << 31; /* 2 GB */
}
+ sb->s_time_gran = 100;
+
/* on error free sesinfo and tcon struct if needed */
if (rc) {
/* if session setup failed, use count is zero but
/* do not care if following two calls succeed - informational only */
CIFSSMBQFSDeviceInfo(xid, tcon, cifs_sb->local_nls);
CIFSSMBQFSAttributeInfo(xid, tcon, cifs_sb->local_nls);
- if (tcon->ses->capabilities & CAP_UNIX)
- CIFSSMBQFSUnixInfo(xid, tcon, cifs_sb->local_nls);
+ if (tcon->ses->capabilities & CAP_UNIX) {
+ if(!CIFSSMBQFSUnixInfo(xid, tcon, cifs_sb->local_nls)) {
+ if(!volume_info.no_psx_acl) {
+ if(CIFS_UNIX_POSIX_ACL_CAP &
+ le64_to_cpu(tcon->fsUnixInfo.Capability))
+ cFYI(1,("server negotiated posix acl support"));
+ sb->s_flags |= MS_POSIXACL;
+ }
+ }
+ }
}
/* volume_info.password is freed above when existing session found
capabilities |= CAP_DFS;
}
pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
- /* pSMB->req_no_secext.CaseInsensitivePasswordLength =
- CIFS_SESSION_KEY_SIZE; */
- pSMB->req_no_secext.CaseInsensitivePasswordLength = 0;
+
+ pSMB->req_no_secext.CaseInsensitivePasswordLength =
+ cpu_to_le16(CIFS_SESSION_KEY_SIZE);
+
pSMB->req_no_secext.CaseSensitivePasswordLength =
cpu_to_le16(CIFS_SESSION_KEY_SIZE);
bcc_ptr = pByteArea(smb_buffer);
- /* memcpy(bcc_ptr, (char *) lm_session_key, CIFS_SESSION_KEY_SIZE);
- bcc_ptr += CIFS_SESSION_KEY_SIZE; */
+ memcpy(bcc_ptr, (char *) session_key, CIFS_SESSION_KEY_SIZE);
+ bcc_ptr += CIFS_SESSION_KEY_SIZE;
memcpy(bcc_ptr, (char *) session_key, CIFS_SESSION_KEY_SIZE);
bcc_ptr += CIFS_SESSION_KEY_SIZE;
32, nls_codepage);
bcc_ptr += 2 * bytes_returned;
bytes_returned =
- cifs_strtoUCS((wchar_t *) bcc_ptr, UTS_RELEASE, 32,
+ cifs_strtoUCS((wchar_t *) bcc_ptr, system_utsname.release, 32,
nls_codepage);
bcc_ptr += 2 * bytes_returned;
bcc_ptr += 2;
}
strcpy(bcc_ptr, "Linux version ");
bcc_ptr += strlen("Linux version ");
- strcpy(bcc_ptr, UTS_RELEASE);
- bcc_ptr += strlen(UTS_RELEASE) + 1;
+ strcpy(bcc_ptr, system_utsname.release);
+ bcc_ptr += strlen(system_utsname.release) + 1;
strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
}
32, nls_codepage);
bcc_ptr += 2 * bytes_returned;
bytes_returned =
- cifs_strtoUCS((wchar_t *) bcc_ptr, UTS_RELEASE, 32,
+ cifs_strtoUCS((wchar_t *) bcc_ptr, system_utsname.release, 32,
nls_codepage);
bcc_ptr += 2 * bytes_returned;
bcc_ptr += 2;
}
strcpy(bcc_ptr, "Linux version ");
bcc_ptr += strlen("Linux version ");
- strcpy(bcc_ptr, UTS_RELEASE);
- bcc_ptr += strlen(UTS_RELEASE) + 1;
+ strcpy(bcc_ptr, system_utsname.release);
+ bcc_ptr += strlen(system_utsname.release) + 1;
strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
}
32, nls_codepage);
bcc_ptr += 2 * bytes_returned;
bytes_returned =
- cifs_strtoUCS((wchar_t *) bcc_ptr, UTS_RELEASE, 32,
+ cifs_strtoUCS((wchar_t *) bcc_ptr, system_utsname.release, 32,
nls_codepage);
bcc_ptr += 2 * bytes_returned;
bcc_ptr += 2; /* null terminate Linux version */
} else { /* ASCII */
strcpy(bcc_ptr, "Linux version ");
bcc_ptr += strlen("Linux version ");
- strcpy(bcc_ptr, UTS_RELEASE);
- bcc_ptr += strlen(UTS_RELEASE) + 1;
+ strcpy(bcc_ptr, system_utsname.release);
+ bcc_ptr += strlen(system_utsname.release) + 1;
strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
bcc_ptr++; /* empty domain field */
32, nls_codepage);
bcc_ptr += 2 * bytes_returned;
bytes_returned =
- cifs_strtoUCS((wchar_t *) bcc_ptr, UTS_RELEASE, 32,
+ cifs_strtoUCS((wchar_t *) bcc_ptr, system_utsname.release, 32,
nls_codepage);
bcc_ptr += 2 * bytes_returned;
bcc_ptr += 2; /* null term version string */
strcpy(bcc_ptr, "Linux version ");
bcc_ptr += strlen("Linux version ");
- strcpy(bcc_ptr, UTS_RELEASE);
- bcc_ptr += strlen(UTS_RELEASE) + 1;
+ strcpy(bcc_ptr, system_utsname.release);
+ bcc_ptr += strlen(system_utsname.release) + 1;
strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
bcc_ptr++; /* null domain */