[linux-cifs-client] [PATCH 4/5] [CIFS] have CIFSSMBNegotiate handle
SPNEGO via upcall
Jeff Layton
jlayton at redhat.com
Thu Oct 25 17:43:47 GMT 2007
Change args for CIFSSMBNegotiate to take key pointer and a hostname
string. Have it call cifs_get_spnego_key when the NegotiateProtocol
response contains a SPNEGO blob.
Signed-off-by: Jeff Layton <jlayton at redhat.com>
---
fs/cifs/cifsproto.h | 3 ++-
fs/cifs/cifssmb.c | 41 ++++++++++++++++++++++++++++++-----------
fs/cifs/connect.c | 7 +++++--
3 files changed, 37 insertions(+), 14 deletions(-)
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 0f8a99d..41c29c5 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -104,7 +104,8 @@ void cifs_proc_clean(void);
extern int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
struct nls_table *nls_info, const char *unc);
-extern int CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses);
+extern int CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses,
+ struct key **spnego_key, const char *hostname);
extern int CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
const char *tree, struct cifsTconInfo *tcon,
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 31686e9..68ac988 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -38,6 +38,7 @@
#include "cifsproto.h"
#include "cifs_unicode.h"
#include "cifs_debug.h"
+#include "cifs_spnego.h"
#ifdef CONFIG_CIFS_POSIX
static struct {
@@ -407,7 +408,8 @@ static int validate_t2(struct smb_t2_rsp *pSMB)
return rc;
}
int
-CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
+CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses,
+ struct key **spnego_key, const char *hostname)
{
NEGOTIATE_REQ *pSMB;
NEGOTIATE_RSP *pSMBr;
@@ -641,19 +643,36 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
memcpy(server->server_GUID,
pSMBr->u.extended_response.GUID, 16);
- if (count == 16) {
+ if (count == 16)
server->secType = RawNTLMSSP;
- } else {
- rc = decode_negTokenInit(pSMBr->u.extended_response.
- SecurityBlob,
- count - 16,
- &server->secType);
- if (rc == 1) {
- /* BB Need to fill struct for sessetup here */
- rc = -EOPNOTSUPP;
- } else {
+ else {
+#ifdef CONFIG_CIFS_UPCALL
+ struct cifs_spnego_msg *msg;
+ *spnego_key = cifs_get_spnego_key(ses, pSMBr->u.
+ extended_response.SecurityBlob,
+ count - 16, hostname);
+ if (IS_ERR(*spnego_key)) {
+ rc = PTR_ERR(*spnego_key);
+ *spnego_key = NULL;
+ goto neg_err_exit;
+ }
+
+ msg = (struct cifs_spnego_msg *)
+ (*spnego_key)->payload.data;
+ if (msg->flags & CIFS_SPNEGO_KRB5)
+ server->secType = Kerberos;
+ else if (msg->flags & CIFS_SPNEGO_NTLMSSP)
+ server->secType = NTLMSSP;
+ else {
rc = -EINVAL;
+ goto neg_err_exit;
}
+#else /* CONFIG_CIFS_UPCALL */
+ cERROR(1, ("SPNEGO response received, but "
+ "CONFIG_CIFS_UPCALL not enabled!"));
+ rc = -EINVAL;
+ goto neg_err_exit;
+#endif /* CONFIG_CIFS_UPCALL */
}
} else
server->capabilities &= ~CAP_EXTENDED_SECURITY;
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 057d55c..37e9474 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -3546,6 +3546,7 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
char ntlm_session_key[CIFS_SESS_KEY_SIZE];
int ntlmv2_flag = FALSE;
int first_time = 0;
+ struct key *spnego_key = NULL;
char *hostname;
hostname = extract_hostname_from_unc(unc);
@@ -3557,9 +3558,9 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
/* what if server changes its buffer size after dropping the session? */
if (pSesInfo->server->maxBuf == 0) /* no need to send on reconnect */ {
- rc = CIFSSMBNegotiate(xid, pSesInfo);
+ rc = CIFSSMBNegotiate(xid, pSesInfo, &spnego_key, hostname);
if (rc == -EAGAIN) /* retry only once on 1st time connection */ {
- rc = CIFSSMBNegotiate(xid, pSesInfo);
+ rc = CIFSSMBNegotiate(xid, pSesInfo, &spnego_key, hostname);
if (rc == -EAGAIN)
rc = -EHOSTDOWN;
}
@@ -3666,6 +3667,8 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
}
}
ss_err_exit:
+ if (spnego_key)
+ key_put(spnego_key);
if (hostname)
kfree(hostname);
--
1.5.2.1
More information about the linux-cifs-client
mailing list