summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve French <stevef@steveft21.ltcsamba>2003-07-16 10:42:25 -0500
committerSteve French <stevef@steveft21.ltcsamba>2003-07-16 10:42:25 -0500
commite2c223814aa74b2bc52f20224f1ff5f2f4e5d7aa (patch)
tree6df6666d65aaefc94fa58024f6e0fb4c083db480
parenteb40c469128fc8478ac3c7317ae8fda9b9e78959 (diff)
parent701f3b0b3837b0830a4e1a9a2cdfe41bfbf78ef5 (diff)
Merge bk://cifs.bkbits.net/linux-2.5cifs
into steveft21.ltcsamba:/usr/src/bk/linux-2.5cifs
-rw-r--r--fs/cifs/CHANGES9
-rw-r--r--fs/cifs/TODO17
-rw-r--r--fs/cifs/cifsfs.c2
-rw-r--r--fs/cifs/cifsglob.h3
-rw-r--r--fs/cifs/connect.c7
-rw-r--r--fs/cifs/misc.c47
-rw-r--r--fs/cifs/transport.c6
7 files changed, 77 insertions, 14 deletions
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index 6b9ac0a61665..031e2073d78d 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -1,3 +1,12 @@
+Version 0.83
+------------
+Fix oops when mounting to long server names caused by inverted parms to kmalloc.
+Fix MultiuserMount (/proc/fs/cifs configuration setting) so that when enabled
+we will choose a cifs user session (smb uid) that better matches the local
+uid if a) the mount uid does not match the current uid and b) we have another
+session to the same server (ip address) for a different mount which
+matches the current local uid.
+
Version 0.82
------------
Add support for mknod of block or character devices. Fix oplock
diff --git a/fs/cifs/TODO b/fs/cifs/TODO
index 28a2c85fb926..034ee77dd391 100644
--- a/fs/cifs/TODO
+++ b/fs/cifs/TODO
@@ -17,9 +17,12 @@ c) multi-user mounts - multiplexed sessionsetups over single vc
d) Kerberos/SPNEGO session setup support - (started)
-e) NTLMv2 authentication and MD5-HMAC signing SMB PDUs - (mostly implemented)
- signing necessary for some Windows 2003 servers in domain
- mode.
+e) NTLMv2 authentication (mostly implemented)
+
+f) MD5-HMAC signing SMB PDUs when SPNEGO style SessionSetup
+used (Kerberos or NTLMSSP). Signing alreadyimplemented for NTLM
+ and raw NTLMSSP already. This is important when enabling
+ extended security and mounting to Windows 2003 Servers
f) Directory entry caching relies on a 1 second timer, rather than
using FindNotify or equivalent. - (started)
@@ -43,11 +46,9 @@ extra copy in/out of the socket buffers in some cases.
m) finish support for IPv6
-n) send oplock break response when sent (oplock currently disabled in
-/proc/fs/cifs)
-
-o) reduces the oplock breaks coming from windows). Piggyback identical
-file opens on top of each other by incrementing reference count rather
+o) Better optimize open (and pathbased setfilesize) to reduce the
+oplock breaks coming from windows srv. Piggyback identical file
+opens on top of each other by incrementing reference count rather
than resending (helps reduce server resource utilization and avoid
spurious oplock breaks).
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 5bba77c54433..0b8e3ba92647 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -230,7 +230,7 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m)
if (cifs_sb) {
if (cifs_sb->tcon) {
seq_printf(s, ",unc=%s", cifs_sb->tcon->treeName);
- if (cifs_sb->tcon->ses->userName)
+ if ((cifs_sb->tcon->ses) && (cifs_sb->tcon->ses->userName))
seq_printf(s, ",username=%s",
cifs_sb->tcon->ses->userName);
if(cifs_sb->tcon->ses->domainName)
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 5b0ae3bc20cb..6d65f4c71e1f 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -155,7 +155,8 @@ struct cifsSesInfo {
char *serverOS; /* name of operating system underlying the server */
char *serverNOS; /* name of network operating system that the server is running */
char *serverDomain; /* security realm of server */
- int Suid; /* needed for user level security */
+ int Suid; /* remote smb uid */
+ 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 userName[MAX_USERNAME_SIZE + 1];
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index a7220c051534..7c4e046b401d 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -405,7 +405,7 @@ parse_mount_options(char *options, const char *devname, struct smb_vol *vol)
return 1; /* needs_arg; */
}
if ((temp_len = strnlen(value, 300)) < 300) {
- vol->UNC = kmalloc(GFP_KERNEL, temp_len);
+ vol->UNC = kmalloc(temp_len+1,GFP_KERNEL);
strcpy(vol->UNC,value);
if (strncmp(vol->UNC, "//", 2) == 0) {
vol->UNC[0] = '\\';
@@ -482,7 +482,7 @@ parse_mount_options(char *options, const char *devname, struct smb_vol *vol)
return 1;
}
if ((temp_len = strnlen(devname, 300)) < 300) {
- vol->UNC = kmalloc(GFP_KERNEL, temp_len);
+ vol->UNC = kmalloc(temp_len+1,GFP_KERNEL);
strcpy(vol->UNC,devname);
if (strncmp(vol->UNC, "//", 2) == 0) {
vol->UNC[0] = '\\';
@@ -860,7 +860,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
FreeXid(xid);
return -EINVAL;
}
- /* BB add support to use the multiuser_mount flag BB */
+
existingCifsSes =
find_tcp_session(sin_server.sin_addr.s_addr,
volume_info.username, &srvTcp);
@@ -926,6 +926,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
if (volume_info.domainname)
strncpy(pSesInfo->domainName,
volume_info.domainname,MAX_USERNAME_SIZE);
+ pSesInfo->linux_uid = volume_info.linux_uid;
rc = setup_session(xid,pSesInfo, cifs_sb->local_nls);
if(!rc)
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index 896c18d1a7f5..7f3a5b905732 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -190,6 +190,8 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
{
int i;
__u32 tmp;
+ struct list_head* temp_item;
+ struct cifsSesInfo * ses;
char *temp = (char *) buffer;
for (i = 0; i < MAX_CIFS_HDR_SIZE; i++) {
@@ -225,7 +227,52 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
if (treeCon->ses->capabilities & CAP_STATUS32) {
buffer->Flags2 |= SMBFLG2_ERR_STATUS;
}
+
buffer->Uid = treeCon->ses->Suid; /* always in LE format */
+ if(multiuser_mount != 0) {
+ /* For the multiuser case, there are few obvious technically */
+ /* possible mechanisms to match the local linux user (uid) */
+ /* to a valid remote smb user (smb_uid): */
+ /* 1) Query Winbind (or other local pam/nss daemon */
+ /* for userid/password/logon_domain or credential */
+ /* 2) Query Winbind for uid to sid to username mapping */
+ /* and see if we have a matching password for existing*/
+ /* session for that user perhas getting password by */
+ /* adding a new pam_cifs module that stores passwords */
+ /* so that the cifs vfs can get at that for all logged*/
+ /* on users */
+ /* 3) (Which is the mechanism we have chosen) */
+ /* Search through sessions to the same server for a */
+ /* a match on the uid that was passed in on mount */
+ /* with the current processes uid (or euid?) and use */
+ /* that smb uid. If no existing smb session for */
+ /* that uid found, use the default smb session ie */
+ /* the smb session for the volume mounted which is */
+ /* the same as would be used if the multiuser mount */
+ /* flag were disabled. */
+
+ /* BB Add support for establishing new tCon and SMB Session */
+ /* with userid/password pairs found on the smb session */
+ /* for other target tcp/ip addresses BB */
+ if(current->uid != treeCon->ses->linux_uid) {
+ cFYI(1,("Multiuser mode and UID did not match tcon uid "));
+ read_lock(&GlobalSMBSeslock);
+ list_for_each(temp_item, &GlobalSMBSessionList) {
+ ses = list_entry(temp_item, struct cifsSesInfo, cifsSessionList);
+ if(ses->linux_uid == current->uid) {
+ if(ses->server == treeCon->ses->server) {
+ cFYI(1,("found matching uid substitute right smb_uid"));
+ buffer->Uid = ses->Suid;
+ break;
+ } else {
+ /* BB eventually call setup_session here */
+ cFYI(1,("local UID found but smb sess with this server does not exist"));
+ }
+ }
+ }
+ read_unlock(&GlobalSMBSeslock);
+ }
+ }
}
if (treeCon->Flags & SMB_SHARE_IS_IN_DFS)
buffer->Flags2 |= SMBFLG2_DFS;
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
index 9273610cc7a8..7a667c06e3b1 100644
--- a/fs/cifs/transport.c
+++ b/fs/cifs/transport.c
@@ -45,6 +45,11 @@ AllocMidQEntry(struct smb_hdr *smb_buffer, struct cifsSesInfo *ses)
cERROR(1, ("Null session passed in to AllocMidQEntry "));
return NULL;
}
+ if (ses->server == NULL) {
+ cERROR(1, ("Null TCP session in AllocMidQEntry"));
+ return NULL;
+ }
+
temp = (struct mid_q_entry *) kmem_cache_alloc(cifs_mid_cachep,
SLAB_KERNEL);
if (temp == NULL)
@@ -65,7 +70,6 @@ AllocMidQEntry(struct smb_hdr *smb_buffer, struct cifsSesInfo *ses)
/* Should we wake up tcp thread first? BB */
timeout = wait_event_interruptible_timeout(ses->server->response_q,
(ses->server->tcpStatus == CifsGood), timeout);
- cFYI(1,("timeout (after reconnection wait) %d",timeout));
}
if (ses->server->tcpStatus == CifsGood) {