[linux-cifs-client] [PATCH 5/5] [CIFS] have CIFS_SessSetup build
correct SPNEGO SessionSetup request
Jeff Layton
jlayton at redhat.com
Thu Oct 25 17:43:52 GMT 2007
Change CIFS_SessSetup to take a key pointer arg. Use the info in the
key payload to build a session setup request packet when Kerberos is
enabled.
Signed-off-by: Jeff Layton <jlayton at redhat.com>
---
fs/cifs/cifsproto.h | 4 ++--
fs/cifs/connect.c | 4 ++--
fs/cifs/sess.c | 45 +++++++++++++++++++++++++++++++++++++--------
3 files changed, 41 insertions(+), 12 deletions(-)
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 41c29c5..cd11b8a 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -77,8 +77,8 @@ extern struct key *cifs_get_spnego_key(struct cifsSesInfo *sesInfo,
const unsigned char *secblob,
size_t seclen, const char *hostname);
extern int CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses,
- const int stage,
- const struct nls_table *nls_cp);
+ const int stage, const struct nls_table *nls_cp,
+ struct key *spnego_key);
extern __u16 GetNextMid(struct TCP_Server_Info *server);
extern struct oplock_q_entry *AllocOplockQEntry(struct inode *, u16,
struct cifsTconInfo *);
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 37e9474..69ebf1d 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -3587,8 +3587,8 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
pSesInfo->server->capabilities,
pSesInfo->server->timeAdj));
if (experimEnabled < 2)
- rc = CIFS_SessSetup(xid, pSesInfo,
- first_time, nls_info);
+ rc = CIFS_SessSetup(xid, pSesInfo, first_time,
+ nls_info, spnego_key);
else if (extended_security
&& (pSesInfo->capabilities
& CAP_EXTENDED_SECURITY)
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
index 899dc60..099d32c 100644
--- a/fs/cifs/sess.c
+++ b/fs/cifs/sess.c
@@ -29,6 +29,7 @@
#include "ntlmssp.h"
#include "nterr.h"
#include <linux/utsname.h>
+#include "cifs_spnego.h"
extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8,
unsigned char *p24);
@@ -330,7 +331,7 @@ static int decode_ascii_ssetup(char **pbcc_area, int bleft,
int
CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
- const struct nls_table *nls_cp)
+ const struct nls_table *nls_cp, struct key *spnego_key)
{
int rc = 0;
int wct;
@@ -341,7 +342,7 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
__u32 capabilities;
int count;
int resp_buf_type = 0;
- struct kvec iov[2];
+ struct kvec iov[3];
enum securityEnum type;
__u16 action;
int bytes_remaining;
@@ -395,6 +396,9 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
ses->flags &= ~CIFS_SES_LANMAN;
+ iov[1].iov_base = NULL;
+ iov[1].iov_len = 0;
+
if (type == LANMAN) {
#ifdef CONFIG_CIFS_WEAK_PW_HASH
char lnm_session_key[CIFS_SESS_KEY_SIZE];
@@ -499,21 +503,46 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
unicode_ssetup_strings(&bcc_ptr, ses, nls_cp);
} else
ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
- } else /* NTLMSSP or SPNEGO */ {
+#ifdef CONFIG_CIFS_UPCALL
+ } else if (type == Kerberos) {
+ struct cifs_spnego_msg *msg = spnego_key->payload.data;
+ ses->server->mac_signing_key.len = msg->sesskey_len;
+ memcpy(ses->server->mac_signing_key.data.ntlm, msg->data,
+ msg->sesskey_len);
pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
capabilities |= CAP_EXTENDED_SECURITY;
pSMB->req.Capabilities = cpu_to_le32(capabilities);
- /* BB set password lengths */
+ iov[1].iov_base = msg->data + msg->sesskey_len;
+ iov[1].iov_len = msg->secblob_len;
+ pSMB->req.SecurityBlobLength = cpu_to_le16(iov[1].iov_len);
+
+ if (ses->capabilities & CAP_UNICODE) {
+ /* unicode strings must be word aligned */
+ if (iov[0].iov_len % 2) {
+ *bcc_ptr = 0;
+ bcc_ptr++;
+ }
+ unicode_oslm_strings(&bcc_ptr, nls_cp);
+ unicode_domain_string(&bcc_ptr, ses, nls_cp);
+ } else
+ /* BB: is this right? */
+ ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
+#endif
+ } else {
+ cERROR(1,("secType %d not supported!", type));
+ rc = -EINVAL;
+ goto ssetup_exit;
}
- count = (long) bcc_ptr - (long) str_area;
+ iov[2].iov_base = str_area;
+ iov[2].iov_len = (long) bcc_ptr - (long) str_area;
+
+ count = iov[1].iov_len + iov[2].iov_len;
smb_buf->smb_buf_length += count;
BCC_LE(smb_buf) = cpu_to_le16(count);
- iov[1].iov_base = str_area;
- iov[1].iov_len = count;
- rc = SendReceive2(xid, ses, iov, 2 /* num_iovecs */, &resp_buf_type,
+ rc = SendReceive2(xid, ses, iov, 3 /* num_iovecs */, &resp_buf_type,
0 /* not long op */, 1 /* log NT STATUS if any */ );
/* SMB request buf freed in SendReceive2 */
--
1.5.2.1
More information about the linux-cifs-client
mailing list