[linux-cifs-client] [PATCH 4/6] [CIFS] change cifs_setup_session to
take a unc string arg
Jeff Layton
jlayton at redhat.com
Wed Oct 31 15:31:36 GMT 2007
..then extract the host portion of the UNC string so that we can
use in SPNEGO.
Signed-off-by: Jeff Layton <jlayton at redhat.com>
---
fs/cifs/cifsproto.h | 2 +-
fs/cifs/cifssmb.c | 6 ++++--
fs/cifs/connect.c | 46 ++++++++++++++++++++++++++++++++++++++++++++--
3 files changed, 49 insertions(+), 5 deletions(-)
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index dd1d7c2..b256e8a 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -107,7 +107,7 @@ void cifs_proc_init(void);
void cifs_proc_clean(void);
extern int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
- struct nls_table *nls_info);
+ struct nls_table *nls_info, const char *unc);
extern int CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses);
extern int CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 0bb3e43..49ad995 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -157,7 +157,8 @@ small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
down(&tcon->ses->sesSem);
if (tcon->ses->status == CifsNeedReconnect)
rc = cifs_setup_session(0, tcon->ses,
- nls_codepage);
+ nls_codepage,
+ tcon->treeName);
if (!rc && (tcon->tidStatus == CifsNeedReconnect)) {
mark_open_files_invalid(tcon);
rc = CIFSTCon(0, tcon->ses, tcon->treeName,
@@ -302,7 +303,8 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
down(&tcon->ses->sesSem);
if (tcon->ses->status == CifsNeedReconnect)
rc = cifs_setup_session(0, tcon->ses,
- nls_codepage);
+ nls_codepage,
+ tcon->treeName);
if (!rc && (tcon->tidStatus == CifsNeedReconnect)) {
mark_open_files_invalid(tcon);
rc = CIFSTCon(0, tcon->ses, tcon->treeName,
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 19ee11f..057d55c 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -1996,7 +1996,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
down(&pSesInfo->sesSem);
/* BB FIXME need to pass vol->secFlgs BB */
rc = cifs_setup_session(xid, pSesInfo,
- cifs_sb->local_nls);
+ cifs_sb->local_nls,
+ volume_info.UNC);
up(&pSesInfo->sesSem);
if (!rc)
atomic_inc(&srvTcp->socketUseCount);
@@ -3508,13 +3509,51 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
return rc; /* BB check if we should always return zero here */
}
+/* extract the host portion of the UNC string */
+static char *
+extract_hostname_from_unc(const char *unc)
+{
+ const char *src;
+ char *dst, *delim;
+ unsigned int len;
+
+ /* skip double chars at beginning of string */
+ /* BB: check validity of these bytes? */
+ src = unc + 2;
+
+ delim = strchr(src, '/');
+ if (!delim) {
+ delim = strchr(src, '\\');
+ if (!delim)
+ return ERR_PTR(-EINVAL);
+ }
+
+ len = delim - src;
+ dst = kmalloc((len + 1), GFP_KERNEL);
+ if (dst == NULL)
+ return ERR_PTR(-ENOMEM);
+
+ memcpy(dst, src, len);
+ dst[len] = '\0';
+
+ return dst;
+}
+
int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
- struct nls_table *nls_info)
+ struct nls_table *nls_info, const char *unc)
{
int rc = 0;
char ntlm_session_key[CIFS_SESS_KEY_SIZE];
int ntlmv2_flag = FALSE;
int first_time = 0;
+ char *hostname;
+
+ hostname = extract_hostname_from_unc(unc);
+ if (IS_ERR(hostname)) {
+ rc = PTR_ERR(hostname);
+ hostname = NULL;
+ goto ss_err_exit;
+ }
/* what if server changes its buffer size after dropping the session? */
if (pSesInfo->server->maxBuf == 0) /* no need to send on reconnect */ {
@@ -3627,6 +3666,9 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
}
}
ss_err_exit:
+ if (hostname)
+ kfree(hostname);
+
return rc;
}
--
1.5.2.1
More information about the linux-cifs-client
mailing list